diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangFuncNameToken.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangFuncNameToken.java index bb6c1dd6cc..a067029c3f 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangFuncNameToken.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangFuncNameToken.java @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * 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; import ghidra.program.model.address.Address; @@ -54,7 +48,7 @@ public class ClangFuncNameToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override @@ -62,7 +56,7 @@ public class ClangFuncNameToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangOpToken.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangOpToken.java index 6c0f9d8e0d..43d17ab0d4 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangOpToken.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangOpToken.java @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * 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; import ghidra.program.model.address.Address; @@ -49,7 +43,7 @@ public class ClangOpToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override @@ -57,7 +51,7 @@ public class ClangOpToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangVariableToken.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangVariableToken.java index 3f96d65d5c..1025083088 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangVariableToken.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/ClangVariableToken.java @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * 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; import ghidra.program.model.address.Address; @@ -59,7 +53,7 @@ public class ClangVariableToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override @@ -67,7 +61,7 @@ public class ClangVariableToken extends ClangToken { if (op == null) { return null; } - return op.getSeqnum().getTarget().getPhysicalAddress(); + return op.getSeqnum().getTarget(); } @Override diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java index d8f01cdea2..6755c6c9c2 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompInterface.java @@ -26,7 +26,7 @@ import java.io.*; import generic.jar.ResourceFile; import ghidra.app.plugin.processors.sleigh.SleighLanguage; 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.listing.Function; import ghidra.program.model.listing.Program; @@ -78,6 +78,51 @@ import ghidra.util.task.TaskMonitor; */ 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; private SleighLanguage pcodelanguage; private PcodeDataTypeManager dtmanage; @@ -87,8 +132,8 @@ public class DecompInterface { protected CompilerSpec compilerSpec; protected DecompileProcess decompProcess; protected DecompileCallback decompCallback; - protected PackedEncode paramEncode; // Encoder for decompiler command parameters - protected Decoder decoder; // Decoder for the Decompiler's main outputs + protected EncodeDecodeSet baseEncodingSet; // Encoders/decoders for functions not in overlay + protected EncodeDecodeSet overlayEncodingSet; // Encoders/decoders for functions in overlays protected StringIngest stringResponse = new StringIngest(); // Ingester for simple responses private DecompileDebug debug; protected CancelledListener monitorListener = new CancelledListener() { @@ -112,8 +157,8 @@ public class DecompInterface { dtmanage = null; decompCallback = null; options = null; - paramEncode = null; - decoder = null; + baseEncodingSet = null; + overlayEncodingSet = null; debug = null; decompileMessage = ""; compilerSpec = null; @@ -239,10 +284,11 @@ public class DecompInterface { throw new IOException("Could not register program: " + nativeMessage); } if (options != null) { - paramEncode.clear(); - options.encode(paramEncode, this); + baseEncodingSet.mainQuery.clear(); + options.encode(baseEncodingSet.mainQuery, this); decompProcess.setMaxResultSize(options.getMaxPayloadMBytes()); - decompProcess.sendCommand1Param("setOptions", paramEncode, stringResponse); + decompProcess.sendCommand1Param("setOptions", baseEncodingSet.mainQuery, + stringResponse); if (!stringResponse.toString().equals("t")) { throw new IOException("Did not accept decompiler options"); } @@ -323,8 +369,7 @@ public class DecompInterface { compilerSpec = spec; dtmanage = new PcodeDataTypeManager(prog); - paramEncode = new PackedEncode(); - decoder = new PackedDecode(prog.getAddressFactory()); + baseEncodingSet = new EncodeDecodeSet(prog); try { decompCallback = new DecompileCallback(prog, pcodelanguage, program.getCompilerSpec(), dtmanage); @@ -346,8 +391,7 @@ public class DecompInterface { } program = null; decompCallback = null; - paramEncode = null; - decoder = null; + baseEncodingSet = null; return false; } @@ -363,8 +407,8 @@ public class DecompInterface { if (program != null) { program = null; decompCallback = null; - paramEncode = null; - decoder = null; + baseEncodingSet = null; + overlayEncodingSet = null; try { if ((decompProcess != null) && decompProcess.isReady()) { decompProcess.deregisterProgram(); @@ -604,10 +648,11 @@ public class DecompInterface { } try { verifyProcess(); - paramEncode.clear(); - options.encode(paramEncode, this); + baseEncodingSet.mainQuery.clear(); + options.encode(baseEncodingSet.mainQuery, this); decompProcess.setMaxResultSize(options.getMaxPayloadMBytes()); - decompProcess.sendCommand1Param("setOptions", paramEncode, stringResponse); + decompProcess.sendCommand1Param("setOptions", baseEncodingSet.mainQuery, + stringResponse); return stringResponse.toString().equals("t"); } catch (IOException e) { @@ -668,15 +713,15 @@ public class DecompInterface { } BlockGraph resgraph = null; try { + setupEncodeDecode(Address.NO_ADDRESS); verifyProcess(); - paramEncode.clear(); - ingraph.encode(paramEncode); - decompProcess.sendCommand1ParamTimeout("structureGraph", paramEncode, timeoutSecs, - decoder); + baseEncodingSet.mainQuery.clear(); + ingraph.encode(baseEncodingSet.mainQuery); + decompProcess.sendCommandTimeout("structureGraph", timeoutSecs, baseEncodingSet); decompileMessage = decompCallback.getNativeMessage(); - if (!decoder.isEmpty()) { + if (!baseEncodingSet.mainResponse.isEmpty()) { resgraph = new BlockGraph(); - resgraph.decode(decoder); + resgraph.decode(baseEncodingSet.mainResponse); resgraph.transferObjectRef(ingraph); } } @@ -716,17 +761,19 @@ public class DecompInterface { DecompileProcess.DisposeState.DISPOSED_ON_CANCEL); } + Decoder decoder = null; try { Address funcEntry = func.getEntryPoint(); if (debug != null) { debug.setFunction(func); } decompCallback.setFunction(func, funcEntry, debug); + EncodeDecodeSet activeSet = setupEncodeDecode(funcEntry); + decoder = activeSet.mainResponse; verifyProcess(); - paramEncode.clear(); - AddressXML.encode(paramEncode, funcEntry); - decompProcess.sendCommand1ParamTimeout("decompileAt", paramEncode, timeoutSecs, - decoder); + activeSet.mainQuery.clear(); + AddressXML.encode(activeSet.mainQuery, funcEntry); + decompProcess.sendCommandTimeout("decompileAt", timeoutSecs, activeSet); decompileMessage = decompCallback.getNativeMessage(); if (debug != null) { XmlEncode xmlEncode = new XmlEncode(); @@ -806,4 +853,28 @@ public class DecompInterface { public CompilerSpec getCompilerSpec() { 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; + + } } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java index 4d8e2edcc3..adde9960ed 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java @@ -63,7 +63,6 @@ public class DecompileCallback { private Function cachedFunction; private AddressSet undefinedBody; private Address funcEntry; - private AddressSpace overlaySpace; // non-null if function being decompiled is in an overlay private int default_extrapop; private Language pcodelanguage; private CompilerSpec pcodecompilerspec; @@ -105,8 +104,6 @@ public class DecompileCallback { undefinedBody = new AddressSet(func.getBody()); } funcEntry = entry; - AddressSpace spc = funcEntry.getAddressSpace(); - overlaySpace = spc.isOverlaySpace() ? spc : null; debug = dbg; if (debug != null) { 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 */ public byte[] getBytes(Address addr, int size) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } if (addr == Address.NO_ADDRESS) { Msg.error(this, "Address does not physically map"); return null; @@ -186,9 +180,6 @@ public class DecompileCallback { * @throws IOException for errors in the underlying stream */ public void getComments(Address addr, int types, Encoder resultEncoder) throws IOException { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } Function func = getFunctionAt(addr); if (func == null) { return; @@ -207,9 +198,6 @@ public class DecompileCallback { * @param resultEncoder will contain the generated p-code ops */ public void getPcode(Address addr, PackedEncode resultEncoder) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } try { Instruction instr = getInstruction(addr); if (instr == null) { @@ -437,9 +425,6 @@ public class DecompileCallback { * @return the symbol or null if no symbol is found */ public String getCodeLabel(Address addr) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } try { Symbol sym = program.getSymbolTable().getPrimarySymbol(addr); if (sym == null) { @@ -669,9 +654,6 @@ public class DecompileCallback { * @param resultEncoder is where to write encoded description */ public void getMappedSymbols(Address addr, Encoder resultEncoder) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } if (addr == Address.NO_ADDRESS) { // Unknown spaces may result from "spacebase" registers defined in cspec return; @@ -712,9 +694,6 @@ public class DecompileCallback { * @param resultEncoder will contain the resulting description */ public void getExternalRef(Address addr, Encoder resultEncoder) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } try { Function func = null; 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 */ public void getTrackedRegisters(Address addr, Encoder resultEncoder) throws IOException { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } ProgramContext context = program.getProgramContext(); encodeTrackedPointSet(resultEncoder, addr, context); @@ -1012,14 +988,14 @@ public class DecompileCallback { Address first = range.getMinAddress(); Address last = range.getMaxAddress(); boolean readonly = true; // Treat function body as readonly - encodeHole(encoder, first.getAddressSpace().getPhysicalSpace(), - first.getUnsignedOffset(), last.getUnsignedOffset(), readonly, false); + encodeHole(encoder, first.getAddressSpace(), first.getUnsignedOffset(), + last.getUnsignedOffset(), readonly, false); return; } } // There is probably some sort of error, just return a block // containing the single queried address - encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(), + encodeHole(encoder, addr.getAddressSpace(), addr.getUnsignedOffset(), addr.getUnsignedOffset(), true, false); } @@ -1084,7 +1060,7 @@ public class DecompileCallback { private void encodeHole(Encoder encoder, Address addr) throws IOException { boolean readonly = isReadOnlyNoData(addr); boolean isvolatile = isVolatileNoData(addr); - encodeHole(encoder, addr.getAddressSpace().getPhysicalSpace(), addr.getUnsignedOffset(), + encodeHole(encoder, addr.getAddressSpace(), addr.getUnsignedOffset(), addr.getUnsignedOffset(), readonly, isvolatile); } @@ -1242,9 +1218,6 @@ public class DecompileCallback { * @return the UTF8 encoded byte array or null */ public StringData getStringData(Address addr, int maxChars, String dtName, long dtId) { - if (overlaySpace != null) { - addr = overlaySpace.getOverlayAddress(addr); - } if (addr == Address.NO_ADDRESS) { Msg.error(this, "Address does not physically map"); return null; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileDebug.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileDebug.java index d1a10f0eda..71e423c3bf 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileDebug.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileDebug.java @@ -235,8 +235,7 @@ public class DecompileDebug { } if (!tagstarted) { buf.append(" tokens = - DecompilerUtils.getTokensFromView(layoutMgr.getFields(), translated); + List tokens = DecompilerUtils.getTokensFromView(layoutMgr.getFields(), address); goToBeginningOfLine(tokens); } @@ -611,65 +609,13 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field 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) { FieldSelection fieldSelection = null; if (selection == null || selection.isEmpty()) { fieldSelection = new FieldSelection(); } else { - List tokens = - DecompilerUtils.getTokens(layoutMgr.getRoot(), translateSet(selection)); + List tokens = DecompilerUtils.getTokens(layoutMgr.getRoot(), selection); fieldSelection = DecompilerUtils.getFieldSelection(tokens); } fieldPanel.setSelection(fieldSelection); @@ -975,9 +921,6 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field address = decompileData.getFunction().getEntryPoint(); } - // adjust in case function is in an overlay space. - address = decompileData.getFunctionSpace().getOverlayAddress(address); - return new DecompilerLocation(decompileData.getProgram(), address, decompileData.getFunction().getEntryPoint(), decompileData.getDecompileResults(), token, location.getIndex().intValue(), location.col); diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java index 5e660232b5..59ddfc767c 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerUtils.java @@ -382,8 +382,6 @@ public class DecompilerUtils { Address minAddress = token.getMinAddress(); Address maxAddress = token.getMaxAddress(); maxAddress = maxAddress == null ? minAddress : maxAddress; - minAddress = space.getOverlayAddress(minAddress); - maxAddress = space.getOverlayAddress(maxAddress); addrs.addRange(minAddress, maxAddress); } @@ -602,8 +600,8 @@ public class DecompilerUtils { return brace; } - private static ClangSyntaxToken moveToNextBrace(ClangToken startToken, - List list, String targetBrace, boolean forward) { + private static ClangSyntaxToken moveToNextBrace(ClangToken startToken, List list, + String targetBrace, boolean forward) { int balance = 0; int index = list.indexOf(startToken); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java index 05768583f9..3e546ea7df 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * Created on Feb 4, 2005 - * - */ package ghidra.app.plugin.processors.sleigh; import java.io.IOException; @@ -63,7 +59,6 @@ public abstract class PcodeEmit { private AddressSpace uniq_space; private long uniquemask; private long uniqueoffset; - private AddressSpace overlayspace = null; /** * Pcode emitter constructor for empty or unimiplemented instructions @@ -85,12 +80,6 @@ public abstract class PcodeEmit { this.instcontext = ictx; this.const_space = walk.getConstSpace(); this.startAddress = parsercontext.getAddr(); - AddressSpace myspace = startAddress.getAddressSpace(); - if (myspace.isOverlaySpace()) { - overlayspace = myspace; - startAddress = ((OverlayAddressSpace) myspace).getOverlayedSpace() - .getAddress(startAddress.getOffset()); - } this.fallOffset = fallOffset; this.override = override; SleighInstructionPrototype sleighproto = parsercontext.getPrototype(); @@ -202,7 +191,7 @@ public abstract class PcodeEmit { } VarnodeData dest = new VarnodeData(); - dest.space = fallOverride.getAddressSpace().getPhysicalSpace(); + dest.space = fallOverride.getAddressSpace(); dest.offset = fallOverride.getOffset(); dest.size = dest.space.getPointerSize(); @@ -675,9 +664,6 @@ public abstract class PcodeEmit { AddressSpace spc = vn.getSpace().fixSpace(walker); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); // translate the address into the overlayspace if we have an overlayspace. - if (overlayspace != null) { - addr = overlayspace.getOverlayAddress(addr); - } ParserWalker oldwalker = walker; long olduniqueoffset = uniqueoffset; 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 * @param opcode opcode of instruction diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmitPacked.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmitPacked.java index 69285b65dd..5bb47adf20 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmitPacked.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmitPacked.java @@ -125,7 +125,6 @@ public class PcodeEmitPacked extends PcodeEmit { void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out) throws IOException { opcode = checkOverrides(opcode, in); - checkOverlays(opcode, in, isize, out); encoder.openElement(ELEM_OP); encoder.writeSignedInteger(ATTRIB_CODE, opcode); encoder.writeSignedInteger(ATTRIB_SIZE, isize); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighInstructionPrototype.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighInstructionPrototype.java index c567c1fa42..fe7215e1c7 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighInstructionPrototype.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighInstructionPrototype.java @@ -606,7 +606,6 @@ public class SleighInstructionPrototype implements InstructionPrototype { VarnodeTpl vn = rec.op.getInput()[0]; AddressSpace spc = vn.getSpace().fixSpace(walker); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); - addr = handleOverlayAddress(context, addr); SleighParserContext crosscontext = (SleighParserContext) context.getParserContext(addr); int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal(); @@ -621,15 +620,6 @@ public class SleighInstructionPrototype implements InstructionPrototype { 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) * and convert to Addresses @@ -663,7 +653,6 @@ public class SleighInstructionPrototype implements InstructionPrototype { VarnodeTpl vn = rec.op.getInput()[0]; AddressSpace spc = vn.getSpace().fixSpace(walker); Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false); - addr = handleOverlayAddress(context, addr); SleighParserContext crosscontext = (SleighParserContext) context.getParserContext(addr); int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal(); @@ -1555,13 +1544,6 @@ public class SleighInstructionPrototype implements InstructionPrototype { return null; } 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; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/AddressXML.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/AddressXML.java index c7a281fa66..16c87dfeaf 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/AddressXML.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/AddressXML.java @@ -487,12 +487,6 @@ public class AddressXML { */ public static void encodeAttributes(Encoder encoder, Address addr) throws IOException { 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.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset()); } @@ -508,12 +502,6 @@ public class AddressXML { public static void encodeAttributes(Encoder encoder, Address addr, int size) throws IOException { 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.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset()); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java index 01761918e6..cbec3a1adf 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighFunction.java @@ -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 { int el = decoder.openElement(ELEM_HIGH); String classstring = decoder.readString(ATTRIB_CLASS); @@ -267,7 +253,6 @@ public class HighFunction extends PcodeSyntaxTree { } if (subel == ELEM_ADDR.id()) { Address addr = AddressXML.decode(decoder); - addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr); if (!func.getEntryPoint().equals(addr)) { throw new DecoderException("Mismatched address in function tag"); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighParamID.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighParamID.java index dd36547f98..31e70b70fc 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighParamID.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighParamID.java @@ -148,8 +148,6 @@ public class HighParamID extends PcodeSyntaxTree { } if (subel == ELEM_ADDR.id()) { functionaddress = AddressXML.decode(decoder); - functionaddress = - func.getEntryPoint().getAddressSpace().getOverlayAddress(functionaddress); if (!func.getEntryPoint().equals(functionaddress)) { throw new DecoderException("Mismatched address in function tag"); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/JumpTable.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/JumpTable.java index 61da926947..ba8872ed2d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/JumpTable.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/JumpTable.java @@ -22,7 +22,8 @@ import java.io.IOException; import java.util.ArrayList; 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.Program; import ghidra.program.model.symbol.*; @@ -37,19 +38,6 @@ import ghidra.util.exception.InvalidInputException; 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 { Address addr; // Starting address of table int size; // Size of a table entry in bytes @@ -83,7 +71,7 @@ public class JumpTable { int el = decoder.openElement(ELEM_LOADTABLE); size = (int) decoder.readSignedInteger(ATTRIB_SIZE); num = (int) decoder.readSignedInteger(ATTRIB_NUM); - addr = translateOverlayAddress(AddressXML.decode(decoder)); + addr = AddressXML.decode(decoder); decoder.closeElement(el); } } @@ -172,7 +160,7 @@ public class JumpTable { ArrayList lTable = new ArrayList<>(); ArrayList ldTable = new ArrayList<>(); - Address switchAddr = translateOverlayAddress(AddressXML.decode(decoder)); + Address switchAddr = AddressXML.decode(decoder); for (;;) { int subel = decoder.peekElement(); @@ -181,8 +169,7 @@ public class JumpTable { } if (subel == ELEM_DEST.id()) { decoder.openElement(); - Address caseAddr = - translateOverlayAddress(AddressXML.decodeFromAttributes(decoder)); + Address caseAddr = AddressXML.decodeFromAttributes(decoder); aTable.add(caseAddr); decoder.rewindAttributes(); for (;;) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecode.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecode.java index 4041a458be..4937330643 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecode.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecode.java @@ -77,7 +77,7 @@ public class PackedDecode implements Decoder { public static final int SPECIALSPACE_SPACEBASE = 4; private AddressFactory addrFactory; - private AddressSpace[] spaces; + protected AddressSpace[] spaces; private LinkedByteBuffer inStream; private LinkedByteBuffer.Position startPos; private LinkedByteBuffer.Position curPos; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecodeOverlay.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecodeOverlay.java new file mode 100644 index 0000000000..07af085ead --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedDecodeOverlay.java @@ -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; + } +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedEncodeOverlay.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedEncodeOverlay.java new file mode 100644 index 0000000000..f8f4afef37 --- /dev/null +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PackedEncodeOverlay.java @@ -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); + } +} diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/SymbolEntry.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/SymbolEntry.java index bfd9a2b4a2..dfa050263d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/SymbolEntry.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/SymbolEntry.java @@ -93,10 +93,6 @@ public abstract class SymbolEntry { AddressSpace spc = decoder.readSpace(ATTRIB_SPACE); long offset = decoder.readUnsignedInteger(ATTRIB_FIRST); pcaddr = spc.getAddress(offset); - pcaddr = symbol.function.getFunction() - .getEntryPoint() - .getAddressSpace() - .getOverlayAddress(pcaddr); decoder.closeElement(rangeel); } @@ -110,14 +106,7 @@ public abstract class SymbolEntry { return; } AddressSpace space = pcaddr.getAddressSpace(); - long off; - if (space.isOverlaySpace()) { - space = space.getPhysicalSpace(); - off = space.getAddress(pcaddr.getOffset()).getUnsignedOffset(); - } - else { - off = pcaddr.getUnsignedOffset(); - } + long off = pcaddr.getUnsignedOffset(); encoder.openElement(ELEM_RANGE); encoder.writeSpace(ATTRIB_SPACE, space); encoder.writeUnsignedInteger(ATTRIB_FIRST, off); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java index 66875e29e7..680ef28c86 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java @@ -337,10 +337,6 @@ public class Varnode { StringBuilder buffer = new StringBuilder(); Address addr = address; AddressSpace space = addr.getAddressSpace(); - if (space.isOverlaySpace()) { - space = space.getPhysicalSpace(); - addr = space.getAddress(addr.getOffset()); - } buffer.append(space.getName()); buffer.append(":0x"); long off = addr.getUnsignedOffset();