GP-3013 Refactor of Relocation API (created V6 DB adapter) to include

status and stored length when original FileBytes are used.
This commit is contained in:
ghidra1 2023-01-17 15:04:22 -05:00
parent f022b9a4d5
commit 5b433f35ca
63 changed files with 2146 additions and 1147 deletions

View file

@ -22,6 +22,8 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.program.model.reloc.RelocationResult;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.util.exception.NotFoundException;
public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
@ -43,13 +45,13 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
}
@Override
public void relocate(ElfRelocationContext context, ElfRelocation relocation,
public RelocationResult relocate(ElfRelocationContext context, ElfRelocation relocation,
Address relocationAddress) throws MemoryAccessException, NotFoundException {
ElfHeader elf = context.getElfHeader();
if (elf.e_machine() != ElfConstants.EM_ARM ||
!(context instanceof ARM_ElfRelocationContext)) {
return;
return RelocationResult.FAILURE;
}
ARM_ElfRelocationContext elfRelocationContext = (ARM_ElfRelocationContext) context;
@ -62,7 +64,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
int type = relocation.getType();
if (type == ARM_ElfRelocationConstants.R_ARM_NONE) {
return;
return RelocationResult.SKIPPED;
}
int symbolIndex = relocation.getSymbolIndex();
@ -80,6 +82,8 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
int newValue = 0;
int byteLength = 4; // most relocations affect 4-bytes (change if different)
switch (type) {
case ARM_ElfRelocationConstants.R_ARM_PC24: { // Target class: ARM Instruction
int oldValue = memory.getInt(relocationAddress, instructionBigEndian);
@ -154,6 +158,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
case ARM_ElfRelocationConstants.R_ARM_ABS16: { // Target class: Data
short sValue = (short) (symbolValue + addend);
memory.setShort(relocationAddress, sValue);
byteLength = 2;
break;
}
case ARM_ElfRelocationConstants.R_ARM_ABS12: { // Target class: ARM Instruction
@ -171,6 +176,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
case ARM_ElfRelocationConstants.R_ARM_ABS_8: { // Target class: Data
byte bValue = (byte) (symbolValue + addend);
memory.setByte(relocationAddress, bValue);
byteLength = 1;
break;
}
/*
@ -221,6 +227,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
newValue = newValue >> 1;
short sValue = (short) ((oldValue & 0xff00) | (newValue & 0x00ff));
memory.setShort(relocationAddress, sValue, instructionBigEndian);
byteLength = 2;
break;
}
/*
@ -270,6 +277,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
// GOT entry bytes if it refers to .plt block
Address symAddress = elfRelocationContext.getSymbolAddress(sym);
MemoryBlock block = memory.getBlock(symAddress);
// 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());
@ -284,7 +292,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
markAsError(program, relocationAddress, "R_ARM_JUMP_SLOT", symbolName,
"Failed to create R_ARM_JUMP_SLOT external function",
elfRelocationContext.getLog());
return;
// relocation already applied above
}
}
break;
@ -592,6 +600,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
newValue -= (offset + elfRelocationContext.getPcBias(true)); // PC relative
newValue = (oldValue & 0x0000f800) | ((newValue >> 1) & 0x000007ff);
memory.setShort(relocationAddress, (short) newValue, instructionBigEndian);
byteLength = 2;
break;
}
case ARM_ElfRelocationConstants.R_ARM_THM_JUMP8: {
@ -603,6 +612,7 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
newValue -= (offset + elfRelocationContext.getPcBias(true)); // PC relative
newValue = (oldValue & 0x0000ff00) | ((newValue >> 1) & 0x000000ff);
memory.setShort(relocationAddress, (short) newValue, instructionBigEndian);
byteLength = 2;
break;
}
/*
@ -689,15 +699,16 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
case ARM_ElfRelocationConstants.R_ARM_COPY: {
markAsWarning(program, relocationAddress, "R_ARM_COPY", symbolName, symbolIndex,
"Runtime copy not supported", elfRelocationContext.getLog());
break;
return RelocationResult.UNSUPPORTED;
}
default: {
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog());
break;
return RelocationResult.UNSUPPORTED;
}
}
return new RelocationResult(Status.APPLIED, byteLength);
}
private boolean isThumb(ElfSymbol symbol) {

View file

@ -17,10 +17,12 @@ package ghidra.app.util.bin.format.macho.relocation;
import static ghidra.app.util.bin.format.macho.relocation.ARM_MachoRelocationConstants.*;
import ghidra.app.util.bin.format.RelocationException;
import ghidra.app.util.bin.format.macho.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.util.exception.NotFoundException;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationResult;
/**
* A {@link MachoRelocationHandler} for ARM
@ -43,24 +45,25 @@ public class ARM_MachoRelocationHandler extends MachoRelocationHandler {
}
@Override
public void relocate(MachoRelocation relocation)
throws MemoryAccessException, NotFoundException {
public RelocationResult relocate(MachoRelocation relocation)
throws MemoryAccessException, RelocationException {
if (!relocation.requiresRelocation()) {
return;
return RelocationResult.SKIPPED;
}
RelocationInfo relocationInfo = relocation.getRelocationInfo();
Address targetAddr = relocation.getTargetAddress();
long orig = read(relocation);
int byteLength;
switch (relocationInfo.getType()) {
case ARM_RELOC_VANILLA:
if (!relocationInfo.isPcRelocated()) {
write(relocation, targetAddr.getOffset());
byteLength = write(relocation, targetAddr.getOffset());
}
else {
throw new NotFoundException("Unimplemented relocation");
return RelocationResult.UNSUPPORTED;
}
break;
case ARM_THUMB_RELOC_BR22: {
@ -86,7 +89,7 @@ public class ARM_MachoRelocationHandler extends MachoRelocationHandler {
imm11 = (value >> 1) & 0x7ff;
long instr = orig & (blx ? 0xc000f800 : 0xd000f800);
instr |= (j1 << 29) | (j2 << 27) | (imm11 << 16) | (s << 10) | imm10;
write(relocation, instr);
byteLength = write(relocation, instr);
break;
}
@ -99,7 +102,8 @@ public class ARM_MachoRelocationHandler extends MachoRelocationHandler {
case ARM_RELOC_HALF: // relocation not required (scattered)
case ARM_RELOC_HALF_SECTDIFF: // relocation not required (scattered)
default:
throw new NotFoundException("Unimplemented relocation");
return RelocationResult.UNSUPPORTED;
}
return new RelocationResult(Status.APPLIED, byteLength);
}
}