mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-1818 Refactor decompiler overlay translations
This commit is contained in:
parent
6911befabb
commit
8b5ec1b439
21 changed files with 259 additions and 279 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (;;) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue