diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java index 0065478489..0d4b18a7d2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/relocation/AbstractElfRelocationHandler.java @@ -99,8 +99,8 @@ abstract public class AbstractElfRelocationHandler + * NOTE: This method will not be invoked if elfSymbol is null and + * {@link ElfRelocationContext#processRelocation(ElfRelocation, Address)} will report + * relocation failure. + *
+ * NOTE: This method will not be invoked for {@code type} == 0/NONE and will be marked as + * skipped. * * @param elfRelocationContext relocation context * @param relocation ELF relocation * @param relocationType ELF relocation type enum value * @param relocationAddress relocation target address (fixup location) - * @param elfSymbol relocation symbol (may be null) + * @param elfSymbol relocation symbol * @param symbolAddr elfSymbol memory address (may be null) * @param symbolValue unadjusted elfSymbol value (0 if no symbol) * @param symbolName elfSymbol name (may be null) @@ -141,6 +148,39 @@ abstract public class AbstractElfRelocationHandler elfRelocationContext, ElfRelocation relocation,Address relocationAddress) { + + int symbolIndex = relocation.getSymbolIndex(); + + ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // will never be null + Address symbolAddr = elfRelocationContext.getSymbolAddress(sym); // may be null + + if (symbolIndex != 0 && symbolAddr == null) { // symbolValue will also be invalid + + int typeId = relocation.getType(); + T type = getRelocationType(typeId); + + String symbolName = elfRelocationContext.getSymbolName(symbolIndex); + + Program program = elfRelocationContext.getProgram(); + + markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, + elfRelocationContext.getLog()); + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to resolve relocation symbol", elfRelocationContext.getLog()); + return true; + } + return false; + } // private String getRelocationTypeDetail(int typeId) { // T relocationType = relocationTypesMap.get(typeId); diff --git a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java index 13a83c2641..aec97b4af7 100644 --- a/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java +++ b/Ghidra/Processors/AARCH64/src/main/java/ghidra/app/util/bin/format/elf/relocation/AARCH64_ElfRelocationHandler.java @@ -50,20 +50,45 @@ public class AARCH64_ElfRelocationHandler ElfRelocation relocation, AARCH64_ElfRelocationType type, Address relocationAddress, ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { - + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); boolean isBigEndianInstructions = program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian(); long addend = relocation.getAddend(); // will be 0 for REL case - long offset = relocationAddress.getOffset(); + int symbolIndex = relocation.getSymbolIndex(); boolean is64bit = true; boolean overflowCheck = true; // *_NC type relocations specify "no overflow check" long newValue = 0; int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + case R_AARCH64_P32_RELATIVE: + is64bit = false; + case R_AARCH64_RELATIVE: + if (elfRelocationContext.extractAddend()) { + addend = getValue(memory, relocationAddress, is64bit); + } + newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; + byteLength = setValue(memory, relocationAddress, newValue, is64bit); + return new RelocationResult(Status.APPLIED, byteLength); + case R_AARCH64_P32_COPY: + case R_AARCH64_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } switch (type) { // .xword: (S+A) @@ -324,19 +349,18 @@ public class AARCH64_ElfRelocationHandler // GOT/PLT symbolValue corresponds to PLT entry for which we need to // create and external function location. Don't bother changing // GOT entry bytes if it refers to .plt block - Address symAddress = elfRelocationContext.getSymbolAddress(sym); - MemoryBlock block = memory.getBlock(symAddress); + + MemoryBlock block = memory.getBlock(symbolAddr); // TODO: jump slots are always in GOT - not sure why PLT check is done boolean isPltSym = block != null && block.getName().startsWith(".plt"); boolean isExternalSym = block != null && MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName()); if (!isPltSym) { - byteLength = - setValue(memory, relocationAddress, symAddress.getOffset(), is64bit); + byteLength = setValue(memory, relocationAddress, symbolValue, is64bit); } if ((isPltSym || isExternalSym) && !StringUtils.isBlank(symbolName)) { Function extFunction = elfRelocationContext.getLoadHelper() - .createExternalFunctionLinkage(symbolName, symAddress, null); + .createExternalFunctionLinkage(symbolName, symbolAddr, null); if (extFunction == null) { markAsError(program, relocationAddress, type, symbolName, symbolIndex, "Failed to create external function", elfRelocationContext.getLog()); @@ -346,24 +370,6 @@ public class AARCH64_ElfRelocationHandler break; } - case R_AARCH64_P32_RELATIVE: - is64bit = false; - case R_AARCH64_RELATIVE: { - if (elfRelocationContext.extractAddend()) { - addend = getValue(memory, relocationAddress, is64bit); - } - newValue = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; - byteLength = setValue(memory, relocationAddress, newValue, is64bit); - break; - } - - case R_AARCH64_P32_COPY: - case R_AARCH64_COPY: { - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - } - default: { markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); 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 de6e08cfd2..c35230238a 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 @@ -62,7 +62,6 @@ public class ARM_ElfRelocationHandler boolean instructionBigEndian = program.getLanguage().getLanguageDescription().getInstructionEndian().isBigEndian(); - boolean isThumb = isThumb(sym); long addend = relocation.getAddend(); // will be 0 for REL case @@ -71,6 +70,32 @@ public class ARM_ElfRelocationHandler int newValue = 0; int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + case R_ARM_RELATIVE: // Target class: Data + if (elfRelocationContext.extractAddend()) { + addend = memory.getInt(relocationAddress); + } + newValue = + (int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + (int) addend; + memory.setInt(relocationAddress, newValue); + return new RelocationResult(Status.APPLIED, byteLength); + case R_ARM_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + + boolean isThumb = isThumb(sym); + switch (type) { case R_ARM_PC24: { // Target class: ARM Instruction int oldValue = memory.getInt(relocationAddress, instructionBigEndian); @@ -260,20 +285,19 @@ public class ARM_ElfRelocationHandler case R_ARM_JUMP_SLOT: { // Target class: Data // Corresponds to lazy dynamically linked external symbols within // GOT/PLT symbolValue corresponds to PLT entry for which we need to - // create and external function location. Don't bother changing + // create an external function location. Don't bother changing // GOT entry bytes if it refers to .plt block - Address symAddress = elfRelocationContext.getSymbolAddress(sym); - MemoryBlock block = memory.getBlock(symAddress); + MemoryBlock block = memory.getBlock(symbolAddr); // TODO: jump slots are always in GOT - not sure why PLT check is done boolean isPltSym = block != null && block.getName().startsWith(".plt"); boolean isExternalSym = block != null && MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName()); if (!isPltSym) { - memory.setInt(relocationAddress, (int) symAddress.getOffset()); + memory.setInt(relocationAddress, (int) symbolValue); } if (isPltSym || isExternalSym) { Function extFunction = elfRelocationContext.getLoadHelper() - .createExternalFunctionLinkage(symbolName, symAddress, null); + .createExternalFunctionLinkage(symbolName, symbolAddr, null); if (extFunction == null) { markAsError(program, relocationAddress, type, symbolName, symbolIndex, "Failed to create external function", elfRelocationContext.getLog()); @@ -282,16 +306,7 @@ public class ARM_ElfRelocationHandler } break; } - - case R_ARM_RELATIVE: { // Target class: Data - if (elfRelocationContext.extractAddend()) { - addend = memory.getInt(relocationAddress); - } - newValue = - (int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + (int) addend; - memory.setInt(relocationAddress, newValue); - break; - } + /* case R_ARM_GOTOFF32: { break; @@ -680,12 +695,6 @@ public class ARM_ElfRelocationHandler } */ - case R_ARM_COPY: { - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - } - default: { markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java index 72772252ef..3003e3c9b2 100644 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR32_ElfRelocationHandler.java @@ -50,13 +50,20 @@ public class AVR32_ElfRelocationHandler throws MemoryAccessException { Program program = elfRelocationContext.getProgram(); + + int symbolIndex = relocation.getSymbolIndex(); + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + Memory memory = program.getMemory(); AddressSpace space = program.getAddressFactory().getDefaultAddressSpace(); long addend = relocation.getAddend(); // will be 0 for REL case long offset = (int) relocationAddress.getOffset(); - int symbolIndex = relocation.getSymbolIndex(); int oldValue = memory.getInt(relocationAddress); @@ -64,8 +71,6 @@ public class AVR32_ElfRelocationHandler int newValueShiftToAligntoUpper = 0; switch (type) { - case R_AVR32_NONE: - return RelocationResult.SKIPPED; case R_AVR32_32: int newValue = (((int) symbolValue + (int) addend) & 0xffffffff); memory.setInt(relocationAddress, newValue); diff --git a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java index 8a054fbf01..571ae5bcba 100644 --- a/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java +++ b/Ghidra/Processors/Atmel/src/main/java/ghidra/app/util/bin/format/elf/relocation/AVR8_ElfRelocationHandler.java @@ -43,27 +43,42 @@ public class AVR8_ElfRelocationHandler ElfRelocation relocation, AVR8_ElfRelocationType type, Address relocationAddress, ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { + + switch (type) { + case R_AVR_DIFF8: + case R_AVR_DIFF16: + case R_AVR_DIFF32: + // nothing to do + return RelocationResult.SKIPPED; + default: + break; + } // WARNING: symbolValue is not in bytes. // It is an addressable word offset within the symbols address space Program program = elfRelocationContext.getProgram(); + + int symbolIndex = relocation.getSymbolIndex(); + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + Memory memory = program.getMemory(); long addend = relocation.getAddend(); // will be 0 for REL case // WARNING: offset is in bytes be careful, word address potentially with byte indexes long offset = relocationAddress.getOffset(); - - int symbolIndex = relocation.getSymbolIndex(); + int oldValue = memory.getShort(relocationAddress); int newValue = 0; int byteLength = 2; // most relocations affect 2-bytes (change if different) switch (type) { - case R_AVR_NONE: - return RelocationResult.SKIPPED; case R_AVR_32: newValue = (((int) symbolValue + (int) addend) & 0xffffffff); @@ -300,12 +315,6 @@ public class AVR8_ElfRelocationHandler memory.setShort(relocationAddress, (short) (newValue & 0xffff)); break; - case R_AVR_DIFF8: - case R_AVR_DIFF16: - case R_AVR_DIFF32: - // nothing to do - break; - case R_AVR_LDS_STS_16: newValue = (((int) symbolValue + (int) addend)); diff --git a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java index d8160c8924..5ccebcf384 100644 --- a/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java +++ b/Ghidra/Processors/Loongarch/src/main/java/ghidra/app/util/bin/format/elf/relocation/Loongarch_ElfRelocationHandler.java @@ -59,14 +59,59 @@ public class Loongarch_ElfRelocationHandler long base = elfRelocationContext.getImageBaseWordAdjustmentOffset(); int symbolIndex = relocation.getSymbolIndex(); - + long value64 = 0; int value32 = 0; short value16 = 0; byte value8 = 0; - byte[] bytes24 = new byte[3]; - + int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_LARCH_RELATIVE: + // Runtime fixup for load-address *(void **) PC = B + A + if (elf.is32Bit()) { + value32 = (int) (base + addend); + memory.setInt(relocationAddress, value32); + } + else { + value64 = base + addend; + memory.setLong(relocationAddress, value64); + byteLength = 8; + } + return new RelocationResult(Status.APPLIED, byteLength); + + case R_LARCH_IRELATIVE: + if (elf.is32Bit()) { + value32 = + (int) (addend + elfRelocationContext.getImageBaseWordAdjustmentOffset()); + memory.setInt(relocationAddress, value32); + } + else { + byteLength = 8; + value64 = addend + elfRelocationContext.getImageBaseWordAdjustmentOffset(); + memory.setLong(relocationAddress, value64); + } + return new RelocationResult(Status.APPLIED, byteLength); + + case R_LARCH_COPY: + // Runtime memory copy in executable memcpy (PC, RtAddr, sizeof (sym)) + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + + byte[] bytes24 = new byte[3]; switch (type) { case R_LARCH_32: @@ -96,25 +141,6 @@ public class Loongarch_ElfRelocationHandler } break; - case R_LARCH_RELATIVE: - // Runtime fixup for load-address *(void **) PC = B + A - if (elf.is32Bit()) { - value32 = (int) (base + addend); - memory.setInt(relocationAddress, value32); - } - else { - value64 = base + addend; - memory.setLong(relocationAddress, value64); - byteLength = 8; - } - break; - - case R_LARCH_COPY: - // Runtime memory copy in executable memcpy (PC, RtAddr, sizeof (sym)) - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case R_LARCH_JUMP_SLOT: // Runtime PLT supporting (implementation-defined) if (elf.is32Bit()) { @@ -137,19 +163,7 @@ public class Loongarch_ElfRelocationHandler markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; - - case R_LARCH_IRELATIVE: - if (elf.is32Bit()) { - value32 = - (int) (addend + elfRelocationContext.getImageBaseWordAdjustmentOffset()); - memory.setInt(relocationAddress, value32); - } - else { - byteLength = 8; - value64 = addend + elfRelocationContext.getImageBaseWordAdjustmentOffset(); - memory.setLong(relocationAddress, value64); - } - break; + // case R_LARCH_MARK_LA: // case R_LARCH_MARK_PCREL: diff --git a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java index c4b8027732..a307822410 100644 --- a/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java +++ b/Ghidra/Processors/MIPS/src/main/java/ghidra/app/util/bin/format/elf/relocation/MIPS_ElfRelocationHandler.java @@ -62,6 +62,8 @@ public class MIPS_ElfRelocationHandler ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { + // TODO: May need to add support for when symbol is not resolved, see handleUnresolvedSymbol + // Determine if result value should be saved as addend for next relocation final boolean saveValue = elfRelocationContext.saveValueForNextReloc; @@ -633,20 +635,19 @@ public class MIPS_ElfRelocationHandler case R_MICROMIPS_JALR: boolean success = false; - Address symAddr = elfRelocationContext.getSymbolAddress(elfSymbol); - if (symAddr != null) { - MemoryBlock block = memory.getBlock(symAddr); + if (symbolAddr != null) { + MemoryBlock block = memory.getBlock(symbolAddr); if (block != null) { if (MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName())) { success = elfRelocationContext.getLoadHelper() - .createExternalFunctionLinkage(symbolName, symAddr, + .createExternalFunctionLinkage(symbolName, symbolAddr, null) != null; if (success) { // Inject appropriate JAL instruction if (type == MIPS_ElfRelocationType.R_MICROMIPS_JALR) { - int offsetBits = (int) (symAddr.getOffset() >> 1) & 0x3ffffff; + int offsetBits = (int) (symbolValue >> 1) & 0x3ffffff; // TODO: upper bits should really come from delay slot int microJalrBits = 0xf4000000 | offsetBits; memory.setShort(relocationAddress, @@ -655,7 +656,7 @@ public class MIPS_ElfRelocationHandler (short) microJalrBits); } else { - int offsetBits = (int) (symAddr.getOffset() >> 2) & 0x3ffffff; + int offsetBits = (int) (symbolValue >> 2) & 0x3ffffff; // TODO: upper bits should really come from delay slot int jalrBits = 0x0c000000 | offsetBits; memory.setInt(relocationAddress, jalrBits); diff --git a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java index abf3320fbf..c4470ccc96 100644 --- a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java +++ b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java @@ -66,6 +66,11 @@ public class PIC30_ElfRelocationHandler ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java index e7bbf452b3..f68f9740c0 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC64_ElfRelocationHandler.java @@ -62,15 +62,11 @@ public class PowerPC64_ElfRelocationHandler Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); - + // NOTE: Based upon glibc source it appears that PowerPC only uses RELA relocations long addend = relocation.getAddend(); - long offset = relocationAddress.getOffset(); int symbolIndex = relocation.getSymbolIndex(); - int oldValue = memory.getInt(relocationAddress); - int newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) // IMPORTANT NOTE: // Handling of Object modules (*.o) is currently problematic since relocations @@ -102,12 +98,40 @@ public class PowerPC64_ElfRelocationHandler break; default: } - + + // Handle relative relocations that do not require symbolAddr or symbolValue switch (type) { + + case R_PPC64_RELATIVE: + long value64 = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; + memory.setLong(relocationAddress, value64); + return new RelocationResult(Status.APPLIED, 8); + + case R_PPC64_TOC: + memory.setLong(relocationAddress, toc); + return new RelocationResult(Status.APPLIED, 8); + case R_PPC64_COPY: markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, sym.getSize(), elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + + int oldValue = memory.getInt(relocationAddress); + int newValue = 0; + + int byteLength = 4; // most relocations affect 4-bytes (change if different) + + switch (type) { + case R_PPC64_ADDR32: newValue = (int) (symbolValue + addend); memory.setInt(relocationAddress, newValue); @@ -179,11 +203,6 @@ public class PowerPC64_ElfRelocationHandler newValue = (oldValue & ~PPC64_LOW24) | newValue; memory.setInt(relocationAddress, newValue); break; - case R_PPC64_RELATIVE: - long value64 = elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; - memory.setLong(relocationAddress, value64); - byteLength = 8; - break; case R_PPC64_REL32: newValue = (int) (symbolValue + addend - offset); memory.setInt(relocationAddress, newValue); @@ -230,7 +249,7 @@ public class PowerPC64_ElfRelocationHandler case R_PPC64_UADDR64: case R_PPC64_ADDR64: case R_PPC64_GLOB_DAT: - value64 = symbolValue + addend; + long value64 = symbolValue + addend; memory.setLong(relocationAddress, value64); byteLength = 8; if (symbolIndex != 0 && addend != 0 && !sym.isSection()) { @@ -239,10 +258,6 @@ public class PowerPC64_ElfRelocationHandler applyComponentOffsetPointer(program, relocationAddress, addend); } break; - case R_PPC64_TOC: - memory.setLong(relocationAddress, toc); - byteLength = 8; - break; default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java index 0fa448361e..639340c175 100644 --- a/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java +++ b/Ghidra/Processors/PowerPC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PowerPC_ElfRelocationHandler.java @@ -71,6 +71,33 @@ public class PowerPC_ElfRelocationHandler extends // NOTE: Based upon glibc source it appears that PowerPC only uses RELA relocations int addend = (int) relocation.getAddend(); + + long relocbase = elfRelocationContext.getImageBaseWordAdjustmentOffset(); + + int newValue = 0; + int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_PPC_RELATIVE: + newValue = (int) relocbase + addend; + memory.setInt(relocationAddress, newValue); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_PPC_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } // if (sym.isLocal() && sym.getSectionHeaderIndex() != ElfSectionHeaderConstants.SHN_UNDEF) { // @@ -83,18 +110,11 @@ public class PowerPC_ElfRelocationHandler extends // symbolValue = elfRelocationContext.getImageBaseWordAdjustmentOffset(); // } - long relocbase = elfRelocationContext.getImageBaseWordAdjustmentOffset(); - int offset = (int) relocationAddress.getOffset(); int oldValue = memory.getInt(relocationAddress); - int newValue = 0; - int byteLength = 4; // most relocations affect 4-bytes (change if different) switch (type) { - case R_PPC_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; + case R_PPC_ADDR32: case R_PPC_UADDR32: case R_PPC_GLOB_DAT: @@ -162,10 +182,6 @@ public class PowerPC_ElfRelocationHandler extends newValue = (oldValue & ~PPC_LOW24) | newValue; memory.setInt(relocationAddress, newValue); break; - case R_PPC_RELATIVE: - newValue = (int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend; - memory.setInt(relocationAddress, newValue); - break; case R_PPC_REL32: newValue = ((int) symbolValue + addend - offset); memory.setInt(relocationAddress, newValue); @@ -216,8 +232,7 @@ public class PowerPC_ElfRelocationHandler extends oldValue = memory.getInt(relocationAddress); - Address symAddr = elfRelocationContext.getSymbolAddress(sym); - MemoryBlock block = memory.getBlock(symAddr); + MemoryBlock block = memory.getBlock(symbolAddr); Integer sdaBase = null; Integer gprID = null; diff --git a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java index 064792e248..a48257d9db 100644 --- a/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java +++ b/Ghidra/Processors/RISCV/src/main/java/ghidra/app/util/bin/format/elf/relocation/RISCV_ElfRelocationHandler.java @@ -154,7 +154,7 @@ public class RISCV_ElfRelocationHandler long base = elfRelocationContext.getImageBaseWordAdjustmentOffset(); int symbolIndex = relocation.getSymbolIndex(); - + long value64 = 0; int value32 = 0; short value16 = 0; @@ -162,6 +162,67 @@ public class RISCV_ElfRelocationHandler int target = 0; int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_RISCV_RELATIVE: + // Runtime relocation word32,64 = B + A + if (elf.is32Bit()) { + value32 = (int) (base + addend); + memory.setInt(relocationAddress, value32); + } + else { + value64 = base + addend; + memory.setLong(relocationAddress, value64); + byteLength = 8; + } + return new RelocationResult(Status.APPLIED, byteLength); + + case R_RISCV_PCREL_LO12_S: + // PC-relative reference %pcrel_lo(symbol) (S-Type) + // S-type immediates split the 12 bit value into separate 7 bit and 5 bit fields. + // Warning: untested! + target = getSymbolValueIndirect(elfRelocationContext, sym, + relocationAddress.getOffset() - relocation.getOffset()); + if (target == 0) { + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to locate HI20 relocation", elfRelocationContext.getLog()); + return RelocationResult.FAILURE; + } + value32 = ((target & 0x000007f) << 25) | (target & 0x00000f80) | + (memory.getInt(relocationAddress) & 0x1fff07f); + memory.setInt(relocationAddress, value32); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_RISCV_PCREL_LO12_I: + // PC-relative reference %pcrel_lo(symbol) (I-Type), relative to the cited pc_rel_hi20 + target = getSymbolValueIndirect(elfRelocationContext, sym, + relocationAddress.getOffset() - relocation.getOffset()); + if (target == 0) { + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Failed to locate HI20 relocation", elfRelocationContext.getLog()); + return RelocationResult.FAILURE; + } + value32 = + ((target & 0x00000fff) << 20) | (memory.getInt(relocationAddress) & 0xfffff); + memory.setInt(relocationAddress, value32); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_RISCV_COPY: + // Runtime relocation must be in executable. not allowed in shared library + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } switch (type) { case R_RISCV_32: @@ -191,25 +252,6 @@ public class RISCV_ElfRelocationHandler } break; - case R_RISCV_RELATIVE: - // Runtime relocation word32,64 = B + A - if (elf.is32Bit()) { - value32 = (int) (base + addend); - memory.setInt(relocationAddress, value32); - } - else { - value64 = base + addend; - memory.setLong(relocationAddress, value64); - byteLength = 8; - } - break; - - case R_RISCV_COPY: - // Runtime relocation must be in executable. not allowed in shared library - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - case R_RISCV_JUMP_SLOT: // Runtime relocation word32,64 = S ;handled by PLT unless LD_BIND_NOW if (elf.is32Bit()) { @@ -278,36 +320,6 @@ public class RISCV_ElfRelocationHandler getHi20(target) | (memory.getInt(relocationAddress) & 0xfff)); break; - case R_RISCV_PCREL_LO12_I: - // PC-relative reference %pcrel_lo(symbol) (I-Type), relative to the cited pc_rel_hi20 - target = getSymbolValueIndirect(elfRelocationContext, sym, - relocationAddress.getOffset() - relocation.getOffset()); - if (target == 0) { - markAsError(program, relocationAddress, type, symbolName, symbolIndex, - "Failed to locate HI20 relocation", elfRelocationContext.getLog()); - return RelocationResult.FAILURE; - } - value32 = - ((target & 0x00000fff) << 20) | (memory.getInt(relocationAddress) & 0xfffff); - memory.setInt(relocationAddress, value32); - break; - - case R_RISCV_PCREL_LO12_S: - // PC-relative reference %pcrel_lo(symbol) (S-Type) - // S-type immediates split the 12 bit value into separate 7 bit and 5 bit fields. - // Warning: untested! - target = getSymbolValueIndirect(elfRelocationContext, sym, - relocationAddress.getOffset() - relocation.getOffset()); - if (target == 0) { - markAsError(program, relocationAddress, type, symbolName, symbolIndex, - "Failed to locate HI20 relocation", elfRelocationContext.getLog()); - return RelocationResult.FAILURE; - } - value32 = ((target & 0x000007f) << 25) | (target & 0x00000f80) | - (memory.getInt(relocationAddress) & 0x1fff07f); - memory.setInt(relocationAddress, value32); - break; - case R_RISCV_HI20: // Absolute address %hi(symbol) (U-Type) value32 = (int) ((symbolValue + 0x800) & 0xfffff000) | diff --git a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java index 4ead1c2f40..2f51dfb372 100644 --- a/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java +++ b/Ghidra/Processors/Sparc/src/main/java/ghidra/app/util/bin/format/elf/relocation/SPARC_ElfRelocationHandler.java @@ -58,6 +58,28 @@ public class SPARC_ElfRelocationHandler int oldValue = memory.getInt(relocationAddress); int newValue = 0; int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_SPARC_RELATIVE: + newValue = (int) elfRelocationContext.getElfHeader().getImageBase() + (int) addend; + memory.setInt(relocationAddress, newValue); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_SPARC_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } switch (type) { case R_SPARC_DISP32: @@ -87,18 +109,10 @@ public class SPARC_ElfRelocationHandler newValue = (int) symbolValue; memory.setInt(relocationAddress, newValue); break; - case R_SPARC_RELATIVE: - newValue = (int) elfRelocationContext.getElfHeader().getImageBase() + (int) addend; - memory.setInt(relocationAddress, newValue); - break; case R_SPARC_UA32: newValue = (int) symbolValue + (int) addend; memory.setInt(relocationAddress, newValue); break; - case R_SPARC_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java index 37f3efdb71..de048c7ea1 100644 --- a/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java +++ b/Ghidra/Processors/SuperH4/src/main/java/ghidra/app/util/bin/format/elf/relocation/SH_ElfRelocationHandler.java @@ -54,6 +54,31 @@ public class SH_ElfRelocationHandler int newValue = 0; int oldValue; int byteLength = 4; // most relocations affect 4-bytes (change if different) + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_SH_RELATIVE: + if (elfRelocationContext.extractAddend()) { + addend = memory.getInt(relocationAddress); + } + newValue = (int) (elfRelocationContext.getImageBaseWordAdjustmentOffset()) + addend; + memory.setInt(relocationAddress, newValue); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_SH_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } switch (type) { case R_SH_DIR32: @@ -123,19 +148,6 @@ public class SH_ElfRelocationHandler byteLength = 2; break; - case R_SH_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case R_SH_RELATIVE: - if (elfRelocationContext.extractAddend()) { - addend = memory.getInt(relocationAddress); - } - newValue = (int) (elfRelocationContext.getImageBaseWordAdjustmentOffset()) + addend; - memory.setInt(relocationAddress, newValue); - break; - default: markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName, elfRelocationContext.getLog()); diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java index e9f02e4e7f..4eefbee9f1 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430X_ElfRelocationHandler.java @@ -46,8 +46,14 @@ public class MSP430X_ElfRelocationHandler ElfSymbol elfSymbol, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); + int symbolIndex = relocation.getSymbolIndex(); long addend = relocation.getAddend(); // will be 0 for REL case long offset = relocationAddress.getOffset(); diff --git a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java index 94901e87af..5caf1fa108 100644 --- a/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java +++ b/Ghidra/Processors/TI_MSP430/src/main/java/ghidra/app/util/bin/format/elf/relocation/MSP430_ElfRelocationHandler.java @@ -46,8 +46,14 @@ public class MSP430_ElfRelocationHandler ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName) throws MemoryAccessException { + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + Program program = elfRelocationContext.getProgram(); Memory memory = program.getMemory(); + int symbolIndex = relocation.getSymbolIndex(); long addend = relocation.getAddend(); // will be 0 for REL case long offset = relocationAddress.getOffset(); diff --git a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java index f0b6ac291b..a6cf4cd529 100644 --- a/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java +++ b/Ghidra/Processors/Xtensa/src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java @@ -57,6 +57,24 @@ public class Xtensa_ElfRelocationHandler int byteLength = -1; int newValue; + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_XTENSA_RELATIVE: + newValue = ((int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend); + memory.setInt(relocationAddress, newValue); + byteLength = 4; + return new RelocationResult(Status.APPLIED, byteLength); + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } int diff_mask = 0; boolean neg = false; @@ -71,12 +89,6 @@ public class Xtensa_ElfRelocationHandler // case R_XTENSA_RTLD: - case R_XTENSA_RELATIVE: - newValue = ((int) elfRelocationContext.getImageBaseWordAdjustmentOffset() + addend); - memory.setInt(relocationAddress, newValue); - byteLength = 4; - break; - case R_XTENSA_GLOB_DAT: case R_XTENSA_JMP_SLOT: case R_XTENSA_PLT: diff --git a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java index ece40995c6..a84945ee08 100644 --- a/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java +++ b/Ghidra/Processors/eBPF/src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java @@ -54,6 +54,12 @@ public class eBPF_ElfRelocationHandler } int symbolIndex = relocation.getSymbolIndex(); + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + long new_value = 0; int byteLength = 8; diff --git a/Ghidra/Processors/tricore/src/main/java/ghidra/app/util/bin/format/elf/relocation/Tricore_ElfRelocationHandler.java b/Ghidra/Processors/tricore/src/main/java/ghidra/app/util/bin/format/elf/relocation/Tricore_ElfRelocationHandler.java index c646bf42c9..0a69a4ca05 100644 --- a/Ghidra/Processors/tricore/src/main/java/ghidra/app/util/bin/format/elf/relocation/Tricore_ElfRelocationHandler.java +++ b/Ghidra/Processors/tricore/src/main/java/ghidra/app/util/bin/format/elf/relocation/Tricore_ElfRelocationHandler.java @@ -60,6 +60,33 @@ public class Tricore_ElfRelocationHandler long rv = 0; int byteLength = -1; + + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + + case R_TRICORE_RELATIVE: + long base = program.getImageBase().getOffset(); + rv = (int) (base + addend); + byteLength = relocate_word32(memory, relocationAddress, rv); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_TRICORE_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + case R_TRICORE_BITPOS: + // This reads as a pseudo relocation, possibly do RelocationResult.PARTIAL instead? + return RelocationResult.SKIPPED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } /** * Key S indicates the final value assigned to the symbol referenced in the @@ -274,21 +301,6 @@ public class Tricore_ElfRelocationHandler memory.setInt(relocationAddress, (int) symbolValue); break; - case R_TRICORE_RELATIVE: - long base = program.getImageBase().getOffset(); - rv = (int) (base + addend); - byteLength = relocate_word32(memory, relocationAddress, rv); - break; - - case R_TRICORE_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case R_TRICORE_BITPOS: - // This reads as a pseudo relocation, possibly do RelocationResult.PARTIAL instead? - return RelocationResult.SKIPPED; - /** case R_TRICORE_SBREG_S2: break; diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java index 89b77c40c9..ef47ff7811 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_32_ElfRelocationHandler.java @@ -62,6 +62,65 @@ public class X86_32_ElfRelocationHandler int byteLength = 4; // most relocations affect 4-bytes (change if different) int value; + // Handle relative relocations that do not require symbolAddr or symbolValue + switch (type) { + case R_386_RELATIVE: + long base = program.getImageBase().getOffset(); + if (elfRelocationContext.getElfHeader().isPreLinked()) { + // adjust prelinked value that is already in memory + value = memory.getInt(relocationAddress) + + (int) elfRelocationContext.getImageBaseWordAdjustmentOffset(); + } + else { + value = (int) (base + addend); + } + memory.setInt(relocationAddress, value); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_386_IRELATIVE: + // NOTE: We don't support this since the code actually uses a function to + // compute the relocation value (i.e., indirect) + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + "Indirect computed relocation not supported", elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + case R_386_GOTPC: + // similar to R_386_PC32 but uses .got address instead of symbol address + try { + long dotgot = elfRelocationContext.getGOTValue(); + value = (int) (dotgot + addend - offset); + memory.setInt(relocationAddress, value); + } + catch (NotFoundException e) { + markAsError(program, relocationAddress, type, symbolName, symbolIndex, + e.getMessage(), elfRelocationContext.getLog()); + return RelocationResult.FAILURE; + } + return new RelocationResult(Status.APPLIED, byteLength); + + case R_386_COPY: + markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, + sym.getSize(), elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + // Thread Local Symbol relocations (unimplemented concept) + case R_386_TLS_DTPMOD32: + case R_386_TLS_DTPOFF32: + case R_386_TLS_TPOFF32: + case R_386_TLS_TPOFF: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + switch (type) { case R_386_32: value = (int) (symbolValue + addend); @@ -102,54 +161,6 @@ public class X86_32_ElfRelocationHandler return RelocationResult.FAILURE; } break; - case R_386_COPY: - markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, - sym.getSize(), elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - // Thread Local Symbol relocations (unimplemented concept) - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, - "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - // cases which do not use symbol value - - case R_386_RELATIVE: - long base = program.getImageBase().getOffset(); - if (elfRelocationContext.getElfHeader().isPreLinked()) { - // adjust prelinked value that is already in memory - value = memory.getInt(relocationAddress) + - (int) elfRelocationContext.getImageBaseWordAdjustmentOffset(); - } - else { - value = (int) (base + addend); - } - memory.setInt(relocationAddress, value); - break; - - case R_386_IRELATIVE: - // NOTE: We don't support this since the code actually uses a function to - // compute the relocation value (i.e., indirect) - markAsError(program, relocationAddress, type, symbolName, symbolIndex, - "Indirect computed relocation not supported", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - - case R_386_GOTPC: - // similar to R_386_PC32 but uses .got address instead of symbol address - try { - long dotgot = elfRelocationContext.getGOTValue(); - value = (int) (dotgot + addend - offset); - memory.setInt(relocationAddress, value); - } - catch (NotFoundException e) { - markAsError(program, relocationAddress, type, symbolName, symbolIndex, - e.getMessage(), elfRelocationContext.getLog()); - return RelocationResult.FAILURE; - } - break; // TODO: Cases not yet examined // case R_386_32PLT diff --git a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java index f7a0809bb1..e16d67a159 100644 --- a/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java +++ b/Ghidra/Processors/x86/src/main/java/ghidra/app/util/bin/format/elf/relocation/X86_64_ElfRelocationHandler.java @@ -66,12 +66,56 @@ public class X86_64_ElfRelocationHandler extends int symbolIndex = relocation.getSymbolIndex(); int byteLength = 8; // most relocations affect 8-bytes (change if different) long value; - + + // Handle relative relocations that do not require symbolAddr or symbolValue switch (type) { + case R_X86_64_RELATIVE: + // word64 for LP64 and specifies word32 for ILP32, + // we assume LP64 only. We probably need a hybrid + // variant to handle the ILP32 case. + case R_X86_64_RELATIVE64: + // dl_machine.h + // value = (Elf64_64Addr) map->l_addr + reloc->r_addend + long imageBaseAdjustment = elfRelocationContext.getImageBaseWordAdjustmentOffset(); + if (elfRelocationContext.getElfHeader().isPreLinked()) { + // adjust prelinked value that is already in memory + value = memory.getLong(relocationAddress) + imageBaseAdjustment; + } + else { + value = addend + imageBaseAdjustment; + } + memory.setLong(relocationAddress, value); + return new RelocationResult(Status.APPLIED, byteLength); + + case R_X86_64_IRELATIVE: + value = addend + elfRelocationContext.getImageBaseWordAdjustmentOffset(); + memory.setLong(relocationAddress, value); + return new RelocationResult(Status.APPLIED, byteLength); + + // Thread Local Symbol relocations (unimplemented concept) + case R_X86_64_DTPMOD64: + case R_X86_64_DTPOFF64: + case R_X86_64_TPOFF64: + case R_X86_64_TLSDESC: + markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, + "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); + return RelocationResult.UNSUPPORTED; + case R_X86_64_COPY: markAsUnsupportedCopy(program, relocationAddress, type, symbolName, symbolIndex, sym.getSize(), elfRelocationContext.getLog()); return RelocationResult.UNSUPPORTED; + default: + break; + } + + // Check for unresolved symbolAddr and symbolValue required by remaining relocation types handled below + if (handleUnresolvedSymbol(elfRelocationContext, relocation, relocationAddress)) { + return RelocationResult.FAILURE; + } + + switch (type) { + case R_X86_64_64: value = symbolValue + addend; memory.setLong(relocationAddress, value); @@ -156,15 +200,6 @@ public class X86_64_ElfRelocationHandler extends memory.setLong(relocationAddress, value); break; - // Thread Local Symbol relocations (unimplemented concept) - case R_X86_64_DTPMOD64: - case R_X86_64_DTPOFF64: - case R_X86_64_TPOFF64: - case R_X86_64_TLSDESC: - markAsWarning(program, relocationAddress, type, symbolName, symbolIndex, - "Thread Local Symbol relocation not supported", elfRelocationContext.getLog()); - return RelocationResult.UNSUPPORTED; - // cases which do not use symbol value case R_X86_64_GOTPC32: @@ -258,28 +293,6 @@ public class X86_64_ElfRelocationHandler extends value = symbolGotAddress.getOffset() + addend - offset; memory.setLong(relocationAddress, value); - case R_X86_64_RELATIVE: - // word64 for LP64 and specifies word32 for ILP32, - // we assume LP64 only. We probably need a hybrid - // variant to handle the ILP32 case. - case R_X86_64_RELATIVE64: - // dl_machine.h - // value = (Elf64_64Addr) map->l_addr + reloc->r_addend - long imageBaseAdjustment = elfRelocationContext.getImageBaseWordAdjustmentOffset(); - if (elfRelocationContext.getElfHeader().isPreLinked()) { - // adjust prelinked value that is already in memory - value = memory.getLong(relocationAddress) + imageBaseAdjustment; - } - else { - value = addend + imageBaseAdjustment; - } - memory.setLong(relocationAddress, value); - break; - case R_X86_64_IRELATIVE: - value = addend + elfRelocationContext.getImageBaseWordAdjustmentOffset(); - memory.setLong(relocationAddress, value); - break; - // case ElfRelocationConstants.R_X86_64_TLSGD: // case ElfRelocationConstants.R_X86_64_TLSLD: // case ElfRelocationConstants.R_X86_64_DTPOFF32: