diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/InstructionAdapterFromPrototype.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/InstructionAdapterFromPrototype.java index fefe4567ef..93c234b5aa 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/InstructionAdapterFromPrototype.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/InstructionAdapterFromPrototype.java @@ -18,7 +18,6 @@ package ghidra.trace.util; import java.util.List; import ghidra.program.model.address.Address; -import ghidra.program.model.address.UniqueAddressFactory; import ghidra.program.model.lang.*; import ghidra.program.model.listing.Instruction; import ghidra.program.model.listing.InstructionPcodeOverride; @@ -137,13 +136,8 @@ public interface InstructionAdapterFromPrototype extends Instruction { @Override default RefType getOperandRefType(int opIndex) { InstructionPrototype prototype = getPrototype(); - Language language = prototype.getLanguage(); InstructionPcodeOverride override = new InstructionPcodeOverride(this); - // TODO: addressFactory may need to be from program/trace (so it has cSpec) - UniqueAddressFactory uniqueFactory = - new UniqueAddressFactory(language.getAddressFactory(), language); - return prototype.getOperandRefType(opIndex, getInstructionContext(), override, - uniqueFactory); + return prototype.getOperandRefType(opIndex, getInstructionContext(), override); } @Override @@ -159,14 +153,11 @@ public interface InstructionAdapterFromPrototype extends Instruction { @Override default PcodeOp[] getPcode(boolean includeOverrides) { if (!includeOverrides) { - return getPrototype().getPcode(getInstructionContext(), null, null); + return getPrototype().getPcode(getInstructionContext(), null); } InstructionPrototype prototype = getPrototype(); - Language language = prototype.getLanguage(); InstructionPcodeOverride override = new InstructionPcodeOverride(this); - UniqueAddressFactory uniqueFactory = - new UniqueAddressFactory(language.getAddressFactory(), language); - return prototype.getPcode(getInstructionContext(), override, uniqueFactory); + return prototype.getPcode(getInstructionContext(), override); } /** diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java index bfc57a0610..3677257275 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java @@ -18,54 +18,27 @@ package ghidra.pcode.exec; import java.util.*; import org.apache.commons.lang3.StringUtils; -import org.jdom.JDOMException; -import org.xml.sax.*; import ghidra.app.plugin.processors.sleigh.*; import ghidra.app.plugin.processors.sleigh.template.ConstructTpl; -import ghidra.pcodeCPort.slgh_compile.PcodeParser; import ghidra.pcodeCPort.slghsymbol.UserOpSymbol; import ghidra.program.model.address.Address; -import ghidra.program.model.lang.Language; -import ghidra.program.model.lang.UnknownInstructionException; +import ghidra.program.model.lang.*; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.pcode.PcodeOp; -import ghidra.util.Msg; -import ghidra.xml.XmlPullParser; -import ghidra.xml.XmlPullParserFactory; public class SleighProgramCompiler { private static final String EXPRESSION_SOURCE_NAME = "expression"; public static PcodeParser createParser(SleighLanguage language) { - String translatorTag = - language.buildTranslatorTag(language.getAddressFactory(), language.getUniqueBase(), - language.getSymbolTable()); - try { - return new PcodeParser(translatorTag); - } - catch (JDOMException e) { - throw new AssertionError(e); - } + return new PcodeParser(language, UniqueLayout.INJECT.getOffset(language)); } public static ConstructTpl compileTemplate(Language language, PcodeParser parser, String sourceName, String text) { - try { - // This is quite the conversion, no? - String templateXml = - PcodeParser.stringifyTemplate( - Objects.requireNonNull(parser.compilePcode(text, EXPRESSION_SOURCE_NAME, 1))); - MyErrorHandler eh = new MyErrorHandler(); - XmlPullParser xmlParser = - XmlPullParserFactory.create(templateXml, EXPRESSION_SOURCE_NAME, eh, false); - ConstructTpl template = new ConstructTpl(); - template.restoreXml(xmlParser, language.getAddressFactory()); - return template; - } - catch (SAXException | UnknownInstructionException e) { - throw new AssertionError(e); - } + ConstructTpl template = + Objects.requireNonNull(parser.compilePcode(text, EXPRESSION_SOURCE_NAME, 1)); + return template; } public static List buildOps(Language language, ConstructTpl template) @@ -125,23 +98,4 @@ public class SleighProgramCompiler { throw new AssertionError(e); } } - - static class MyErrorHandler implements ErrorHandler { - SAXParseException exc; - - @Override - public void warning(SAXParseException e) throws SAXException { - Msg.warn(this, e); - } - - @Override - public void error(SAXParseException e) throws SAXException { - exc = e; - } - - @Override - public void fatalError(SAXParseException e) throws SAXException { - exc = e; - } - } } diff --git a/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java b/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java index ca0f979b8f..633b446c2f 100644 --- a/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java +++ b/Ghidra/Features/Base/ghidra_scripts/ResolveX86orX64LinuxSyscallsScript.java @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + //Uses overriding references and the symbolic propogator to resolve system calls //@category Analysis + import java.io.*; import java.util.*; import java.util.Map.Entry; @@ -31,8 +33,8 @@ import ghidra.app.util.opinion.ElfLoader; import ghidra.framework.Application; import ghidra.program.model.address.*; import ghidra.program.model.data.DataTypeManager; -import ghidra.program.model.lang.BasicCompilerSpec; import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.SpaceNames; import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.pcode.PcodeOp; @@ -127,8 +129,9 @@ public class ResolveX86orX64LinuxSyscallsScript extends GhidraScript { " to run this script"); return; } - Address startAddr = currentProgram.getAddressFactory().getAddressSpace( - BasicCompilerSpec.OTHER_SPACE_NAME).getAddress(0x0L); + Address startAddr = currentProgram.getAddressFactory() + .getAddressSpace(SpaceNames.OTHER_SPACE_NAME) + .getAddress(0x0L); AddUninitializedMemoryBlockCmd cmd = new AddUninitializedMemoryBlockCmd( SYSCALL_SPACE_NAME, null, this.getClass().getName(), startAddr, SYSCALL_SPACE_LENGTH, true, true, true, false, true); @@ -188,8 +191,9 @@ public class ResolveX86orX64LinuxSyscallsScript extends GhidraScript { callee.setNoReturn(true); } } - Reference ref = currentProgram.getReferenceManager().addMemoryReference(callSite, - callTarget, overrideType, SourceType.USER_DEFINED, Reference.MNEMONIC); + Reference ref = currentProgram.getReferenceManager() + .addMemoryReference(callSite, callTarget, overrideType, SourceType.USER_DEFINED, + Reference.MNEMONIC); //overriding references must be primary to be active currentProgram.getReferenceManager().setPrimary(ref, true); } @@ -320,8 +324,10 @@ public class ResolveX86orX64LinuxSyscallsScript extends GhidraScript { for (PcodeOp op : inst.getPcode()) { if (op.getOpcode() == PcodeOp.CALLOTHER) { int index = (int) op.getInput(0).getOffset(); - if (inst.getProgram().getLanguage().getUserDefinedOpName(index).equals( - SYSCALL_X64_CALLOTHER)) { + if (inst.getProgram() + .getLanguage() + .getUserDefinedOpName(index) + .equals(SYSCALL_X64_CALLOTHER)) { retVal = true; } } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc index 49bc6fd49e..8392b9b360 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc @@ -644,9 +644,9 @@ void Architecture::restoreFromSpec(DocumentStorage &store) translate = newtrans; modifySpaces(newtrans); // Give architecture chance to modify spaces, before copying copySpaces(newtrans); - insertSpace( new FspecSpace(this,translate,"fspec",numSpaces())); - insertSpace( new IopSpace(this,translate,"iop",numSpaces())); - insertSpace( new JoinSpace(this,translate,"join",numSpaces())); + insertSpace( new FspecSpace(this,translate,numSpaces())); + insertSpace( new IopSpace(this,translate,numSpaces())); + insertSpace( new JoinSpace(this,translate,numSpaces())); userops.initialize(this); if (translate->getAlignment() <= 8) min_funcsymbol_size = translate->getAlignment(); @@ -843,7 +843,7 @@ void Architecture::addOtherSpace(void) { Scope *scope = symboltab->getGlobalScope(); - AddrSpace *otherSpace = getSpaceByName("OTHER"); + AddrSpace *otherSpace = getSpaceByName(OtherSpace::NAME); symboltab->addRange(scope,otherSpace,0,otherSpace->getHighest()); if (otherSpace->isOverlayBase()) { int4 num = numSpaces(); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc index a59ad6f651..5756f1e590 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.cc @@ -1702,16 +1702,17 @@ int4 ParamActive::getNumUsed(void) const return count; } +const string FspecSpace::NAME = "fspec"; + /// Constructor for the \b fspec space. /// There is only one such space, and it is considered /// internal to the model, i.e. the Translate engine should never /// generate addresses in this space. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name of the space (always \b fspec) /// \param ind is the index associated with the space -FspecSpace::FspecSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind) - : AddrSpace(m,t,IPTR_FSPEC,nm,sizeof(void *),1,ind,0,1) +FspecSpace::FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind) + : AddrSpace(m,t,IPTR_FSPEC,NAME,sizeof(void *),1,ind,0,1) { clearFlags(heritaged|does_deadcode|big_endian); if (HOST_ENDIAN==1) // Endianness always set by host diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh index 64ea8e62ec..a44d9f07c9 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh @@ -286,12 +286,13 @@ public: /// value of the pointer class FspecSpace : public AddrSpace { public: - FspecSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); ///< Constructor + FspecSpace(AddrSpaceManager *m,const Translate *t,int4 ind); ///< Constructor virtual void saveXmlAttributes(ostream &s,uintb offset) const; virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const; virtual void printRaw(ostream &s,uintb offset) const; virtual void saveXml(ostream &s) const; virtual void restoreXml(const Element *el); + static const string NAME; ///< Reserved name for the fspec space }; /// \brief Basic elements of a parameter: address, data-type, properties diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index f645fc7295..e5c361eaff 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -24,9 +24,7 @@ Funcdata::Funcdata(const string &nm,Scope *scope,const Address &addr,FunctionSymbol *sym,int4 sz) : baseaddr(addr), funcp(), - vbank(scope->getArch(), - scope->getArch()->getUniqueSpace(), - 0x10000000), // Unique space which is reused per function starts here + vbank(scope->getArch()), heritage(this), covermerge(*this) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc index b72d089d2a..e4e34b029b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc @@ -278,8 +278,8 @@ void InjectPayloadDynamic::inject(InjectContext &context,PcodeEmit &emit) const emit.restoreXmlOp(*iter,glb->translate); } -PcodeInjectLibrarySleigh::PcodeInjectLibrarySleigh(Architecture *g,uintb tmpbase) - : PcodeInjectLibrary(g,tmpbase) +PcodeInjectLibrarySleigh::PcodeInjectLibrarySleigh(Architecture *g) + : PcodeInjectLibrary(g,g->translate->getUniqueStart(Translate::INJECT)) { slgh = (const SleighBase *)g->translate; contextCache.glb = g; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh index 600215c658..7d8776c125 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh @@ -97,7 +97,7 @@ protected: virtual int4 allocateInject(const string &sourceName,const string &name,int4 type); virtual void registerInject(int4 injectid); public: - PcodeInjectLibrarySleigh(Architecture *g,uintb tmpbase); + PcodeInjectLibrarySleigh(Architecture *g); virtual void restoreDebug(const Element *el); virtual int4 manualCallFixup(const string &name,const string &snippetstring); virtual int4 manualCallOtherFixup(const string &name,const string &outname,const vector &inname, diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc index af89c583ac..ba74450c6e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.cc @@ -16,16 +16,17 @@ #include "op.hh" #include "funcdata.hh" +const string IopSpace::NAME = "iop"; + /// Constructor for the \b iop space. /// There is only one such space, and it is considered internal /// to the model, i.e. the Translate engine should never generate /// addresses in this space. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name of the space (always \b iop) /// \param ind is the associated index -IopSpace::IopSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind) - : AddrSpace(m,t,IPTR_IOP,nm,sizeof(void *),1,ind,0,1) +IopSpace::IopSpace(AddrSpaceManager *m,const Translate *t,int4 ind) + : AddrSpace(m,t,IPTR_IOP,NAME,sizeof(void *),1,ind,0,1) { clearFlags(heritaged|does_deadcode|big_endian); if (HOST_ENDIAN==1) // Endianness always set to host diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh index 9d65f96397..57bb99b411 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/op.hh @@ -31,12 +31,13 @@ /// within the \b fspec space. class IopSpace : public AddrSpace { public: - IopSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); + IopSpace(AddrSpaceManager *m,const Translate *t,int4 ind); virtual void saveXmlAttributes(ostream &s,uintb offset) const { s << " space=\"iop\""; } virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const { s << " space=\"iop\""; } virtual void printRaw(ostream &s,uintb offset) const; virtual void saveXml(ostream &s) const; virtual void restoreXml(const Element *el); + static const string NAME; ///< Reserved name for the iop space }; /// \brief Lowest level operation of the \b p-code language diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.hh index 6205c47b91..3c7f2b26f4 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodecompile.hh @@ -58,7 +58,7 @@ class PcodeCompile { AddrSpace *uniqspace; uint4 local_labelcount; // Number of labels in current constructor bool enforceLocalKey; // Force slaspec to use 'local' keyword when defining temporary varnodes - virtual uintb allocateTemp(void)=0; + virtual uint4 allocateTemp(void)=0; virtual void addSymbol(SleighSymbol *sym)=0; public: PcodeCompile(void) { defaultspace=(AddrSpace *)0; constantspace=(AddrSpace *)0; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeinject.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeinject.hh index 4dea9f568a..af14ad02d6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeinject.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeinject.hh @@ -162,7 +162,7 @@ public: class PcodeInjectLibrary { protected: Architecture *glb; ///< The Architecture to which the injection payloads apply - uintb tempbase; ///< Offset within \e unique space for allocating temporaries within a payload + uint4 tempbase; ///< Offset within \e unique space for allocating temporaries within a payload vector injection; ///< Registered injections map callFixupMap; ///< Map of registered call-fixup names to injection id map callOtherFixupMap; ///< Map of registered callother-fixup names to injection id @@ -195,9 +195,9 @@ protected: /// \param injectid is the id of the InjectPayload to finalize virtual void registerInject(int4 injectid)=0; public: - PcodeInjectLibrary(Architecture *g,uintb tmpbase) { glb = g; tempbase = tmpbase; } ///< Constructor + PcodeInjectLibrary(Architecture *g,uint4 tmpbase) { glb = g; tempbase = tmpbase; } ///< Constructor virtual ~PcodeInjectLibrary(void); ///< Destructor - uintb getUniqueBase(void) const { return tempbase; } ///< Get the (current) offset for building temporary registers + uint4 getUniqueBase(void) const { return tempbase; } ///< Get the (current) offset for building temporary registers int4 getPayloadId(int4 type,const string &nm) const; ///< Map name and type to the payload id InjectPayload *getPayload(int4 id) const { return injection[id]; } ///< Get the InjectPayload by id string getCallFixupName(int4 injectid) const; ///< Get the call-fixup name associated with an id diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.cc index a15a81a2ac..8a02942b63 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.cc @@ -3236,10 +3236,10 @@ void PcodeLexer::initialize(istream *t) } } -uintb PcodeSnippet::allocateTemp(void) +uint4 PcodeSnippet::allocateTemp(void) { // Allocate a variable in the unique space and return the offset - uintb res = tempbase; + uint4 res = tempbase; tempbase += 16; return res; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.hh index d8621a9eec..587604237a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/pcodeparse.hh @@ -71,11 +71,11 @@ class PcodeSnippet : public PcodeCompile { PcodeLexer lexer; const SleighBase *sleigh; // Language from which we get symbols SymbolTree tree; // Symbols in the local scope of the snippet (temporaries) - uintb tempbase; + uint4 tempbase; int4 errorcount; string firsterror; ConstructTpl *result; - virtual uintb allocateTemp(void); + virtual uint4 allocateTemp(void); virtual void addSymbol(SleighSymbol *sym); public: PcodeSnippet(const SleighBase *slgh); @@ -87,8 +87,8 @@ public: virtual void reportWarning(const Location *loc, const string &msg) {} bool hasErrors(void) const { return (errorcount != 0); } const string getErrorMessage(void) const { return firsterror; } - void setUniqueBase(uintb val) { tempbase = val; } - uintb getUniqueBase(void) const { return tempbase; } + void setUniqueBase(uint4 val) { tempbase = val; } + uint4 getUniqueBase(void) const { return tempbase; } void clear(void); int lex(void); bool parseStream(istream& s); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc index bf65a9d5f0..4c06eb5462 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.cc @@ -186,6 +186,30 @@ AddrSpace *SleighBuilder::generatePointer(const VarnodeTpl *vntpl,VarnodeData &v return hand.space; } +void SleighBuilder::generatePointerAdd(PcodeData *op,const VarnodeTpl *vntpl) + +{ + uintb offsetPlus = vntpl->getOffset().getReal() & 0xffff; + if (offsetPlus == 0) { + return; + } + PcodeData *nextop = cache->allocateInstruction(); + nextop->opc = op->opc; + nextop->invar = op->invar; + nextop->isize = op->isize; + nextop->outvar = op->outvar; + op->isize = 2; + op->opc = CPUI_INT_ADD; + VarnodeData *newparams = op->invar = cache->allocateVarnodes(2); + newparams[0] = nextop->invar[1]; + newparams[1].space = const_space; // Add in V_OFFSET_PLUS + newparams[1].offset = offsetPlus; + newparams[1].size = newparams[0].size; + op->outvar = nextop->invar + 1; // Output of ADD is input to original op + op->outvar->space = uniq_space; // Result of INT_ADD in special runtime temp + op->outvar->offset = uniq_space->getTrans()->getUniqueStart(Translate::RUNTIME_BITRANGE_EA); +} + void SleighBuilder::dump(OpTpl *op) { // Dump on op through low-level dump interface @@ -211,6 +235,8 @@ void SleighBuilder::dump(OpTpl *op) loadvars[0].space = const_space; loadvars[0].offset = (uintb)(uintp)spc; loadvars[0].size = sizeof(spc); + if (vn->getOffset().getSelect() == ConstTpl::v_offset_plus) + generatePointerAdd(load_op, vn); } else generateLocation(vn,invars[i]); @@ -238,6 +264,8 @@ void SleighBuilder::dump(OpTpl *op) storevars[0].space = const_space; storevars[0].offset = (uintb)(uintp)spc; // space in which to store storevars[0].size = sizeof(spc); + if (outvn->getOffset().getSelect() == ConstTpl::v_offset_plus) + generatePointerAdd(store_op,outvn); } else { thisop->outvar = cache->allocateVarnodes(1); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.hh index 1a758a4881..4a66e77606 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh.hh @@ -136,6 +136,7 @@ class SleighBuilder : public PcodeBuilder { void buildEmpty(Constructor *ct,int4 secnum); void generateLocation(const VarnodeTpl *vntpl,VarnodeData &vn); AddrSpace *generatePointer(const VarnodeTpl *vntpl,VarnodeData &vn); + void generatePointerAdd(PcodeData *op,const VarnodeTpl *vntpl); void setUniqueOffset(const Address &addr); ///< Set uniquifying bits for the current instruction public: SleighBuilder(ParserWalker *w,DisassemblyCache *dcache,PcodeCacher *pc,AddrSpace *cspc,AddrSpace *uspc,uint4 umask); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh_arch.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh_arch.cc index a8efac8c7e..6b8edd53e2 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh_arch.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleigh_arch.cc @@ -161,7 +161,7 @@ PcodeInjectLibrary *SleighArchitecture::buildPcodeInjectLibrary(void) { // Build the pcode injector based on sleigh PcodeInjectLibrary *res; - res = new PcodeInjectLibrarySleigh(this,translate->getUniqueBase()); + res = new PcodeInjectLibrarySleigh(this); return res; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc index 1748131c88..0af4b793d3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc @@ -17,7 +17,7 @@ const int4 SleighBase::SLA_FORMAT_VERSION = 3; -const uintb SleighBase::MAX_UNIQUE_SIZE = 128; +const uint4 SleighBase::MAX_UNIQUE_SIZE = 128; int4 SourceFileIndexer::index(const string filename){ auto it = fileToIndex.find(filename); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh index 62c60e813f..2cfe1f751d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh @@ -69,7 +69,7 @@ protected: void reregisterContext(void); ///< Reregister context fields for a new executable void restoreXml(const Element *el); ///< Read a SLEIGH specification from XML public: - static const uintb MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java) + static const uint4 MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java) SleighBase(void); ///< Construct an uninitialized translator bool isInitialized(void) const { return (root != (SubtableSymbol *)0); } ///< Return \b true if \b this is initialized virtual ~SleighBase(void) {} ///< Destructor diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc index 40d775b2db..3ec58b9d05 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc @@ -1739,7 +1739,7 @@ void MacroBuilder::setLabel(OpTpl *op) outvec.push_back(clone); } -uintb SleighPcode::allocateTemp(void) +uint4 SleighPcode::allocateTemp(void) { return compiler->getUniqueAddr(); @@ -1799,14 +1799,14 @@ void SleighCompile::predefinedSymbols(void) // Some predefined symbols root = new SubtableSymbol("instruction"); // Base constructors symtab.addSymbol(root); - insertSpace(new ConstantSpace(this,this,"const",AddrSpace::constant_space_index)); + insertSpace(new ConstantSpace(this,this)); SpaceSymbol *spacesym = new SpaceSymbol(getConstantSpace()); // Constant space symtab.addSymbol(spacesym); - OtherSpace *otherSpace = new OtherSpace(this,this,"OTHER",AddrSpace::other_space_index); + OtherSpace *otherSpace = new OtherSpace(this,this,OtherSpace::INDEX); insertSpace(otherSpace); spacesym = new SpaceSymbol(otherSpace); symtab.addSymbol(spacesym); - insertSpace(new UniqueSpace(this,this,"unique",numSpaces(),0)); + insertSpace(new UniqueSpace(this,this,numSpaces(),0)); spacesym = new SpaceSymbol(getUniqueSpace()); // Temporary register space symtab.addSymbol(spacesym); StartSymbol *startsym = new StartSymbol("inst_start",getConstantSpace()); @@ -2271,10 +2271,10 @@ void SleighCompile::reportWarning(const string &msg) /// this method does not make an assumption about the size of the requested temporary Varnode. /// It reserves a fixed amount of space and returns its starting offset. /// \return the starting offset of the new temporary register -uintb SleighCompile::getUniqueAddr(void) +uint4 SleighCompile::getUniqueAddr(void) { - uintb base = getUniqueBase(); + uint4 base = getUniqueBase(); setUniqueBase(base + SleighBase::MAX_UNIQUE_SIZE); return base; } @@ -3422,7 +3422,7 @@ void SleighCompile::checkUniqueAllocation(void) if (i>=tables.size()) break; sym = tables[i]; } - uintm ubase = getUniqueBase(); // We have to adjust the unique base + uint4 ubase = getUniqueBase(); // We have to adjust the unique base ubase <<= sa; setUniqueBase(ubase); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh index edb19aed3f..e7ab191853 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh @@ -246,7 +246,7 @@ public: /// parser. class SleighPcode : public PcodeCompile { SleighCompile *compiler; ///< The main SLEIGH parser - virtual uintb allocateTemp(void); + virtual uint4 allocateTemp(void); virtual const Location *getLocation(SleighSymbol *sym) const; virtual void reportError(const Location* loc, const string &msg); virtual void reportWarning(const Location* loc, const string &msg); @@ -332,7 +332,7 @@ public: void reportWarning(const Location *loc, const string &msg); ///< Issue a warning message with a source location int4 numErrors(void) const { return errors; } ///< Return the current number of fatal errors - uintb getUniqueAddr(void); ///< Get the next available temporary register offset + uint4 getUniqueAddr(void); ///< Get the next available temporary register offset /// \brief Set whether unnecessary truncation and extension operators generate warnings individually /// diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc index 5f07edf8ea..7e70656a39 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/space.cc @@ -350,16 +350,17 @@ void AddrSpace::restoreXml(const Element *el) calcScaleMask(); } +const string ConstantSpace::NAME = "const"; + +const int4 ConstantSpace::INDEX = 0; + /// This constructs the unique constant space /// By convention, the name is always "const" and the index /// is always 0. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name -/// \param ind is the integer identifier -ConstantSpace::ConstantSpace(AddrSpaceManager *m,const Translate *t, - const string &nm,int4 ind) - : AddrSpace(m,t,IPTR_CONSTANT,nm,sizeof(uintb),1,ind,0,0) +ConstantSpace::ConstantSpace(AddrSpaceManager *m,const Translate *t) + : AddrSpace(m,t,IPTR_CONSTANT,NAME,sizeof(uintb),1,INDEX,0,0) { clearFlags(heritaged|does_deadcode|big_endian); if (HOST_ENDIAN==1) // Endianness always matches host @@ -390,16 +391,18 @@ void ConstantSpace::restoreXml(const Element *el) throw LowlevelError("Should never restore the constant space from XML"); } +const string OtherSpace::NAME = "OTHER"; + +const int4 OtherSpace::INDEX = 1; + /// Construct the \b other space, which is automatically constructed /// by the compiler, and is only constructed once. The name should /// always by \b OTHER. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name of the space /// \param ind is the integer identifier -OtherSpace::OtherSpace(AddrSpaceManager *m,const Translate *t, - const string &nm,int4 ind) - : AddrSpace(m,t,IPTR_PROCESSOR,nm,sizeof(uintb),1,ind,0,0) +OtherSpace::OtherSpace(AddrSpaceManager *m,const Translate *t,int4 ind) + : AddrSpace(m,t,IPTR_PROCESSOR,NAME,sizeof(uintb),1,INDEX,0,0) { clearFlags(heritaged|does_deadcode); setFlags(is_otherspace); @@ -426,17 +429,19 @@ void OtherSpace::saveXml(ostream &s) const s << "/>\n"; } +const string UniqueSpace::NAME = "unique"; + +const uint4 UniqueSpace::SIZE = 4; + /// This is the constructor for the \b unique space, which is /// automatically constructed by the analysis engine, and /// constructed only once. The name should always be \b unique. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name of the space /// \param ind is the integer identifier /// \param fl are attribute flags (currently unused) -UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t,const string &nm, - int4 ind,uint4 fl) - : AddrSpace(m,t,IPTR_INTERNAL,nm,sizeof(uintm),1,ind,fl,0) +UniqueSpace::UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl) + : AddrSpace(m,t,IPTR_INTERNAL,NAME,SIZE,1,ind,fl,0) { setFlags(hasphysical); } @@ -455,14 +460,15 @@ void UniqueSpace::saveXml(ostream &s) const s << "/>\n"; } +const string JoinSpace::NAME = "join"; + /// This is the constructor for the \b join space, which is automatically constructed by the /// analysis engine, and constructed only once. The name should always be \b join. /// \param m is the associated address space manager /// \param t is the associated processor translator -/// \param nm is the name of the space /// \param ind is the integer identifier -JoinSpace::JoinSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind) - : AddrSpace(m,t,IPTR_JOIN,nm,sizeof(uintm),1,ind,0,0) +JoinSpace::JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind) + : AddrSpace(m,t,IPTR_JOIN,NAME,sizeof(uintm),1,ind,0,0) { // This is a virtual space // setFlags(hasphysical); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/space.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/space.hh index 3bac2651ff..23eb035417 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/space.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/space.hh @@ -86,10 +86,6 @@ public: is_otherspace = 512, ///< Quick check for the OtherSpace derived class has_nearpointers = 0x400 ///< Does there exist near pointers into this space }; - enum { - constant_space_index = 0, ///< Reserved index for the constant space - other_space_index = 1 ///< Reserved index for the other space - }; private: spacetype type; ///< Type of space (PROCESSOR, CONSTANT, INTERNAL, ...) AddrSpaceManager *manage; ///< Manager for processor using this space @@ -178,19 +174,23 @@ public: /// by the offset field of an Address. class ConstantSpace : public AddrSpace { public: - ConstantSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); ///< Only constructor + ConstantSpace(AddrSpaceManager *m,const Translate *t); ///< Only constructor virtual void printRaw(ostream &s,uintb offset) const; virtual void saveXml(ostream &s) const; virtual void restoreXml(const Element *el); + static const string NAME; // Reserved name for the address space + static const int4 INDEX; // Reserved index for constant space }; /// \brief Special AddrSpace for special/user-defined address spaces class OtherSpace : public AddrSpace { public: - OtherSpace(AddrSpaceManager *m, const Translate *t, const string &nm, int4 ind); ///< Constructor + OtherSpace(AddrSpaceManager *m, const Translate *t, int4 ind); ///< Constructor OtherSpace(AddrSpaceManager *m, const Translate *t); ///< For use with restoreXml virtual void printRaw(ostream &s, uintb offset) const; virtual void saveXml(ostream &s) const; + static const string NAME; // Reserved name for the address space + static const int4 INDEX; // Reserved index for the other space }; /// \brief The pool of temporary storage registers @@ -204,9 +204,11 @@ public: /// \b unique. class UniqueSpace : public AddrSpace { public: - UniqueSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind,uint4 fl); ///< Constructor + UniqueSpace(AddrSpaceManager *m,const Translate *t,int4 ind,uint4 fl); ///< Constructor UniqueSpace(AddrSpaceManager *m,const Translate *t); ///< For use with restoreXml virtual void saveXml(ostream &s) const; + static const string NAME; ///< Reserved name for the unique space + static const uint4 SIZE; ///< Fixed size (in bytes) for unique space offsets }; /// \brief The pool of logically joined variables @@ -219,7 +221,7 @@ public: /// have an absolute meaning, the database may vary what offset is assigned to what set of pieces. class JoinSpace : public AddrSpace { public: - JoinSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind); + JoinSpace(AddrSpaceManager *m,const Translate *t,int4 ind); virtual void saveXmlAttributes(ostream &s,uintb offset) const; virtual void saveXmlAttributes(ostream &s,uintb offset,int4 size) const; virtual uintb restoreXmlAttributes(const Element *el,uint4 &size) const; @@ -227,6 +229,7 @@ public: virtual uintb read(const string &s,int4 &size) const; virtual void saveXml(ostream &s) const; virtual void restoreXml(const Element *el); + static const string NAME; ///< Reserved name for the join space }; /// \brief An overlay space. diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc index 6a397be4a4..de3621aa40 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc @@ -229,7 +229,7 @@ void AddrSpaceManager::restoreXmlSpaces(const Element *el,const Translate *trans { // The first space should always be the constant space - insertSpace(new ConstantSpace(this,trans,"const",AddrSpace::constant_space_index)); + insertSpace(new ConstantSpace(this,trans)); string defname(el->getAttributeValue("defaultspace")); const List &list(el->getChildren()); @@ -302,14 +302,14 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc) bool duplicateId = false; switch(spc->getType()) { case IPTR_CONSTANT: - if (spc->getName() != "const") + if (spc->getName() != ConstantSpace::NAME) nameTypeMismatch = true; - if (spc->index != AddrSpace::constant_space_index) + if (spc->index != ConstantSpace::INDEX) throw LowlevelError("const space must be assigned index 0"); constantspace = spc; break; case IPTR_INTERNAL: - if (spc->getName() != "unique") + if (spc->getName() != UniqueSpace::NAME) nameTypeMismatch = true; if (uniqspace != (AddrSpace *)0) duplicateName = true; @@ -323,7 +323,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc) fspecspace = spc; break; case IPTR_JOIN: - if (spc->getName() != "join") + if (spc->getName() != JoinSpace::NAME) nameTypeMismatch = true; if (joinspace != (AddrSpace *)0) duplicateName = true; @@ -349,7 +349,7 @@ void AddrSpaceManager::insertSpace(AddrSpace *spc) ospc->getBaseSpace()->setFlags(AddrSpace::overlaybase); // Mark the base as being overlayed } else if (spc->isOtherSpace()) { - if (spc->index != AddrSpace::other_space_index) + if (spc->index != OtherSpace::INDEX) throw LowlevelError("OTHER space must be assigned index 1"); } break; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh index 04434bc671..7bc942af79 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.hh @@ -292,21 +292,32 @@ public: /// with the processor. In particular, it knows about all the /// address spaces, registers, and spacebases for the processor. class Translate : public AddrSpaceManager { +public: + /// Tagged addresses in the \e unique address space + enum UniqueLayout { + RUNTIME_BOOLEAN_INVERT=0, ///< Location of the runtime temporary for boolean inversion + RUNTIME_RETURN_LOCATION=0x80, ///< Location of the runtime temporary storing the return value + RUNTIME_BITRANGE_EA=0x100, ///< Location of the runtime temporary for storing an effective address + INJECT=0x200, ///< Range of temporaries for use in compiling p-code snippets + ANALYSIS=0x10000000 ///< Range of temporaries for use during decompiler analysis + }; +private: bool target_isbigendian; ///< \b true if the general endianness of the process is big endian - uintm unique_base; ///< Starting offset into unique space + uint4 unique_base; ///< Starting offset into unique space protected: int4 alignment; ///< Byte modulo on which instructions are aligned vector floatformats; ///< Floating point formats utilized by the processor void setBigEndian(bool val); ///< Set general endianness to \b big if val is \b true - void setUniqueBase(uintm val); ///< Set the base offset for new temporary registers + void setUniqueBase(uint4 val); ///< Set the base offset for new temporary registers public: Translate(void); ///< Constructor for the translator void setDefaultFloatFormats(void); ///< If no explicit float formats, set up default formats bool isBigEndian(void) const; ///< Is the processor big endian? const FloatFormat *getFloatFormat(int4 size) const; ///< Get format for a particular floating point encoding int4 getAlignment(void) const; ///< Get the instruction alignment for the processor - uintm getUniqueBase(void) const; ///< Get the base offset for new temporary registers + uint4 getUniqueBase(void) const; ///< Get the base offset for new temporary registers + uint4 getUniqueStart(UniqueLayout layout) const; ///< Get a tagged address within the \e unique space /// \brief Initialize the translator given XML configuration documents /// @@ -551,7 +562,7 @@ inline void Translate::setBigEndian(bool val) { /// for the pcode engine, and sets the base offset where registers /// created by the simplification process can start being allocated. /// \param val is the boundary offset -inline void Translate::setUniqueBase(uintm val) { +inline void Translate::setUniqueBase(uint4 val) { if (val>unique_base) unique_base = val; } @@ -573,14 +584,19 @@ inline int4 Translate::getAlignment(void) const { return alignment; } -/// This routine gets the base offset, within the \e unique -/// temporary register space, where new registers can be -/// allocated for the simplification process. Locations before -/// this offset are reserved registers needed by the pcode -/// translation engine. +/// Return the first offset within the \e unique space after the range statically reserved by Translate. +/// This is generally the starting offset where dynamic temporary registers can start to be allocated. /// \return the first allocatable offset -inline uintm Translate::getUniqueBase(void) const { +inline uint4 Translate::getUniqueBase(void) const { return unique_base; } +/// Regions of the \e unique space are reserved for specific uses. We select the start of a specific +/// region based on the given tag. +/// \param layout is the given tag +/// \return the absolute offset into the \e unique space +inline uint4 Translate::getUniqueStart(UniqueLayout layout) const { + return (layout != ANALYSIS) ? layout + unique_base : layout; +} + #endif diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc index 6fa44dfe48..5c773d414b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.cc @@ -852,17 +852,15 @@ void Varnode::printRaw(ostream &s,const Varnode *vn) } /// \param m is the underlying address space manager -/// \param uspace is the \e unique space -/// \param ubase is the base offset for allocating temporaries -VarnodeBank::VarnodeBank(AddrSpaceManager *m,AddrSpace *uspace,uintm ubase) +VarnodeBank::VarnodeBank(AddrSpaceManager *m) : searchvn(0,Address(Address::m_minimal),(Datatype *)0) { manage = m; searchvn.flags = Varnode::input; // searchvn is always an input varnode of size 0 - uniq_space = uspace; - uniqbase = ubase; - uniqid = ubase; + uniq_space = m->getUniqueSpace(); + uniqbase = uniq_space->getTrans()->getUniqueStart(Translate::ANALYSIS); + uniqid = uniqbase; create_index = 0; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh index c4443c76d7..2d6fcf1add 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varnode.hh @@ -339,7 +339,7 @@ class VarnodeBank { mutable Varnode searchvn; ///< Template varnode for searching trees Varnode *xref(Varnode *vn); ///< Insert a Varnode into the sorted lists public: - VarnodeBank(AddrSpaceManager *m,AddrSpace *uspace,uintm ubase); ///< Construct the container + VarnodeBank(AddrSpaceManager *m); ///< Construct the container void clear(void); ///< Clear out all Varnodes and reset counters ~VarnodeBank(void) { clear(); } ///< Destructor int4 numVarnodes(void) const { return loc_tree.size(); } ///< Get number of Varnodes \b this contains 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 21babd7495..dc2e2ae6f6 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 @@ -25,6 +25,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.AddressFactory; import ghidra.program.model.lang.*; @@ -212,9 +213,7 @@ public class DecompInterface { DecompileProcessFactory.release(decompProcess); decompProcess = DecompileProcessFactory.get(); } - // use static uniqueBase since we don't know how many dynamically generated - // variables Ghidra may add to the language/compile-spec uniqueBase - long uniqueBase = 0x10000000; + long uniqueBase = UniqueLayout.SLEIGH_BASE.getOffset(pcodelanguage); String tspec = pcodelanguage.buildTranslatorTag(program.getAddressFactory(), uniqueBase, null); String coretypes = dtmanage.buildCoreTypes(); 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 868d3205f0..5fa15b44ea 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 @@ -67,7 +67,6 @@ public class DecompileCallback { private DecompileDebug debug; private Program program; private Listing listing; - private UniqueAddressFactory uniqueFactory; private Function cachedFunction; private AddressSet undefinedBody; private Address funcEntry; @@ -88,7 +87,6 @@ public class DecompileCallback { PcodeDataTypeManager dt) { program = prog; pcodelanguage = language; - uniqueFactory = new UniqueAddressFactory(prog.getAddressFactory(), language); pcodecompilerspec = compilerSpec; listing = program.getListing(); addrfactory = program.getAddressFactory(); @@ -138,7 +136,6 @@ public class DecompileCallback { if (pseudoDisassembler != null) { pseudoDisassembler.resetDisassemblerContext(); } - uniqueFactory.reset(); } /** @@ -294,7 +291,7 @@ public class DecompileCallback { PackedBytes pcode = instr.getPrototype() .getPcodePacked(instr.getInstructionContext(), - new InstructionPcodeOverride(instr), uniqueFactory); + new InstructionPcodeOverride(instr)); return pcode; } 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 08ddd95e5d..5eae12a060 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 @@ -49,10 +49,10 @@ public abstract class PcodeEmit { private Address defaultFallAddress; private Address fallOverride; private int fallOffset; - private UniqueAddressFactory uniqueFactory; + private SleighLanguage language; + private AddressFactory addressFactory; private VarnodeData outcache; protected VarnodeData[] incache; - private VarnodeData[] dyncache; protected ArrayList labeldef = null; protected int numOps = 0; // Number of PcodeOps generated so far private int labelbase = 0; @@ -76,10 +76,9 @@ public abstract class PcodeEmit { * @param ictx is the InstructionContext interface to resolve requests for context * @param fallOffset default instruction fall offset (i.e., instruction length including delay slotted instructions) * @param override required if pcode overrides are to be utilized - * @param uniqueFactory required when override specified or if overlay normalization is required */ public PcodeEmit(ParserWalker walk, InstructionContext ictx, int fallOffset, - PcodeOverride override, UniqueAddressFactory uniqueFactory) { + PcodeOverride override) { this.walker = walk; this.parsercontext = walk.getParserContext(); this.instcontext = ictx; @@ -88,30 +87,27 @@ public abstract class PcodeEmit { AddressSpace myspace = startAddress.getAddressSpace(); if (myspace.isOverlaySpace()) { overlayspace = myspace; - startAddress = ((OverlayAddressSpace) myspace).getOverlayedSpace().getAddress( - startAddress.getOffset()); + startAddress = ((OverlayAddressSpace) myspace).getOverlayedSpace() + .getAddress(startAddress.getOffset()); } this.fallOffset = fallOffset; - this.uniqueFactory = uniqueFactory; this.override = override; SleighInstructionPrototype sleighproto = parsercontext.getPrototype(); if (sleighproto != null) { - SleighLanguage sleighlang = (SleighLanguage) sleighproto.getLanguage(); - uniq_space = sleighlang.getAddressFactory().getUniqueSpace(); - uniquemask = sleighlang.getUniqueAllocationMask(); + language = (SleighLanguage) sleighproto.getLanguage(); + addressFactory = language.getAddressFactory(); + uniq_space = addressFactory.getUniqueSpace(); + uniquemask = language.getUniqueAllocationMask(); uniqueoffset = (startAddress.getOffset() & uniquemask) << 4; } else { // This can happen for CallFixup snippets, but these don't need their temporary vars patched up + language = null; uniq_space = null; uniquemask = 0; uniqueoffset = 0; } if (override != null) { - if (uniqueFactory == null) { - throw new IllegalArgumentException( - "uniqueFactory required when override is specified"); - } flowOverride = override.getFlowOverride(); if (flowOverride == FlowOverride.NONE) { flowOverride = null; @@ -131,7 +127,6 @@ public abstract class PcodeEmit { } incache = new VarnodeData[8]; // Maximum number of inputs - dyncache = null; } private void setUniqueOffset(Address addr) { @@ -159,7 +154,7 @@ public abstract class PcodeEmit { */ private void setLabel(OpTpl op) { if (labeldef == null) { - labeldef = new ArrayList(); + labeldef = new ArrayList<>(); } int labelindex = (int) op.getInput()[0].getOffset().getReal() + labelbase; while (labeldef.size() <= labelindex) { @@ -282,9 +277,11 @@ public abstract class PcodeEmit { // CALL //