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);