diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/CallFixupAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/CallFixupAnalyzer.java
index 60f8c68024..36931f31b0 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/CallFixupAnalyzer.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/CallFixupAnalyzer.java
@@ -101,8 +101,8 @@ public class CallFixupAnalyzer extends AbstractAnalyzer {
if (mustFix) {
PcodeInjectLibrary snippetLibrary =
program.getCompilerSpec().getPcodeInjectLibrary();
- InjectPayload callFixup =
- snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, callFixupApplied);
+ InjectPayload callFixup = snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE,
+ callFixupApplied, program, null);
boolean isfallthru = true;
if (callFixup != null) {
isfallthru = callFixup.isFallThru();
@@ -405,8 +405,8 @@ public class CallFixupAnalyzer extends AbstractAnalyzer {
}
}
- program.getBookmarkManager()
- .removeBookmarks(repairedCallLocations, BookmarkType.ERROR, monitor);
+ program.getBookmarkManager().removeBookmarks(repairedCallLocations, BookmarkType.ERROR,
+ monitor);
if (!clearInstSet.isEmpty()) {
// entries including data flow referenced from instructions will be repaired
@@ -449,7 +449,7 @@ public class CallFixupAnalyzer extends AbstractAnalyzer {
String[] callFixupNames = snippetLibrary.getCallFixupNames();
for (String fixupName : callFixupNames) {
InjectPayload payload =
- snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, fixupName);
+ snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, fixupName, program, null);
List callFixupTargets = ((InjectPayloadCallfixup) payload).getTargets();
for (String name : callFixupTargets) {
cachedTargetFixupMap.put(name, fixupName);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorDialog.java
index a8d85b1a9e..da0ecfab24 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorDialog.java
@@ -359,9 +359,6 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
}
private JComponent createCallFixupComboPanel() {
-
- JPanel panel = new JPanel();
-
callFixupComboBox = new GComboBox<>();
String[] callFixupNames = model.getCallFixupNames();
@@ -380,8 +377,7 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
callFixupComboBox.setEnabled(false);
}
- panel.add(callFixupComboBox);
- return panel;
+ return callFixupComboBox;
}
private Component buildTable() {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
index 0ec9498847..1d2c2b5a3f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
@@ -405,9 +405,8 @@ public class SymbolicPropogator {
canceled = false;
// only stop flowing on unknown bad calls when the stack depth could be unknown
- boolean callCouldCauseBadStackDepth = program.getCompilerSpec()
- .getDefaultCallingConvention()
- .getExtrapop() == PrototypeModel.UNKNOWN_EXTRAPOP;
+ boolean callCouldCauseBadStackDepth =
+ program.getCompilerSpec().getDefaultCallingConvention().getExtrapop() == PrototypeModel.UNKNOWN_EXTRAPOP;
while (!contextStack.isEmpty()) {
monitor.checkCanceled();
@@ -835,8 +834,8 @@ public class SymbolicPropogator {
try {
val1 = vContext.getValue(in[0], evaluator);
lval1 = vContext.getConstant(val1, evaluator);
- vt = vContext.getVarnode(minInstrAddress.getAddressSpace().getSpaceID(),
- lval1, 0);
+ vt = vContext.getVarnode(
+ minInstrAddress.getAddressSpace().getSpaceID(), lval1, 0);
makeReference(vContext, instruction, ptype, -1, vt,
instruction.getFlowType(), monitor);
}
@@ -874,8 +873,8 @@ public class SymbolicPropogator {
if (val1.isConstant()) {
// indirect target - assume single code space (same as instruction)
- target = instruction.getAddress()
- .getNewTruncatedAddress(val1.getOffset(), true);
+ target = instruction.getAddress().getNewTruncatedAddress(
+ val1.getOffset(), true);
}
else if (val1.isAddress()) {
// TODO: could this also occur if a memory location was copied ??
@@ -958,8 +957,8 @@ public class SymbolicPropogator {
case PcodeOp.CALLOTHER:
// HACK ALERT!
// if this is a segment op, emulate the segmenting for now.
- String opName = this.program.getLanguage()
- .getUserDefinedOpName((int) in[0].getOffset());
+ String opName = this.program.getLanguage().getUserDefinedOpName(
+ (int) in[0].getOffset());
if (opName.equals("segment") && in.length > 2) {
checkSegmented(out, in[1], in[2], mustClearAll);
}
@@ -1075,8 +1074,8 @@ public class SymbolicPropogator {
}
else if (!evaluator.followFalseConditionalBranches()) {
// pcode addresses are raw addresses, make sure address is in same instruction space
- nextAddr = minInstrAddress.getAddressSpace()
- .getOverlayAddress(in[0].getAddress());
+ nextAddr = minInstrAddress.getAddressSpace().getOverlayAddress(
+ in[0].getAddress());
pcodeIndex = ops.length; // break out of the processing
}
}
@@ -1203,8 +1202,8 @@ public class SymbolicPropogator {
case PcodeOp.INT_RIGHT:
val1 = vContext.getValue(in[0], false, evaluator);
val2 = vContext.getValue(in[1], false, evaluator);
- lresult = vContext.getConstant(val1, evaluator) >> vContext
- .getConstant(val2, evaluator);
+ lresult = vContext.getConstant(val1,
+ evaluator) >> vContext.getConstant(val2, evaluator);
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1212,8 +1211,8 @@ public class SymbolicPropogator {
case PcodeOp.INT_SRIGHT:
val1 = vContext.getValue(in[0], true, evaluator);
val2 = vContext.getValue(in[1], false, evaluator);
- lresult = vContext.getConstant(val1, evaluator) >>> vContext
- .getConstant(val2, evaluator);
+ lresult = vContext.getConstant(val1,
+ evaluator) >>> vContext.getConstant(val2, evaluator);
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1316,8 +1315,8 @@ public class SymbolicPropogator {
val2 = vContext.getValue(in[1], true, evaluator);
lval1 = vContext.getConstant(val1, evaluator);
lval2 = vContext.getConstant(val2, evaluator);
- lresult = (vContext.getConstant(val1, evaluator) < vContext
- .getConstant(val2, evaluator)) ? 1 : 0;
+ lresult = (vContext.getConstant(val1,
+ evaluator) < vContext.getConstant(val2, evaluator)) ? 1 : 0;
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1335,8 +1334,8 @@ public class SymbolicPropogator {
case PcodeOp.INT_SLESSEQUAL:
val1 = vContext.getValue(in[0], true, evaluator);
val2 = vContext.getValue(in[1], true, evaluator);
- lresult = (vContext.getConstant(val1, evaluator) <= vContext
- .getConstant(val2, evaluator)) ? 1 : 0;
+ lresult = (vContext.getConstant(val1,
+ evaluator) <= vContext.getConstant(val2, evaluator)) ? 1 : 0;
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1345,8 +1344,8 @@ public class SymbolicPropogator {
val1 = vContext.getValue(in[0], false, evaluator);
val2 = vContext.getValue(in[1], false, evaluator);
- lresult = (vContext.getConstant(val1, evaluator) == vContext
- .getConstant(val2, evaluator)) ? 1 : 0;
+ lresult = (vContext.getConstant(val1,
+ evaluator) == vContext.getConstant(val2, evaluator)) ? 1 : 0;
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1354,8 +1353,8 @@ public class SymbolicPropogator {
case PcodeOp.INT_NOTEQUAL:
val1 = vContext.getValue(in[0], false, evaluator);
val2 = vContext.getValue(in[1], false, evaluator);
- lresult = (vContext.getConstant(val1, evaluator) != vContext
- .getConstant(val2, evaluator)) ? 1 : 0;
+ lresult = (vContext.getConstant(val1,
+ evaluator) != vContext.getConstant(val2, evaluator)) ? 1 : 0;
result = vContext.createConstantVarnode(lresult, val1.getSize());
vContext.putValue(out, result, mustClearAll);
break;
@@ -1572,7 +1571,7 @@ public class SymbolicPropogator {
PcodeInjectLibrary snippetLibrary = prog.getCompilerSpec().getPcodeInjectLibrary();
InjectPayload payload =
- snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, callFixupName);
+ snippetLibrary.getPayload(InjectPayload.CALLFIXUP_TYPE, callFixupName, prog, null);
if (payload == null) {
return null;
}
@@ -1599,7 +1598,7 @@ public class SymbolicPropogator {
PcodeInjectLibrary snippetLibrary = prog.getCompilerSpec().getPcodeInjectLibrary();
InjectPayload payload =
- snippetLibrary.getPayload(InjectPayload.CALLMECHANISM_TYPE, injectionName);
+ snippetLibrary.getPayload(InjectPayload.CALLMECHANISM_TYPE, injectionName, prog, null);
if (payload == null) {
return null;
}
@@ -1844,14 +1843,14 @@ public class SymbolicPropogator {
// } else
if (!vContext.isStackSymbolicSpace(refLocation) && evaluator != null) {
- Address constant = program.getAddressFactory()
- .getAddress((int) targetSpaceID.getOffset(), offset);
+ Address constant = program.getAddressFactory().getAddress(
+ (int) targetSpaceID.getOffset(), offset);
Address newTarget = evaluator.evaluateConstant(vContext, instruction,
pcodeType, constant, 0, reftype);
if (newTarget != null) {
makeReference(vContext, instruction, Reference.MNEMONIC,
- newTarget.getAddressSpace().getSpaceID(), newTarget.getOffset(), 0,
- reftype, pcodeType, false, monitor);
+ newTarget.getAddressSpace().getSpaceID(), newTarget.getOffset(),
+ 0, reftype, pcodeType, false, monitor);
return;
}
}
diff --git a/Ghidra/Features/Decompiler/build.gradle b/Ghidra/Features/Decompiler/build.gradle
index 85a49229f9..a426377b0a 100644
--- a/Ghidra/Features/Decompiler/build.gradle
+++ b/Ghidra/Features/Decompiler/build.gradle
@@ -120,7 +120,7 @@ task buildDecompilerHelpHtml(type: Exec) {
rm -f $installHelpPoint/topics/DecompilePlugin/*.html
echo '** Building html files **'
- xsltproc --output $buildDir/decomp_noscaling.xml --stringparam profile.condition "noscaling" commonprofile.xsl decompileplugin.xml 2>&1
+ xsltproc --output $buildDir/decomp_noscaling.xml --stringparam profile.condition "noscaling" /usr/share/sgml/docbook/xsl-stylesheets/profiling/profile.xsl decompileplugin.xml 2>&1
xsltproc --stringparam base.dir ${installHelpPoint}/topics/DecompilePlugin/ --stringparam root.filename Decompiler decompileplugin_html.xsl $buildDir/decomp_noscaling.xml 2>&1
rm ${installHelpPoint}/topics/DecompilePlugin/Decompiler.html
sed -i -e '/Frontpage.css/ { p; s/Frontpage.css/languages.css/; }' ${installHelpPoint}/topics/DecompilePlugin/*.html 2>&1
@@ -175,19 +175,19 @@ task buildDecompilerHelpPdf(type: Exec) {
echo '** Checking if required executables are installed. **'
which fop 2>&1
which xsltproc 2>&1
- rm -f $buildDir/decompileplugin.fo $buildDir/decompileplugin.pdf $buildDir/decompileplugin_withscaling.xml 2>&1
- rm -rf $buildDir/images 2>&1
- mkdir -p $buildDir/images 2>&1
- cp $installHelpPoint/topics/DecompilePlugin/images/*.png $buildDir/images 2>&1
- cp $installHelpPoint/topics/DecompilePlugin/images/*.gif $buildDir/images 2>&1
- cp $installHelpPoint/shared/*.png $buildDir/images 2>&1
+ rm -f decompileplugin.fo decompileplugin.pdf decompileplugin_withscaling.xml 2>&1
+ rm -rf ./images 2>&1
+ mkdir -p ./images 2>&1
+ cp $installHelpPoint/topics/DecompilePlugin/images/*.png ./images 2>&1
+ cp $installHelpPoint/topics/DecompilePlugin/images/*.gif ./images 2>&1
+ cp $installHelpPoint/shared/*.png ./images 2>&1
echo '** Building decompileplugin.fo **'
- xsltproc --output $buildDir/decompileplugin_withscaling.xml --stringparam profile.condition "withscaling" commonprofile.xsl decompileplugin.xml 2>&1
- xsltproc --output $buildDir/decompileplugin.fo decompileplugin_pdf.xsl $buildDir/decompileplugin_withscaling.xml 2>&1
+ xsltproc --output ./decompileplugin_withscaling.xml --stringparam profile.condition "withscaling" /usr/share/sgml/docbook/xsl-stylesheets/profiling/profile.xsl decompileplugin.xml 2>&1
+ xsltproc --output ./decompileplugin.fo decompileplugin_pdf.xsl decompileplugin_withscaling.xml 2>&1
echo '** Building decompileplugin.pdf **'
- fop $buildDir/decompileplugin.fo $buildDir/decompileplugin.pdf 2>&1
+ fop decompileplugin.fo decompileplugin.pdf 2>&1
echo '** Done. **'
"""
diff --git a/Ghidra/Features/Decompiler/certification.manifest b/Ghidra/Features/Decompiler/certification.manifest
index 9a6aa4192b..f965b0d4c3 100644
--- a/Ghidra/Features/Decompiler/certification.manifest
+++ b/Ghidra/Features/Decompiler/certification.manifest
@@ -30,7 +30,6 @@ src/decompile/datatests/sbyte.xml||GHIDRA||||END|
src/decompile/datatests/threedim.xml||GHIDRA||||END|
src/decompile/datatests/twodim.xml||GHIDRA||||END|
src/decompile/datatests/wayoffarray.xml||GHIDRA||||END|
-src/main/doc/commonprofile.xsl||GHIDRA||||END|
src/main/doc/cspec.xml||GHIDRA||||END|
src/main/doc/cspec_html.xsl||GHIDRA||||END|
src/main/doc/decompileplugin.xml||GHIDRA||||END|
diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/TurnOnLanguage.java b/Ghidra/Features/Decompiler/ghidra_scripts/TurnOnLanguage.java
index 0a29834439..2a86ffda93 100644
--- a/Ghidra/Features/Decompiler/ghidra_scripts/TurnOnLanguage.java
+++ b/Ghidra/Features/Decompiler/ghidra_scripts/TurnOnLanguage.java
@@ -15,17 +15,18 @@
*/
import ghidra.app.script.GhidraScript;
import ghidra.framework.options.Options;
-import ghidra.program.database.ProgramCompilerSpec;
+import ghidra.program.model.lang.BasicCompilerSpec;
public class TurnOnLanguage extends GhidraScript {
@Override
protected void run() throws Exception {
- Options decompilerPropertyList =
- currentProgram.getOptions(ProgramCompilerSpec.DECOMPILER_PROPERTY_LIST_NAME);
- decompilerPropertyList.registerOption(ProgramCompilerSpec.DECOMPILER_OUTPUT_LANGUAGE,
- ProgramCompilerSpec.DECOMPILER_OUTPUT_DEF, null,
- ProgramCompilerSpec.DECOMPILER_OUTPUT_DESC);
+ Options decompilerPropertyList = currentProgram.getOptions(BasicCompilerSpec.DECOMPILER_PROPERTY_LIST_NAME);
+ decompilerPropertyList.registerOption(
+ BasicCompilerSpec.DECOMPILER_OUTPUT_LANGUAGE,
+ BasicCompilerSpec.DECOMPILER_OUTPUT_DEF,
+ null,
+ BasicCompilerSpec.DECOMPILER_OUTPUT_DESC);
}
}
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc
index 56dd7f979f..e04d172dab 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc
@@ -1218,26 +1218,6 @@ void Architecture::parseCompilerConfig(DocumentStorage &store)
else if (elname == "inferptrbounds")
parseInferPtrBounds(*iter);
}
-
- el = store.getTag("specextensions"); // Look for any user-defined configuration document
- if (el != (const Element *)0) {
- const List &userlist(el->getChildren());
- for(iter=userlist.begin();iter!=userlist.end();++iter) {
- const string &elname( (*iter)->getName() );
- if (elname == "prototype")
- parseProto(*iter);
- else if (elname == "callfixup") {
- pcodeinjectlib->restoreXmlInject(archid+" : compiler spec", (*iter)->getAttributeValue("name"),
- InjectPayload::CALLFIXUP_TYPE, *iter);
- }
- else if (elname == "callotherfixup") {
- userops.parseCallOtherFixup(*iter,this);
- }
- else if (elname == "global")
- globaltags.push_back(*iter);
- }
- }
-
// tags instantiate the base symbol table
// They need to know about all spaces, so it must come
// after parsing of and
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh
index 974e733e22..9a592cb4a2 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/fspec.hh
@@ -314,7 +314,7 @@ public:
enum {
unaffected = 1, ///< The sub-function does not change the value at all
killedbycall = 2, ///< The memory is changed and is completely unrelated to its original value
- return_address = 3, ///< The memory is being used to store the return address
+ return_address = 3, ///< The memory is being used to pass back a return value from the sub-function
unknown_effect = 4 ///< An unknown effect (indicates the absence of an EffectRecord)
};
private:
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc
index b72a8093db..d34513ef04 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.cc
@@ -284,7 +284,7 @@ void ArchitectureGhidra::buildSpecFile(DocumentStorage &store)
istringstream cstream(cspecxml);
doc = store.parseDocument(cstream);
store.registerTag(doc->getRoot());
-
+
istringstream tstream(tspecxml);
doc = store.parseDocument(tstream);
store.registerTag(doc->getRoot());
@@ -293,10 +293,10 @@ void ArchitectureGhidra::buildSpecFile(DocumentStorage &store)
doc = store.parseDocument(corestream);
store.registerTag(doc->getRoot());
- pspecxml.clear(); // Strings aren't used again free memory
- cspecxml.clear();
- tspecxml.clear();
- corespecxml.clear();
+ pspecxml = ""; // Strings aren't used again free memory
+ cspecxml = "";
+ tspecxml = "";
+ corespecxml = "";
}
void ArchitectureGhidra::postSpecFile(void)
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.hh
index 0953288662..f796c7ea76 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.hh
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.hh
@@ -82,8 +82,7 @@ class ArchitectureGhidra : public Architecture {
virtual void postSpecFile(void);
virtual void resolveArchitecture(void);
public:
- ArchitectureGhidra(const string &pspec,const string &cspec,const string &tspec,const string &corespec,
- istream &i,ostream &o);
+ ArchitectureGhidra(const string &pspec,const string &cspec,const string &tspec,const string &corespec,istream &i,ostream &o);
const string &getWarnings(void) const { return warnings; } ///< Get warnings produced by the last decompilation
void clearWarnings(void) { warnings.clear(); } ///< Clear warnings
Document *getRegister(const string ®name); ///< Retrieve a register description given a name
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc
index 46efe6eb0f..e78b0c0ced 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_process.cc
@@ -174,10 +174,6 @@ void RegisterProgram::rawAction(void)
}
}
ghidra = new ArchitectureGhidra(pspec,cspec,tspec,corespec,sin,sout);
- pspec.clear();
- cspec.clear();
- tspec.clear();
- corespec.clear();
DocumentStorage store; // temp storage of initialization xml docs
ghidra->init(store);
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc
index b72d089d2a..4a1e44dbf8 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.cc
@@ -293,23 +293,6 @@ int4 PcodeInjectLibrarySleigh::registerDynamicInject(InjectPayload *payload)
return id;
}
-/// \brief Force a payload to be dynamic for debug purposes
-///
-/// Debug information may include inject information for payloads that aren't dynamic.
-/// We substitute a dynamic payload so that analysis uses the debug info to inject, rather
-/// than the hard-coded payload information.
-/// \param injectid is the id of the payload to treat dynamic
-/// \return the new dynamic payload object
-InjectPayloadDynamic *PcodeInjectLibrarySleigh::forceDebugDynamic(int4 injectid)
-
-{
- InjectPayload *oldPayload = injection[injectid];
- InjectPayloadDynamic *newPayload = new InjectPayloadDynamic(glb,oldPayload->getName(),oldPayload->getType());
- delete oldPayload;
- injection[injectid] = newPayload;
- return newPayload;
-}
-
void PcodeInjectLibrarySleigh::parseInject(InjectPayload *payload)
{
@@ -416,10 +399,9 @@ void PcodeInjectLibrarySleigh::restoreDebug(const Element *el)
s.unsetf(ios::dec | ios::hex | ios::oct);
s >> type;
int4 id = getPayloadId(type,name);
- InjectPayloadDynamic *payload = dynamic_cast(getPayload(id));
- if (payload == (InjectPayloadDynamic *)0) {
- payload = forceDebugDynamic(id);
- }
+ InjectPayloadDynamic *payload = (InjectPayloadDynamic *)getPayload(id);
+ if (payload->getSource() != "dynamic")
+ throw LowlevelError("Mismatch with debug inject XML");
payload->restoreEntry(subel);
}
}
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh
index 600215c658..ad6f44bff2 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/inject_sleigh.hh
@@ -91,7 +91,6 @@ class PcodeInjectLibrarySleigh : public PcodeInjectLibrary {
vector inst;
InjectContextSleigh contextCache;
int4 registerDynamicInject(InjectPayload *payload);
- InjectPayloadDynamic *forceDebugDynamic(int4 injectid);
void parseInject(InjectPayload *payload);
protected:
virtual int4 allocateInject(const string &sourceName,const string &name,int4 type);
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/userop.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/userop.cc
index 0d13d3a7b6..e08b43f037 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/userop.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/userop.cc
@@ -216,10 +216,10 @@ void SegmentOp::restoreXml(const Element *el)
throw LowlevelError("Bad segment pattern tag: "+subel->getName());
}
if (injectId < 0)
- throw LowlevelError("Missing child in tag");
+ throw LowlevelError("Missing child in tag");
InjectPayload *payload = glb->pcodeinjectlib->getPayload(injectId);
if (payload->sizeOutput() != 1)
- throw LowlevelError(" child of tag must declare one
In the absence of parameter and return value annotations, the decompiler will use the prototype model as
@@ -1043,8 +1042,7 @@
Call-fixups are specified by name. The name and associated p-code chunk are typically defined in the
- compiler specification for the Program. Users can extend the available set
- of call-fixups. See “Specification Extensions”.
+ compiler specification for the Program.
- P-code allows for additional, processor specific, operations referred to
- as user-defined or CALLOTHER operations.
- These may be defined as part of a Ghidra's specification for the processor and
- are typically used as placeholders for what is otherwise unmodeled processor behavior.
- Each CALLOTHER must have a unique name, and as a p-code operation, it still takes
- varnode inputs and may produce a varnode output. But the exact affect of the operation is
- not specified.
-
-
- The decompiler treats a CALLOTHER operation as a black box. It will keep track of data
- flowing into and out of the operation but won't simplify or transform it. In decompiler
- output, a CALLOTHER is usually displayed using its unique name, with functional syntax
- showing its inputs and output.
-
-
- Ghidra or a user can provide the behavior details for a named CALLOTHER operation. The
- details are provided as a sequence of p-code operations, referred to as a
- Callother-Fixup, which is substituted for the
- CALLOTHER operation during decompilation, or by other Analyzers that use p-code.
- Callother-Fixups are applied by Ghidra for specific processor or compiler variants,
- and a user can choose to apply them to an individual Program. (See “Specification Extensions”)
-
-
-
-
-
Internal Decompiler Functions
@@ -1081,13 +1052,10 @@
use of multiple models. Subsequently, each distinct model has a name like __stdcall or
__thiscall. The decompiler makes use of the prototype model, as assigned to the function by the user or
discovered in some other way, when performing its analysis of parameters.
- It is possible for users to extend the set of prototype models available to a Program,
- see “Specification Extensions”.
A prototype model is typically used as a whole and is assigned by name to individual functions. But some of
- the sub-concepts of the model may be relevant to reverse engineers. Concepts that a prototype
- model encapsulates include:
+ the sub-concepts of the model may be relevant to reverse engineers.
@@ -1139,150 +1107,5 @@
-
-
-SLEIGH Specification Files
-
-
- SLEIGH is Ghidra's specification language for describing processor instructions.
- Specification files are read in for a Program, and once configured, Ghidra's SLEIGH engine can:
-
-
-
-
- Disassemble machine instructions from the underlying bytes and
-
-
- Produce the raw p-code consumed by the decompiler and other analyzers.
-
-
-
-
-
-
- Specification files are selected based on the Language Id
- assigned to the Program at the time it is imported into Ghidra.
- (See Import Program)
-
-
-
-
x86:LE:32:default:windows
-
AARCH64:LE:64:default:v8A:default
-
MIPS:BE:32:micro:default
-
-
-
- A Language Id is a label with these 5 formal fields, separated
- by a ':' character:
-
-
-
-
Processor family
-
Endianess
-
Size of the address bus
-
Process variant
-
Compiler producing the Program
-
-
-
- A field with the value 'default' indicates either the preferred processor variant or the preferred compiler.
-
-
- Within the Ghidra installation, specification files are stored based on the overarching
- processor family, such as 'MIPS' or 'x86'. For a specific family, files are located under
-
- where <Root> represents the root directory of the Ghidra installation and
- <Family> is the processor family.
-
-
- There are several types of specification files that are distinguishable by their suffix.
- These include:
-
-
-
-
SLEIGH files - *.slaspec or *.sinc
-
-
- These are the human readable SLEIGH language files. A single specification is
- rooted in one of the *.slaspec files, which may recursively include
- one or more *.sinc files. The format of these files is described
- in the document "SLEIGH: A Language for Rapid Processor Specification".
-
-
-
Compiled SLEIGH files - *.sla
-
-
- This is a compiled form of a single SLEIGH specification. It is produced
- automatically by Ghidra from the corresponding *.slaspec.
-
-
-
Compiler specification files - *.cspec
-
-
- These files contain configuration for a specific compiler. Analysis of Programs whose
- executable content was produced using this compiler benefits from this information.
- The file is an XML document with tags describing details of data organization and
- other conventions used by the compiler. In particular, the compiler specification
- contains tags:
-
-
-
-
-
<prototype> - describing a specific calling convention
-
<callfixup> - describing a Call-fixup
-
<callotherfixup> - describing a Callother-fixup
-
-
-
-
-
Processor specification files - *.pspec
-
-
- These files contain configuration information that is specific to a particular
- processor variant.
-
-
-
-
-
-
-
-
-Modifying Specification Files
-
-
- Changing any of the specification files described here is not recommended.
- To make additions to either the compiler specification
- or the processor specification files, see
- “Specification Extensions”, which describes a safe and portable way
- to add specific elements.
-
-
-
-
-
-
-
- Making modifications to specification files within a Ghidra installation is possible,
- but any analysis results obtained will likely not be portable to other installations.
- In particular, saving a Program from a modified Ghidra and then reopening it using
- an unmodified installation may corrupt the Program database.
-
-
-
- When Ghidra starts, it checks for changes to *.slaspec
- and *.sinc files and will rebuild the corresponding
- *.sla file automatically. Also, specification files are read again when
- Ghidra restarts. So analysts can and do make changes to these files.
- However they need to be prepared to view any results as temporary and
- should backup their installation and specific Programs being analyzed.
-
- Options that are specific to the particular Program being analyzed are accessed by
- selecting the Code Browser menu
+ Another source of options can be accessed by selecting the Code Browser menu
Edit -> Options for <Program>
- Picking the Decompiler tab shows “Program Options”
- that only affect the decompiler. Picking the “Specification Extensions” tab
- shows a table of the available prototype models, call-fixups, and callother-fixups. These
- affect more than just the decompiler but are also documented here.
+ and the picking the Decompiler tab. These “Program Options”
+ are specific to the particular Program being analyzed.
@@ -576,8 +573,7 @@
Program Options
- Changes to these options affect only the decompiler and only for
- the current Program being analyzed.
+ Changes to these options affect only the current Program being analyzed.
@@ -599,284 +595,6 @@
-
-
-Specification Extensions
-
-
- This tab displays elements from the Program's compiler specification and
- processor specification and allows the user to add or remove
- extensions, including prototype models, call-fixups, and
- callother-fixups.
-
-
- Every program has a core set of specification elements,
- loaded from the “SLEIGH Specification Files”, that cannot
- be modified or removed. Extensions, however, can be added to this core specification. Any extension
- imported from this dialog is directly associated with the active Program and is stored permanently
- with it.
-
-
- Users can change or reimport an extension, if new information points to a better definition.
- Users have full control over an extension, and unlike a core element, can tailor it specifically
- to the Program.
-
-
- This options tab presents a table of all specification elements.
- Each element, whether core or an extension, is displayed on a separate row with three columns:
-
-
-
-
-Extension Type - indicating the type of element
-
-Name - showing the formal name of the element
-
-Status - indicating whether the element is core or an extension
-
-
-
- The core elements of the specification have a blank Status column, and any extension
- is labeled either as "extension" or "override".
-
-
-
-Extension Types
-
-
- Each of the element types described here represents an XML tag of the same name, which, if
- present in the table, must either be in the compiler specification file,
- the processor specification file, or provided to Ghidra as an
- import document.
-
-
-
-
prototype
-
-
- This element is a “Prototype Model” that holds a specific named set
- of parameter passing details. It
- can be applied to individual functions by name, typically via the "Calling Convention" menu
- in the Function Editor Dialog.
- See the documentation on “Function Prototypes” for how they affect decompilation.
-
-
- The XML tag, <prototype> always has a name attribute
- that defines the formal name of the prototype model, which must be unique across all models.
-
- This element is a Call-fixup, which can be used to substitute a specific p-code
- sequence for CALL instructions during decompilation, as described in
- “Function Prototypes”.
-
-
- The <callfixup> tag has a name
- attribute listing the formal name, which must be unique across all call-fixups.
-
- This element is a Callother-fixup, which can be used to substitute a specific p-code
- sequence for CALLOTHER p-code operations. A CALLOTHER
- is a black-box, or unspecified p-code operation, see “User-defined P-code Operations - CALLOTHER”.
-
-
- The <callotherfixup> tag has a
- targetop attribute which lists the
- name of the particular CALLOTHER operation it substitutes for.
-
- The Status column labels an element as either a core specification
- or an extension; it also gives an indication of whether the element
- is about to be installed or removed.
-
-
- With no changes pending, the column will show one of the three main values:
-
-
-
-
<blank>
-
-
- A blank Status column indicates that the element is a core part of the
- specification, originating from one of the specification files.
- These elements cannot be changed or removed.
-
-
-
extension
-
-
- Indicates that the element is a program specific extension that has been
- added to the specification.
-
-
-
override
-
-
- Indicates that the element, which must be a callotherfixup,
- is an extension that overrides a core element with the same target. The extension
- effectively replaces the p-code injection of the core element with a user supplied one.
- If this type of extension is later removed, the core element becomes active again.
-
-
-
-
-
-
-
- If the user has either imported additional extensions or selected an extensions for removal but
- has not yet clicked the Apply button in the Options dialog, the Status column
- may show one of the following values, indicating a pending change.
-
-
-
-
install
-
-
- Indicates a new extension that will be installed.
-
-
-
remove
-
-
- Indicates an extension that is about to be removed.
-
-
-
replace
-
-
- Indicates a new extension that will replace a current
- extension with the same name.
-
-
-
override pending
-
-
- Indicates a new extension that will override a core element when
- it is installed.
-
-
-
-
-
-
-
-
-
-Importing a New Extension
-
-
- The Import button at the bottom of the
- "Specification Extensions" pane allows the user to import one of the
- three element types, prototype,
- callfixup, or callotherfixup,
- into the program as a new extension.
- The user must supply a properly formed XML document, as a file, that fully describes the new
- extension. Clicking the Import button brings up a File Chooser dialog,
- from which the user must select their prepared XML file. Once Ok is
- clicked, the file is read in and validated. If there are any problems with the validation, or if
- the new extension's name collides with a core element, the import does not succeed and
- an error message will be displayed. Otherwise, the import is accepted, and the table is updated
- to indicate the pending change.
-
-
- The final change to the program, installing the new extension, will not happen until the
- Apply button, at the bottom of the Options dialog, is clicked.
-
-
- The XML file describing the extension must have one of the tags,
- <prototype>, <callfixup>, or <callotherfixup>,
- as its single root element. Users can find numerous examples within the compiler
- and processor specification files that come as part of Ghidra's installation.
- See “SLEIGH Specification Files”.
-
-
- In the case of prototype and callfixup
- elements, extensions cannot replace existing core elements, so the new extension must not
- have a name that matches an existing core element. If a new callotherfixup
- extension has a targetop that matches a core element, the extension is automatically treated as an override.
-
-
- Existing extensions can be replaced simply by importing a new extension with the same name or targetop.
-
-
-
-
-Removing an Extension
-
-
- The Remove button at the bottom of the "Specification Extensions" pane allows
- the user to remove a previously installed extension. A row from the table is selected first, which
- must have a Status of extension or override.
- Core elements of the specification cannot be removed.
- Clicking the Remove button brings up a confirmation dialog, and if
- Ok is clicked, the selected extension is marked for removal. The Status of the row
- changes to remove, reflecting this.
-
-
- The final change to the program, removing the extension, will not happen until the
- Apply button, at the bottom of the Options dialog, is clicked.
-
-
- If a prototype or callfixup is removed,
- all functions are checked to see if they have the matching calling convention or call-fixup set.
- A function with matching calling convention is changed to have the default convention, which is always a core element.
- A function with matching call-fixup is changed to have no call-fixup.
-