mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
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:
parent
f022b9a4d5
commit
5b433f35ca
63 changed files with 2146 additions and 1147 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue