GP-1818 Refactor decompiler overlay translations

This commit is contained in:
caheckman 2022-08-19 19:57:55 -04:00
parent 6911befabb
commit 8b5ec1b439
21 changed files with 259 additions and 279 deletions

View file

@ -13,12 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* Created on Jun 12, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package ghidra.app.decompiler; package ghidra.app.decompiler;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@ -54,7 +48,7 @@ public class ClangFuncNameToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override
@ -62,7 +56,7 @@ public class ClangFuncNameToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override

View file

@ -13,12 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* Created on Jun 12, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package ghidra.app.decompiler; package ghidra.app.decompiler;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@ -49,7 +43,7 @@ public class ClangOpToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override
@ -57,7 +51,7 @@ public class ClangOpToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override

View file

@ -13,12 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* Created on Jun 12, 2003
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package ghidra.app.decompiler; package ghidra.app.decompiler;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@ -59,7 +53,7 @@ public class ClangVariableToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override
@ -67,7 +61,7 @@ public class ClangVariableToken extends ClangToken {
if (op == null) { if (op == null) {
return null; return null;
} }
return op.getSeqnum().getTarget().getPhysicalAddress(); return op.getSeqnum().getTarget();
} }
@Override @Override

View file

@ -26,7 +26,7 @@ import java.io.*;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.app.plugin.processors.sleigh.UniqueLayout; import ghidra.app.plugin.processors.sleigh.UniqueLayout;
import ghidra.program.model.address.Address; import ghidra.program.model.address.*;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
@ -78,6 +78,51 @@ import ghidra.util.task.TaskMonitor;
*/ */
public class DecompInterface { public class DecompInterface {
public static class EncodeDecodeSet {
public OverlayAddressSpace overlay; // Active overlay space or null
public Encoder mainQuery; // Encoder for main query to decompiler process
public PackedDecode mainResponse; // Decoder for main response from the decompiler process
public PackedDecode callbackQuery; // Decoder for queries from the decompiler process
public PackedEncode callbackResponse; // Encode for response to decompiler queries
/**
* Set up encoders and decoders for functions that are not in overlay address spaces
* @param program is the active Program
*/
public EncodeDecodeSet(Program program) {
overlay = null;
mainQuery = new PackedEncode();
mainResponse = new PackedDecode(program.getAddressFactory());
callbackQuery = new PackedDecode(program.getAddressFactory());
callbackResponse = new PackedEncode();
}
/**
* Set up encoders and decoders for functions in an overlay space
* @param program is the active Program
* @param spc is the initial overlay space to set up for
* @throws AddressFormatException if address translation is not supported for the overlay
*/
public EncodeDecodeSet(Program program, OverlayAddressSpace spc)
throws AddressFormatException {
mainQuery = new PackedEncodeOverlay(spc);
mainResponse = new PackedDecodeOverlay(program.getAddressFactory(), spc);
callbackQuery = new PackedDecodeOverlay(program.getAddressFactory(), spc);
callbackResponse = new PackedEncodeOverlay(spc);
}
public void setOverlay(OverlayAddressSpace spc) throws AddressFormatException {
if (overlay == spc) {
return;
}
overlay = spc;
((PackedEncodeOverlay) mainQuery).setOverlay(spc);
((PackedDecodeOverlay) mainResponse).setOverlay(spc);
((PackedDecodeOverlay) callbackQuery).setOverlay(spc);
((PackedEncodeOverlay) callbackResponse).setOverlay(spc);
}
}
protected Program program; protected Program program;
private SleighLanguage pcodelanguage; private SleighLanguage pcodelanguage;
private PcodeDataTypeManager dtmanage; private PcodeDataTypeManager dtmanage;
@ -87,8 +132,8 @@ public class DecompInterface {
protected CompilerSpec compilerSpec; protected CompilerSpec compilerSpec;
protected DecompileProcess decompProcess; protected DecompileProcess decompProcess;
protected DecompileCallback decompCallback; protected DecompileCallback decompCallback;
protected PackedEncode paramEncode; // Encoder for decompiler command parameters protected EncodeDecodeSet baseEncodingSet; // Encoders/decoders for functions not in overlay
protected Decoder decoder; // Decoder for the Decompiler's main outputs protected EncodeDecodeSet overlayEncodingSet; // Encoders/decoders for functions in overlays
protected StringIngest stringResponse = new StringIngest(); // Ingester for simple responses protected StringIngest stringResponse = new StringIngest(); // Ingester for simple responses
private DecompileDebug debug; private DecompileDebug debug;
protected CancelledListener monitorListener = new CancelledListener() { protected CancelledListener monitorListener = new CancelledListener() {
@ -112,8 +157,8 @@ public class DecompInterface {
dtmanage = null; dtmanage = null;
decompCallback = null; decompCallback = null;
options = null; options = null;
paramEncode = null; baseEncodingSet = null;
decoder = null; overlayEncodingSet = null;
debug = null; debug = null;
decompileMessage = ""; decompileMessage = "";
compilerSpec = null; compilerSpec = null;
@ -239,10 +284,11 @@ public class DecompInterface {
throw new IOException("Could not register program: " + nativeMessage); throw new IOException("Could not register program: " + nativeMessage);
} }
if (options != null) { if (options != null) {
paramEncode.clear(); baseEncodingSet.mainQuery.clear();
options.encode(paramEncode, this); options.encode(baseEncodingSet.mainQuery, this);
decompProcess.setMaxResultSize(options.getMaxPayloadMBytes()); decompProcess.setMaxResultSize(options.getMaxPayloadMBytes());
decompProcess.sendCommand1Param("setOptions", paramEncode, stringResponse); decompProcess.sendCommand1Param("setOptions", baseEncodingSet.mainQuery,
stringResponse);
if (!stringResponse.toString().equals("t")) { if (!stringResponse.toString().equals("t")) {
throw new IOException("Did not accept decompiler options"); throw new IOException("Did not accept decompiler options");
} }
@ -323,8 +369,7 @@ public class DecompInterface {
compilerSpec = spec; compilerSpec = spec;
dtmanage = new PcodeDataTypeManager(prog); dtmanage = new PcodeDataTypeManager(prog);
paramEncode = new PackedEncode(); baseEncodingSet = new EncodeDecodeSet(prog);
decoder = new PackedDecode(prog.getAddressFactory());
try { try {
decompCallback = decompCallback =
new DecompileCallback(prog, pcodelanguage, program.getCompilerSpec(), dtmanage); new DecompileCallback(prog, pcodelanguage, program.getCompilerSpec(), dtmanage);
@ -346,8 +391,7 @@ public class DecompInterface {
} }
program = null; program = null;
decompCallback = null; decompCallback = null;
paramEncode = null; baseEncodingSet = null;
decoder = null;
return false; return false;
} }
@ -363,8 +407,8 @@ public class DecompInterface {
if (program != null) { if (program != null) {
program = null; program = null;
decompCallback = null; decompCallback = null;
paramEncode = null; baseEncodingSet = null;
decoder = null; overlayEncodingSet = null;
try { try {
if ((decompProcess != null) && decompProcess.isReady()) { if ((decompProcess != null) && decompProcess.isReady()) {
decompProcess.deregisterProgram(); decompProcess.deregisterProgram();
@ -604,10 +648,11 @@ public class DecompInterface {
} }
try { try {
verifyProcess(); verifyProcess();
paramEncode.clear(); baseEncodingSet.mainQuery.clear();
options.encode(paramEncode, this); options.encode(baseEncodingSet.mainQuery, this);
decompProcess.setMaxResultSize(options.getMaxPayloadMBytes()); decompProcess.setMaxResultSize(options.getMaxPayloadMBytes());
decompProcess.sendCommand1Param("setOptions", paramEncode, stringResponse); decompProcess.sendCommand1Param("setOptions", baseEncodingSet.mainQuery,
stringResponse);
return stringResponse.toString().equals("t"); return stringResponse.toString().equals("t");
} }
catch (IOException e) { catch (IOException e) {
@ -668,15 +713,15 @@ public class DecompInterface {
} }
BlockGraph resgraph = null; BlockGraph resgraph = null;
try { try {
setupEncodeDecode(Address.NO_ADDRESS);
verifyProcess(); verifyProcess();
paramEncode.clear(); baseEncodingSet.mainQuery.clear();
ingraph.encode(paramEncode); ingraph.encode(baseEncodingSet.mainQuery);
decompProcess.sendCommand1ParamTimeout("structureGraph", paramEncode, timeoutSecs, decompProcess.sendCommandTimeout("structureGraph", timeoutSecs, baseEncodingSet);
decoder);
decompileMessage = decompCallback.getNativeMessage(); decompileMessage = decompCallback.getNativeMessage();
if (!decoder.isEmpty()) { if (!baseEncodingSet.mainResponse.isEmpty()) {
resgraph = new BlockGraph(); resgraph = new BlockGraph();
resgraph.decode(decoder); resgraph.decode(baseEncodingSet.mainResponse);
resgraph.transferObjectRef(ingraph); resgraph.transferObjectRef(ingraph);
} }
} }
@ -716,17 +761,19 @@ public class DecompInterface {
DecompileProcess.DisposeState.DISPOSED_ON_CANCEL); DecompileProcess.DisposeState.DISPOSED_ON_CANCEL);
} }
Decoder decoder = null;
try { try {
Address funcEntry = func.getEntryPoint(); Address funcEntry = func.getEntryPoint();
if (debug != null) { if (debug != null) {
debug.setFunction(func); debug.setFunction(func);
} }
decompCallback.setFunction(func, funcEntry, debug); decompCallback.setFunction(func, funcEntry, debug);
EncodeDecodeSet activeSet = setupEncodeDecode(funcEntry);
decoder = activeSet.mainResponse;
verifyProcess(); verifyProcess();
paramEncode.clear(); activeSet.mainQuery.clear();
AddressXML.encode(paramEncode, funcEntry); AddressXML.encode(activeSet.mainQuery, funcEntry);
decompProcess.sendCommand1ParamTimeout("decompileAt", paramEncode, timeoutSecs, decompProcess.sendCommandTimeout("decompileAt", timeoutSecs, activeSet);
decoder);
decompileMessage = decompCallback.getNativeMessage(); decompileMessage = decompCallback.getNativeMessage();
if (debug != null) { if (debug != null) {
XmlEncode xmlEncode = new XmlEncode(); XmlEncode xmlEncode = new XmlEncode();
@ -806,4 +853,28 @@ public class DecompInterface {
public CompilerSpec getCompilerSpec() { public CompilerSpec getCompilerSpec() {
return compilerSpec; return compilerSpec;
} }
/**
* Setup the correct Encoder and Decoder to use for the decompilation.
* Generally we use the base versions unless there is an overlay. In which case we switch
* to special translating encoders and decoders.
* @param addr is the address of the function being decompiled
* @return the set of encoders and decoders that should be used
* @throws AddressFormatException if decompilation is not supported for the (overlay) address
*/
protected EncodeDecodeSet setupEncodeDecode(Address addr) throws AddressFormatException {
AddressSpace spc = addr.getAddressSpace();
if (!spc.isOverlaySpace()) {
return baseEncodingSet;
}
OverlayAddressSpace overlay = (OverlayAddressSpace) spc;
if (overlayEncodingSet == null) {
overlayEncodingSet = new EncodeDecodeSet(program, overlay);
}
else {
overlayEncodingSet.setOverlay(overlay);
}
return overlayEncodingSet;
}
} }

View file

@ -63,7 +63,6 @@ public class DecompileCallback {
private Function cachedFunction; private Function cachedFunction;
private AddressSet undefinedBody; private AddressSet undefinedBody;
private Address funcEntry; private Address funcEntry;
private AddressSpace overlaySpace; // non-null if function being decompiled is in an overlay
private int default_extrapop; private int default_extrapop;
private Language pcodelanguage; private Language pcodelanguage;
private CompilerSpec pcodecompilerspec; private CompilerSpec pcodecompilerspec;
@ -105,8 +104,6 @@ public class DecompileCallback {
undefinedBody = new AddressSet(func.getBody()); undefinedBody = new AddressSet(func.getBody());
} }
funcEntry = entry; funcEntry = entry;
AddressSpace spc = funcEntry.getAddressSpace();
overlaySpace = spc.isOverlaySpace() ? spc : null;
debug = dbg; debug = dbg;
if (debug != null) { if (debug != null) {
debug.setPcodeDataTypeManager(dtmanage); debug.setPcodeDataTypeManager(dtmanage);
@ -141,9 +138,6 @@ public class DecompileCallback {
* @return the bytes matching the query or null if the query can't be met * @return the bytes matching the query or null if the query can't be met
*/ */
public byte[] getBytes(Address addr, int size) { public byte[] getBytes(Address addr, int size) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
if (addr == Address.NO_ADDRESS) { if (addr == Address.NO_ADDRESS) {
Msg.error(this, "Address does not physically map"); Msg.error(this, "Address does not physically map");
return null; return null;
@ -186,9 +180,6 @@ public class DecompileCallback {
* @throws IOException for errors in the underlying stream * @throws IOException for errors in the underlying stream
*/ */
public void getComments(Address addr, int types, Encoder resultEncoder) throws IOException { public void getComments(Address addr, int types, Encoder resultEncoder) throws IOException {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
Function func = getFunctionAt(addr); Function func = getFunctionAt(addr);
if (func == null) { if (func == null) {
return; return;
@ -207,9 +198,6 @@ public class DecompileCallback {
* @param resultEncoder will contain the generated p-code ops * @param resultEncoder will contain the generated p-code ops
*/ */
public void getPcode(Address addr, PackedEncode resultEncoder) { public void getPcode(Address addr, PackedEncode resultEncoder) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
try { try {
Instruction instr = getInstruction(addr); Instruction instr = getInstruction(addr);
if (instr == null) { if (instr == null) {
@ -437,9 +425,6 @@ public class DecompileCallback {
* @return the symbol or null if no symbol is found * @return the symbol or null if no symbol is found
*/ */
public String getCodeLabel(Address addr) { public String getCodeLabel(Address addr) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
try { try {
Symbol sym = program.getSymbolTable().getPrimarySymbol(addr); Symbol sym = program.getSymbolTable().getPrimarySymbol(addr);
if (sym == null) { if (sym == null) {
@ -669,9 +654,6 @@ public class DecompileCallback {
* @param resultEncoder is where to write encoded description * @param resultEncoder is where to write encoded description
*/ */
public void getMappedSymbols(Address addr, Encoder resultEncoder) { public void getMappedSymbols(Address addr, Encoder resultEncoder) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
if (addr == Address.NO_ADDRESS) { if (addr == Address.NO_ADDRESS) {
// Unknown spaces may result from "spacebase" registers defined in cspec // Unknown spaces may result from "spacebase" registers defined in cspec
return; return;
@ -712,9 +694,6 @@ public class DecompileCallback {
* @param resultEncoder will contain the resulting description * @param resultEncoder will contain the resulting description
*/ */
public void getExternalRef(Address addr, Encoder resultEncoder) { public void getExternalRef(Address addr, Encoder resultEncoder) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
try { try {
Function func = null; Function func = null;
if (cachedFunction != null && cachedFunction.getEntryPoint().equals(addr)) { if (cachedFunction != null && cachedFunction.getEntryPoint().equals(addr)) {
@ -824,9 +803,6 @@ public class DecompileCallback {
* @throws IOException for errors in the underlying stream writing the result * @throws IOException for errors in the underlying stream writing the result
*/ */
public void getTrackedRegisters(Address addr, Encoder resultEncoder) throws IOException { public void getTrackedRegisters(Address addr, Encoder resultEncoder) throws IOException {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
ProgramContext context = program.getProgramContext(); ProgramContext context = program.getProgramContext();
encodeTrackedPointSet(resultEncoder, addr, context); encodeTrackedPointSet(resultEncoder, addr, context);
@ -1012,14 +988,14 @@ public class DecompileCallback {
Address first = range.getMinAddress(); Address first = range.getMinAddress();
Address last = range.getMaxAddress(); Address last = range.getMaxAddress();
boolean readonly = true; // Treat function body as readonly boolean readonly = true; // Treat function body as readonly
encodeHole(encoder, first.getAddressSpace().getPhysicalSpace(), encodeHole(encoder, first.getAddressSpace(), first.getUnsignedOffset(),
first.getUnsignedOffset(), last.getUnsignedOffset(), readonly, false); last.getUnsignedOffset(), readonly, false);
return; return;
} }
} }
// There is probably some sort of error, just return a block // There is probably some sort of error, just return a block
// containing the single queried address // containing the single queried address
encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(), encodeHole(encoder, addr.getAddressSpace(), addr.getUnsignedOffset(),
addr.getUnsignedOffset(), true, false); addr.getUnsignedOffset(), true, false);
} }
@ -1084,7 +1060,7 @@ public class DecompileCallback {
private void encodeHole(Encoder encoder, Address addr) throws IOException { private void encodeHole(Encoder encoder, Address addr) throws IOException {
boolean readonly = isReadOnlyNoData(addr); boolean readonly = isReadOnlyNoData(addr);
boolean isvolatile = isVolatileNoData(addr); boolean isvolatile = isVolatileNoData(addr);
encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(), encodeHole(encoder, addr.getAddressSpace(), addr.getUnsignedOffset(),
addr.getUnsignedOffset(), readonly, isvolatile); addr.getUnsignedOffset(), readonly, isvolatile);
} }
@ -1242,9 +1218,6 @@ public class DecompileCallback {
* @return the UTF8 encoded byte array or null * @return the UTF8 encoded byte array or null
*/ */
public StringData getStringData(Address addr, int maxChars, String dtName, long dtId) { public StringData getStringData(Address addr, int maxChars, String dtName, long dtId) {
if (overlaySpace != null) {
addr = overlaySpace.getOverlayAddress(addr);
}
if (addr == Address.NO_ADDRESS) { if (addr == Address.NO_ADDRESS) {
Msg.error(this, "Address does not physically map"); Msg.error(this, "Address does not physically map");
return null; return null;

View file

@ -235,8 +235,7 @@ public class DecompileDebug {
} }
if (!tagstarted) { if (!tagstarted) {
buf.append("<bytechunk"); buf.append("<bytechunk");
SpecXmlUtils.encodeStringAttribute(buf, "space", SpecXmlUtils.encodeStringAttribute(buf, "space", space.getName());
space.getPhysicalSpace().getName());
SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "offset", SpecXmlUtils.encodeUnsignedIntegerAttribute(buf, "offset",
chunk.addr.getOffset() + chunk.min); chunk.addr.getOffset() + chunk.min);
if (lastreadonly) { if (lastreadonly) {

View file

@ -73,9 +73,9 @@ public class DecompileProcess {
private String programSource; // String describing program for error reports private String programSource; // String describing program for error reports
private int maxResultSizeMBYtes = 50; // maximum result size in MBytes to allow from decompiler private int maxResultSizeMBYtes = 50; // maximum result size in MBytes to allow from decompiler
private PackedDecode paramDecoder; // Ingest queries from the decompiler process private PackedDecode paramDecoder; // Decoder to use for queries from the decompiler
private PackedEncode resultEncoder; // Encoder to use for query responses
private StringIngest stringDecoder; // Ingest of exception and status messages private StringIngest stringDecoder; // Ingest of exception and status messages
private PackedEncode resultEncoder; // Encode responses to decompile process queries
public enum DisposeState { public enum DisposeState {
NOT_DISPOSED, // Process was/is not disposed NOT_DISPOSED, // Process was/is not disposed
@ -416,9 +416,13 @@ public class DecompileProcess {
throws IOException, DecompileException { throws IOException, DecompileException {
callback = cback; callback = cback;
programSource = program.getName(); programSource = program.getName();
resultEncoder = new PackedEncode();
// Decompiler process may callback during the registerProgram operation
// so provide query/reponse decoding/encoding
paramDecoder = new PackedDecode(program.getAddressFactory()); paramDecoder = new PackedDecode(program.getAddressFactory());
StringIngest response = new StringIngest(); // Don't use stringResponse resultEncoder = new PackedEncode();
StringIngest response = new StringIngest(); // Don't use stringDecoder
setup(); setup();
try { try {
@ -455,6 +459,8 @@ public class DecompileProcess {
writeString("deregisterProgram"); writeString("deregisterProgram");
writeString(Integer.toString(archId)); writeString(Integer.toString(archId));
write(command_end); write(command_end);
paramDecoder = null; // Don't expect callback queries
resultEncoder = null;
StringIngest response = new StringIngest(); // Don't use stringResponse StringIngest response = new StringIngest(); // Don't use stringResponse
readResponse(response); readResponse(response);
int res = Integer.parseInt(response.toString()); int res = Integer.parseInt(response.toString());
@ -477,6 +483,8 @@ public class DecompileProcess {
if (!statusGood) { if (!statusGood) {
throw new IOException(command + " called on bad process"); throw new IOException(command + " called on bad process");
} }
paramDecoder = null; // Don't expect callback queries
resultEncoder = null;
try { try {
write(command_start); write(command_start);
writeString(command); writeString(command);
@ -495,20 +503,23 @@ public class DecompileProcess {
} }
/** /**
* Execute a command with a timeout. Parameters are in the encodingSet.mainQuery.
* The response gets written to encodingSet.mainResponse.
* @param command the decompiler should execute * @param command the decompiler should execute
* @param param an additional (encoded) parameter for the command
* @param timeoutSecs the number of seconds to run before timing out * @param timeoutSecs the number of seconds to run before timing out
* @param response the response accumulator * @param encodeSet contains encoded parameters and the response container
* @throws IOException for any problems with the pipe to the decompiler process * @throws IOException for any problems with the pipe to the decompiler process
* @throws DecompileException for any problems while executing the command * @throws DecompileException for any problems while executing the command
*/ */
public synchronized void sendCommand1ParamTimeout(String command, Encoder param, public synchronized void sendCommandTimeout(String command, int timeoutSecs,
int timeoutSecs, ByteIngest response) throws IOException, DecompileException { DecompInterface.EncodeDecodeSet encodeSet) throws IOException, DecompileException {
if (!statusGood) { if (!statusGood) {
throw new IOException(command + " called on bad process"); throw new IOException(command + " called on bad process");
} }
paramDecoder = encodeSet.callbackQuery;
resultEncoder = encodeSet.callbackResponse;
int validatedTimeoutMs = getTimeoutMs(timeoutSecs); int validatedTimeoutMs = getTimeoutMs(timeoutSecs);
GTimerMonitor timerMonitor = GTimer.scheduleRunnable(validatedTimeoutMs, timeoutRunnable); GTimerMonitor timerMonitor = GTimer.scheduleRunnable(validatedTimeoutMs, timeoutRunnable);
@ -516,9 +527,9 @@ public class DecompileProcess {
write(command_start); write(command_start);
writeString(command); writeString(command);
writeString(Integer.toString(archId)); writeString(Integer.toString(archId));
writeString(param); writeString(encodeSet.mainQuery);
write(command_end); write(command_end);
readResponse(response); readResponse(encodeSet.mainResponse);
} }
catch (IOException e) { catch (IOException e) {
statusGood = false; statusGood = false;
@ -554,6 +565,8 @@ public class DecompileProcess {
if (!statusGood) { if (!statusGood) {
throw new IOException(command + " called on bad process"); throw new IOException(command + " called on bad process");
} }
paramDecoder = null; // Don't expect callback queries
resultEncoder = null;
try { try {
write(command_start); write(command_start);
writeString(command); writeString(command);
@ -591,6 +604,8 @@ public class DecompileProcess {
if (!statusGood) { if (!statusGood) {
throw new IOException(command + " called on bad process"); throw new IOException(command + " called on bad process");
} }
paramDecoder = null; // Don't expect callback queries
resultEncoder = null;
try { try {
write(command_start); write(command_start);
writeString(command); writeString(command);
@ -618,6 +633,8 @@ public class DecompileProcess {
if (!statusGood) { if (!statusGood) {
throw new IOException(command + " called on bad process"); throw new IOException(command + " called on bad process");
} }
paramDecoder = null; // Don't expect callback queries
resultEncoder = null;
try { try {
write(command_start); write(command_start);
writeString(command); writeString(command);

View file

@ -506,9 +506,7 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
return; return;
} }
Address translated = translate(address); List<ClangToken> tokens = DecompilerUtils.getTokensFromView(layoutMgr.getFields(), address);
List<ClangToken> tokens =
DecompilerUtils.getTokensFromView(layoutMgr.getFields(), translated);
goToBeginningOfLine(tokens); goToBeginningOfLine(tokens);
} }
@ -611,65 +609,13 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
return 0; return 0;
} }
/**
* Translate Ghidra address to decompiler address. Functions within an overlay space are
* decompiled in their physical space, therefore decompiler results refer to the functions
* underlying .physical space
*
* @param addr the Ghidra address
* @return the decompiler address
*/
private Address translate(Address addr) {
Function func = decompileData.getFunction();
if (func == null) {
return addr;
}
AddressSpace funcSpace = func.getEntryPoint().getAddressSpace();
if (funcSpace.isOverlaySpace() && addr.getAddressSpace().equals(funcSpace)) {
return addr.getPhysicalAddress();
}
return addr;
}
/**
* Translate Ghidra address set to decompiler address set. Functions within an overlay space are
* decompiled in their physical space, therefore decompiler results refer to the functions
* underlying .physical space
*
* @param set the Ghidra addresses
* @return the decompiler addresses
*/
private AddressSetView translateSet(AddressSetView set) {
Function func = decompileData.getFunction();
if (func == null) {
return set;
}
AddressSpace funcSpace = func.getEntryPoint().getAddressSpace();
if (!funcSpace.isOverlaySpace()) {
return set;
}
AddressSet newSet = new AddressSet();
AddressRangeIterator iter = set.getAddressRanges();
while (iter.hasNext()) {
AddressRange range = iter.next();
Address min = range.getMinAddress();
if (min.getAddressSpace().equals(funcSpace)) {
Address max = range.getMaxAddress();
range = new AddressRangeImpl(min.getPhysicalAddress(), max.getPhysicalAddress());
}
newSet.add(range);
}
return newSet;
}
void setSelection(ProgramSelection selection) { void setSelection(ProgramSelection selection) {
FieldSelection fieldSelection = null; FieldSelection fieldSelection = null;
if (selection == null || selection.isEmpty()) { if (selection == null || selection.isEmpty()) {
fieldSelection = new FieldSelection(); fieldSelection = new FieldSelection();
} }
else { else {
List<ClangToken> tokens = List<ClangToken> tokens = DecompilerUtils.getTokens(layoutMgr.getRoot(), selection);
DecompilerUtils.getTokens(layoutMgr.getRoot(), translateSet(selection));
fieldSelection = DecompilerUtils.getFieldSelection(tokens); fieldSelection = DecompilerUtils.getFieldSelection(tokens);
} }
fieldPanel.setSelection(fieldSelection); fieldPanel.setSelection(fieldSelection);
@ -975,9 +921,6 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
address = decompileData.getFunction().getEntryPoint(); address = decompileData.getFunction().getEntryPoint();
} }
// adjust in case function is in an overlay space.
address = decompileData.getFunctionSpace().getOverlayAddress(address);
return new DecompilerLocation(decompileData.getProgram(), address, return new DecompilerLocation(decompileData.getProgram(), address,
decompileData.getFunction().getEntryPoint(), decompileData.getDecompileResults(), token, decompileData.getFunction().getEntryPoint(), decompileData.getDecompileResults(), token,
location.getIndex().intValue(), location.col); location.getIndex().intValue(), location.col);

View file

@ -382,8 +382,6 @@ public class DecompilerUtils {
Address minAddress = token.getMinAddress(); Address minAddress = token.getMinAddress();
Address maxAddress = token.getMaxAddress(); Address maxAddress = token.getMaxAddress();
maxAddress = maxAddress == null ? minAddress : maxAddress; maxAddress = maxAddress == null ? minAddress : maxAddress;
minAddress = space.getOverlayAddress(minAddress);
maxAddress = space.getOverlayAddress(maxAddress);
addrs.addRange(minAddress, maxAddress); addrs.addRange(minAddress, maxAddress);
} }
@ -602,8 +600,8 @@ public class DecompilerUtils {
return brace; return brace;
} }
private static ClangSyntaxToken moveToNextBrace(ClangToken startToken, private static ClangSyntaxToken moveToNextBrace(ClangToken startToken, List<ClangNode> list,
List<ClangNode> list, String targetBrace, boolean forward) { String targetBrace, boolean forward) {
int balance = 0; int balance = 0;
int index = list.indexOf(startToken); int index = list.indexOf(startToken);

View file

@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* Created on Feb 4, 2005
*
*/
package ghidra.app.plugin.processors.sleigh; package ghidra.app.plugin.processors.sleigh;
import java.io.IOException; import java.io.IOException;
@ -63,7 +59,6 @@ public abstract class PcodeEmit {
private AddressSpace uniq_space; private AddressSpace uniq_space;
private long uniquemask; private long uniquemask;
private long uniqueoffset; private long uniqueoffset;
private AddressSpace overlayspace = null;
/** /**
* Pcode emitter constructor for empty or unimiplemented instructions * Pcode emitter constructor for empty or unimiplemented instructions
@ -85,12 +80,6 @@ public abstract class PcodeEmit {
this.instcontext = ictx; this.instcontext = ictx;
this.const_space = walk.getConstSpace(); this.const_space = walk.getConstSpace();
this.startAddress = parsercontext.getAddr(); this.startAddress = parsercontext.getAddr();
AddressSpace myspace = startAddress.getAddressSpace();
if (myspace.isOverlaySpace()) {
overlayspace = myspace;
startAddress = ((OverlayAddressSpace) myspace).getOverlayedSpace()
.getAddress(startAddress.getOffset());
}
this.fallOffset = fallOffset; this.fallOffset = fallOffset;
this.override = override; this.override = override;
SleighInstructionPrototype sleighproto = parsercontext.getPrototype(); SleighInstructionPrototype sleighproto = parsercontext.getPrototype();
@ -202,7 +191,7 @@ public abstract class PcodeEmit {
} }
VarnodeData dest = new VarnodeData(); VarnodeData dest = new VarnodeData();
dest.space = fallOverride.getAddressSpace().getPhysicalSpace(); dest.space = fallOverride.getAddressSpace();
dest.offset = fallOverride.getOffset(); dest.offset = fallOverride.getOffset();
dest.size = dest.space.getPointerSize(); dest.size = dest.space.getPointerSize();
@ -675,9 +664,6 @@ public abstract class PcodeEmit {
AddressSpace spc = vn.getSpace().fixSpace(walker); AddressSpace spc = vn.getSpace().fixSpace(walker);
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
// translate the address into the overlayspace if we have an overlayspace. // translate the address into the overlayspace if we have an overlayspace.
if (overlayspace != null) {
addr = overlayspace.getOverlayAddress(addr);
}
ParserWalker oldwalker = walker; ParserWalker oldwalker = walker;
long olduniqueoffset = uniqueoffset; long olduniqueoffset = uniqueoffset;
setUniqueOffset(addr); setUniqueOffset(addr);
@ -770,30 +756,6 @@ public abstract class PcodeEmit {
} }
} }
void checkOverlays(int opcode, VarnodeData[] in, int isize, VarnodeData out) {
if (overlayspace != null) {
if ((opcode == PcodeOp.LOAD) || (opcode == PcodeOp.STORE)) {
int spaceId = (int) in[0].offset;
AddressSpace space = addressFactory.getAddressSpace(spaceId);
if (space.isOverlaySpace()) {
space = ((OverlayAddressSpace) space).getOverlayedSpace();
in[0].offset = space.getSpaceID();
}
}
for (int i = 0; i < isize; ++i) {
VarnodeData v = in[i];
if (v.space.equals(overlayspace)) {
v.space = ((OverlayAddressSpace) v.space).getOverlayedSpace();
}
}
if (out != null) {
if (out.space.equals(overlayspace)) {
out.space = ((OverlayAddressSpace) out.space).getOverlayedSpace();
}
}
}
}
/** /**
* Applies opcode-specific overrides * Applies opcode-specific overrides
* @param opcode opcode of instruction * @param opcode opcode of instruction

View file

@ -125,7 +125,6 @@ public class PcodeEmitPacked extends PcodeEmit {
void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out) void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out)
throws IOException { throws IOException {
opcode = checkOverrides(opcode, in); opcode = checkOverrides(opcode, in);
checkOverlays(opcode, in, isize, out);
encoder.openElement(ELEM_OP); encoder.openElement(ELEM_OP);
encoder.writeSignedInteger(ATTRIB_CODE, opcode); encoder.writeSignedInteger(ATTRIB_CODE, opcode);
encoder.writeSignedInteger(ATTRIB_SIZE, isize); encoder.writeSignedInteger(ATTRIB_SIZE, isize);

View file

@ -606,7 +606,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
VarnodeTpl vn = rec.op.getInput()[0]; VarnodeTpl vn = rec.op.getInput()[0];
AddressSpace spc = vn.getSpace().fixSpace(walker); AddressSpace spc = vn.getSpace().fixSpace(walker);
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
addr = handleOverlayAddress(context, addr);
SleighParserContext crosscontext = SleighParserContext crosscontext =
(SleighParserContext) context.getParserContext(addr); (SleighParserContext) context.getParserContext(addr);
int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal(); int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal();
@ -621,15 +620,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
return curflags; return curflags;
} }
private Address handleOverlayAddress(InstructionContext context, Address addr) {
AddressSpace addressSpace = context.getAddress().getAddressSpace();
if (addressSpace.isOverlaySpace()) {
OverlayAddressSpace ospace = (OverlayAddressSpace) addressSpace;
addr = ospace.getOverlayAddress(addr);
}
return addr;
}
/** /**
* Gather all the flow records (perhaps across multiple InstructionPrototypes via crossbuilds) * Gather all the flow records (perhaps across multiple InstructionPrototypes via crossbuilds)
* and convert to Addresses * and convert to Addresses
@ -663,7 +653,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
VarnodeTpl vn = rec.op.getInput()[0]; VarnodeTpl vn = rec.op.getInput()[0];
AddressSpace spc = vn.getSpace().fixSpace(walker); AddressSpace spc = vn.getSpace().fixSpace(walker);
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
addr = handleOverlayAddress(context, addr);
SleighParserContext crosscontext = SleighParserContext crosscontext =
(SleighParserContext) context.getParserContext(addr); (SleighParserContext) context.getParserContext(addr);
int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal(); int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal();
@ -1555,13 +1544,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
return null; return null;
} }
Address newaddr = hand.space.getTruncatedAddress(hand.offset_offset, false); Address newaddr = hand.space.getTruncatedAddress(hand.offset_offset, false);
newaddr = newaddr.getPhysicalAddress();
// if we are in an address space, translate it
if (curSpace.isOverlaySpace()) {
newaddr = curSpace.getOverlayAddress(newaddr);
}
return newaddr; return newaddr;
} }

View file

@ -487,12 +487,6 @@ public class AddressXML {
*/ */
public static void encodeAttributes(Encoder encoder, Address addr) throws IOException { public static void encodeAttributes(Encoder encoder, Address addr) throws IOException {
AddressSpace space = addr.getAddressSpace(); AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
if (space.getType() != AddressSpace.TYPE_OTHER) {
space = space.getPhysicalSpace();
addr = space.getAddress(addr.getOffset());
}
}
encoder.writeSpace(ATTRIB_SPACE, space); encoder.writeSpace(ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset()); encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset());
} }
@ -508,12 +502,6 @@ public class AddressXML {
public static void encodeAttributes(Encoder encoder, Address addr, int size) public static void encodeAttributes(Encoder encoder, Address addr, int size)
throws IOException { throws IOException {
AddressSpace space = addr.getAddressSpace(); AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
if (space.getType() != AddressSpace.TYPE_OTHER) {
space = space.getPhysicalSpace();
addr = space.getAddress(addr.getOffset());
}
}
encoder.writeSpace(ATTRIB_SPACE, space); encoder.writeSpace(ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset()); encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset());

View file

@ -204,20 +204,6 @@ public class HighFunction extends PcodeSyntaxTree {
} }
} }
@Override
public Varnode newVarnode(int sz, Address addr) {
// translate into function overlay space if possible
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
return super.newVarnode(sz, addr);
}
@Override
public Varnode newVarnode(int sz, Address addr, int id) {
// translate into function overlay space if possible
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
return super.newVarnode(sz, addr, id);
}
private void decodeHigh(Decoder decoder) throws DecoderException { private void decodeHigh(Decoder decoder) throws DecoderException {
int el = decoder.openElement(ELEM_HIGH); int el = decoder.openElement(ELEM_HIGH);
String classstring = decoder.readString(ATTRIB_CLASS); String classstring = decoder.readString(ATTRIB_CLASS);
@ -267,7 +253,6 @@ public class HighFunction extends PcodeSyntaxTree {
} }
if (subel == ELEM_ADDR.id()) { if (subel == ELEM_ADDR.id()) {
Address addr = AddressXML.decode(decoder); Address addr = AddressXML.decode(decoder);
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
if (!func.getEntryPoint().equals(addr)) { if (!func.getEntryPoint().equals(addr)) {
throw new DecoderException("Mismatched address in function tag"); throw new DecoderException("Mismatched address in function tag");
} }

View file

@ -148,8 +148,6 @@ public class HighParamID extends PcodeSyntaxTree {
} }
if (subel == ELEM_ADDR.id()) { if (subel == ELEM_ADDR.id()) {
functionaddress = AddressXML.decode(decoder); functionaddress = AddressXML.decode(decoder);
functionaddress =
func.getEntryPoint().getAddressSpace().getOverlayAddress(functionaddress);
if (!func.getEntryPoint().equals(functionaddress)) { if (!func.getEntryPoint().equals(functionaddress)) {
throw new DecoderException("Mismatched address in function tag"); throw new DecoderException("Mismatched address in function tag");
} }

View file

@ -22,7 +22,8 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import ghidra.program.database.symbol.CodeSymbol; import ghidra.program.database.symbol.CodeSymbol;
import ghidra.program.model.address.*; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -37,19 +38,6 @@ import ghidra.util.exception.InvalidInputException;
public class JumpTable { public class JumpTable {
/**
* Translate address into preferred memory space (JumpTable.preferredSpace)
* @param addr is the given Address
* @return preferred address or original addr
*/
private Address translateOverlayAddress(Address addr) {
if (addr != null && preferredSpace.isOverlaySpace()) {
OverlayAddressSpace overlaySpace = (OverlayAddressSpace) preferredSpace;
return overlaySpace.getOverlayAddress(addr);
}
return addr;
}
public class LoadTable { public class LoadTable {
Address addr; // Starting address of table Address addr; // Starting address of table
int size; // Size of a table entry in bytes int size; // Size of a table entry in bytes
@ -83,7 +71,7 @@ public class JumpTable {
int el = decoder.openElement(ELEM_LOADTABLE); int el = decoder.openElement(ELEM_LOADTABLE);
size = (int) decoder.readSignedInteger(ATTRIB_SIZE); size = (int) decoder.readSignedInteger(ATTRIB_SIZE);
num = (int) decoder.readSignedInteger(ATTRIB_NUM); num = (int) decoder.readSignedInteger(ATTRIB_NUM);
addr = translateOverlayAddress(AddressXML.decode(decoder)); addr = AddressXML.decode(decoder);
decoder.closeElement(el); decoder.closeElement(el);
} }
} }
@ -172,7 +160,7 @@ public class JumpTable {
ArrayList<Integer> lTable = new ArrayList<>(); ArrayList<Integer> lTable = new ArrayList<>();
ArrayList<LoadTable> ldTable = new ArrayList<>(); ArrayList<LoadTable> ldTable = new ArrayList<>();
Address switchAddr = translateOverlayAddress(AddressXML.decode(decoder)); Address switchAddr = AddressXML.decode(decoder);
for (;;) { for (;;) {
int subel = decoder.peekElement(); int subel = decoder.peekElement();
@ -181,8 +169,7 @@ public class JumpTable {
} }
if (subel == ELEM_DEST.id()) { if (subel == ELEM_DEST.id()) {
decoder.openElement(); decoder.openElement();
Address caseAddr = Address caseAddr = AddressXML.decodeFromAttributes(decoder);
translateOverlayAddress(AddressXML.decodeFromAttributes(decoder));
aTable.add(caseAddr); aTable.add(caseAddr);
decoder.rewindAttributes(); decoder.rewindAttributes();
for (;;) { for (;;) {

View file

@ -77,7 +77,7 @@ public class PackedDecode implements Decoder {
public static final int SPECIALSPACE_SPACEBASE = 4; public static final int SPECIALSPACE_SPACEBASE = 4;
private AddressFactory addrFactory; private AddressFactory addrFactory;
private AddressSpace[] spaces; protected AddressSpace[] spaces;
private LinkedByteBuffer inStream; private LinkedByteBuffer inStream;
private LinkedByteBuffer.Position startPos; private LinkedByteBuffer.Position startPos;
private LinkedByteBuffer.Position curPos; private LinkedByteBuffer.Position curPos;

View file

@ -0,0 +1,49 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.model.pcode;
import ghidra.program.model.address.*;
/**
* Alter address space decoding for a specific overlay space.
* Any decoded space that matches the overlayed space is replaced with the overlay itself.
* This causes addresses in the overlayed space to be converted into overlay addresses.
*/
public class PackedDecodeOverlay extends PackedDecode {
private OverlayAddressSpace overlay = null;
public PackedDecodeOverlay(AddressFactory addrFactory, OverlayAddressSpace spc)
throws AddressFormatException {
super(addrFactory);
setOverlay(spc);
}
public void setOverlay(OverlayAddressSpace spc) throws AddressFormatException {
AddressSpace underlie;
if (overlay != null) {
underlie = overlay.getOverlayedSpace();
spaces[underlie.getUnique()] = underlie;
overlay = null;
}
underlie = spc.getOverlayedSpace();
if (underlie.getUnique() == 0 || underlie.getUnique() >= spaces.length) {
throw new AddressFormatException("Cannot set overlay over " + underlie.getName());
}
spaces[underlie.getUnique()] = spc;
overlay = spc;
}
}

View file

@ -0,0 +1,62 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.model.pcode;
import java.io.IOException;
import ghidra.program.model.address.*;
/**
* Alter address space encoding for a specific overlay space.
* Any space that matches the overlay space is encoded as the overlayed space.
* This causes addresses in the overlay space to be converted into the underlying space.
*/
public class PackedEncodeOverlay extends PackedEncode {
private OverlayAddressSpace overlay = null;
private int overlayId; // Id of the overlay space
private int underlyingId; // If of the space underlying the overlay
public PackedEncodeOverlay(OverlayAddressSpace spc) throws AddressFormatException {
super();
setOverlay(spc);
}
public void setOverlay(OverlayAddressSpace spc) throws AddressFormatException {
overlayId = spc.getUnique();
AddressSpace underlie = spc.getOverlayedSpace();
underlyingId = underlie.getUnique();
if (underlyingId == 0) {
throw new AddressFormatException("Cannot set overlay over " + underlie.getName());
}
overlay = spc;
}
@Override
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
if (spc == overlay) {
spc = overlay.getOverlayedSpace();
}
super.writeSpace(attribId, spc);
}
@Override
public void writeSpaceId(AttributeId attribId, long spaceId) {
if (spaceId == overlayId) {
spaceId = underlyingId;
}
super.writeSpaceId(attribId, spaceId);
}
}

View file

@ -93,10 +93,6 @@ public abstract class SymbolEntry {
AddressSpace spc = decoder.readSpace(ATTRIB_SPACE); AddressSpace spc = decoder.readSpace(ATTRIB_SPACE);
long offset = decoder.readUnsignedInteger(ATTRIB_FIRST); long offset = decoder.readUnsignedInteger(ATTRIB_FIRST);
pcaddr = spc.getAddress(offset); pcaddr = spc.getAddress(offset);
pcaddr = symbol.function.getFunction()
.getEntryPoint()
.getAddressSpace()
.getOverlayAddress(pcaddr);
decoder.closeElement(rangeel); decoder.closeElement(rangeel);
} }
@ -110,14 +106,7 @@ public abstract class SymbolEntry {
return; return;
} }
AddressSpace space = pcaddr.getAddressSpace(); AddressSpace space = pcaddr.getAddressSpace();
long off; long off = pcaddr.getUnsignedOffset();
if (space.isOverlaySpace()) {
space = space.getPhysicalSpace();
off = space.getAddress(pcaddr.getOffset()).getUnsignedOffset();
}
else {
off = pcaddr.getUnsignedOffset();
}
encoder.openElement(ELEM_RANGE); encoder.openElement(ELEM_RANGE);
encoder.writeSpace(ATTRIB_SPACE, space); encoder.writeSpace(ATTRIB_SPACE, space);
encoder.writeUnsignedInteger(ATTRIB_FIRST, off); encoder.writeUnsignedInteger(ATTRIB_FIRST, off);

View file

@ -337,10 +337,6 @@ public class Varnode {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
Address addr = address; Address addr = address;
AddressSpace space = addr.getAddressSpace(); AddressSpace space = addr.getAddressSpace();
if (space.isOverlaySpace()) {
space = space.getPhysicalSpace();
addr = space.getAddress(addr.getOffset());
}
buffer.append(space.getName()); buffer.append(space.getName());
buffer.append(":0x"); buffer.append(":0x");
long off = addr.getUnsignedOffset(); long off = addr.getUnsignedOffset();