From f3b4e6de16a9ac7c7c5414f68d2d6e320d3d9dbd Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 16 Sep 2020 12:48:40 -0400 Subject: [PATCH] GP-164 Added ELF ARM relocation R_ARM_PREL31 and corrected issue with R_ARM_ABS32 relocation. Fixes #2261, Fixes #2276 --- .../relocation/ARM_ElfRelocationHandler.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java index 7326f8e8e2..a9ae6a9561 100644 --- a/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java +++ b/Ghidra/Processors/ARM/src/main/java/ghidra/app/util/bin/format/elf/relocation/ARM_ElfRelocationHandler.java @@ -83,8 +83,10 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } case ARM_ElfRelocationConstants.R_ARM_ABS32: { // Target class: Data - int oldValue = memory.getInt(relocationAddress); - newValue = (int) (symbolValue + addend + oldValue); + if (elfRelocationContext.extractAddend()) { + addend = memory.getInt(relocationAddress); + } + newValue = (int) (symbolValue + addend); if (isThumb) { newValue |= 1; } @@ -92,8 +94,10 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { break; } case ARM_ElfRelocationConstants.R_ARM_REL32: { // Target class: Data - int oldValue = memory.getInt(relocationAddress); - newValue = (int) (symbolValue + addend + oldValue); + if (elfRelocationContext.extractAddend()) { + addend = memory.getInt(relocationAddress); + } + newValue = (int) (symbolValue + addend); newValue -= offset; // PC relative if (isThumb) { newValue |= 1; @@ -101,6 +105,20 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler { memory.setInt(relocationAddress, newValue); break; } + case ARM_ElfRelocationConstants.R_ARM_PREL31: { // Target class: Data + int oldValue = memory.getInt(relocationAddress); + if (elfRelocationContext.extractAddend()) { + addend = (oldValue << 1) >> 1; + } + newValue = (int) (symbolValue + addend); + newValue -= offset; // PC relative + if (isThumb) { + newValue |= 1; + } + newValue = (newValue & 0x7fffffff) + (oldValue & 0x80000000); + memory.setInt(relocationAddress, newValue); + break; + } case ARM_ElfRelocationConstants.R_ARM_LDR_PC_G0: { // Target class: ARM Instruction int oldValue = memory.getInt(relocationAddress, instructionBigEndian); newValue = (int) (symbolValue + addend);