GP-4737 - Improve ELF relocation handling of unresolved symbol

This commit is contained in:
ghidra1
2024-06-26 12:50:25 -04:00
parent 72d4a342a6
commit 036ef9d0db
20 changed files with 529 additions and 306 deletions

View File

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

View File

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