mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-2814: Fix translation of address operands for guest instructions.
This commit is contained in:
parent
346eef3727
commit
ef6fb310bb
8 changed files with 201 additions and 25 deletions
|
@ -17,6 +17,7 @@ package ghidra.trace.database.listing;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import db.DBRecord;
|
||||
|
@ -24,8 +25,7 @@ import ghidra.program.model.address.*;
|
|||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.ContextChangeException;
|
||||
import ghidra.program.model.listing.FlowOverride;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.trace.database.DBTrace;
|
||||
import ghidra.trace.database.DBTraceUtils;
|
||||
|
@ -106,11 +106,32 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
|||
@Override
|
||||
public ParserContext getParserContext(Address instructionAddress)
|
||||
throws UnknownContextException, MemoryAccessException {
|
||||
// TODO: Does the given address need mapping?
|
||||
return DBTraceInstruction.this.getParserContext(instructionAddress);
|
||||
}
|
||||
}
|
||||
|
||||
protected class GuestMemBuffer implements MemBufferAdapter {
|
||||
@Override
|
||||
public Address getAddress() {
|
||||
return platform.mapHostToGuest(getX1());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Memory getMemory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBigEndian() {
|
||||
return platform.getLanguage().isBigEndian();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes(ByteBuffer buffer, int addressOffset) {
|
||||
return DBTraceInstruction.this.getBytes(buffer, addressOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@DBAnnotatedField(column = PLATFORM_COLUMN_NAME)
|
||||
private int platformKey;
|
||||
@DBAnnotatedField(column = PROTOTYPE_COLUMN_NAME)
|
||||
|
@ -126,6 +147,7 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
|||
protected ParserContext parserContext;
|
||||
protected InternalTracePlatform platform;
|
||||
protected InstructionContext instructionContext;
|
||||
protected MemBuffer memBuffer;
|
||||
|
||||
/**
|
||||
* Construct an instruction unit
|
||||
|
@ -150,9 +172,11 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
|||
this.platform = platform;
|
||||
if (platform.isHost()) {
|
||||
instructionContext = this;
|
||||
memBuffer = this;
|
||||
}
|
||||
else {
|
||||
instructionContext = new GuestInstructionContext();
|
||||
memBuffer = new GuestMemBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,12 +732,13 @@ public class DBTraceInstruction extends AbstractDBTraceCodeUnit<DBTraceInstructi
|
|||
|
||||
@Override
|
||||
public MemBuffer getMemBuffer() {
|
||||
return this;
|
||||
return memBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParserContext getParserContext() throws MemoryAccessException {
|
||||
return parserContext == null ? parserContext = prototype.getParserContext(this, this)
|
||||
return parserContext == null
|
||||
? parserContext = prototype.getParserContext(getMemBuffer(), getProcessorContext())
|
||||
: parserContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,16 +16,18 @@
|
|||
package ghidra.trace.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.InstructionPcodeOverride;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.RefType;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.listing.TraceInstruction;
|
||||
|
||||
public interface InstructionAdapterFromPrototype extends Instruction {
|
||||
public interface InstructionAdapterFromPrototype extends TraceInstruction {
|
||||
default String getFullString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getMnemonicString());
|
||||
|
@ -68,7 +70,7 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
|||
InstructionContext context = getInstructionContext();
|
||||
int opType = prototype.getOpType(opIndex, context);
|
||||
if (OperandType.isAddress(opType)) {
|
||||
return prototype.getAddress(opIndex, context);
|
||||
return getPlatform().mapGuestToHost(prototype.getAddress(opIndex, context));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -106,11 +108,13 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
|||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object opElem : opList) {
|
||||
if (opElem instanceof Address) {
|
||||
Address opAddr = (Address) opElem;
|
||||
if (opElem instanceof Address opAddr) {
|
||||
sb.append("0x");
|
||||
sb.append(opAddr.toString(false));
|
||||
}
|
||||
else if (opElem == null) {
|
||||
sb.append("<null>");
|
||||
}
|
||||
else {
|
||||
sb.append(opElem.toString());
|
||||
}
|
||||
|
@ -120,7 +124,23 @@ public interface InstructionAdapterFromPrototype extends Instruction {
|
|||
|
||||
@Override
|
||||
default List<Object> getDefaultOperandRepresentationList(int opIndex) {
|
||||
return getPrototype().getOpRepresentationList(opIndex, getInstructionContext());
|
||||
// TODO: Cache this in the instruction?
|
||||
List<Object> list =
|
||||
getPrototype().getOpRepresentationList(opIndex, getInstructionContext());
|
||||
TracePlatform platform = getPlatform();
|
||||
if (platform.isHost()) {
|
||||
return list;
|
||||
}
|
||||
return list.stream().map(obj -> {
|
||||
if (obj instanceof Address addr) {
|
||||
Address hostAddr = platform.mapGuestToHost(addr);
|
||||
if (hostAddr == null) {
|
||||
return "guest:" + addr.toString(true);
|
||||
}
|
||||
return hostAddr;
|
||||
}
|
||||
return obj;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue