mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Namespace display options
This commit is contained in:
parent
05c3358fe4
commit
e339d91ffd
12 changed files with 129 additions and 75 deletions
|
@ -81,6 +81,7 @@ OptionDatabase::OptionDatabase(Architecture *g)
|
||||||
registerOption(new OptionToggleRule());
|
registerOption(new OptionToggleRule());
|
||||||
registerOption(new OptionAliasBlock());
|
registerOption(new OptionAliasBlock());
|
||||||
registerOption(new OptionMaxInstruction());
|
registerOption(new OptionMaxInstruction());
|
||||||
|
registerOption(new OptionNamespaceStrategy());
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionDatabase::~OptionDatabase(void)
|
OptionDatabase::~OptionDatabase(void)
|
||||||
|
@ -833,3 +834,23 @@ string OptionMaxInstruction::apply(Architecture *glb,const string &p1,const stri
|
||||||
glb->max_instructions = newMax;
|
glb->max_instructions = newMax;
|
||||||
return "Maximum instructions per function set";
|
return "Maximum instructions per function set";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \class OptionNamespaceStrategy
|
||||||
|
/// \brief How should namespace tokens be displayed
|
||||||
|
///
|
||||||
|
/// The first parameter gives the strategy identifier, mapping to PrintLanguage::namespace_strategy.
|
||||||
|
string OptionNamespaceStrategy::apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const
|
||||||
|
|
||||||
|
{
|
||||||
|
PrintLanguage::namespace_strategy strategy;
|
||||||
|
if (p1 == "minimal")
|
||||||
|
strategy = PrintLanguage::MINIMAL_NAMESPACES;
|
||||||
|
else if (p1 == "all")
|
||||||
|
strategy = PrintLanguage::ALL_NAMESPACES;
|
||||||
|
else if (p1 == "none")
|
||||||
|
strategy = PrintLanguage::NO_NAMESPACES;
|
||||||
|
else
|
||||||
|
throw ParseError("Must specify a valid strategy");
|
||||||
|
glb->print->setNamespaceStrategy(strategy);
|
||||||
|
return "Namespace strategy set";
|
||||||
|
}
|
||||||
|
|
|
@ -270,4 +270,10 @@ public:
|
||||||
virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const;
|
virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OptionNamespaceStrategy : public ArchOption {
|
||||||
|
public:
|
||||||
|
OptionNamespaceStrategy(void) { name = "namespacestrategy"; } ///< Constructor
|
||||||
|
virtual string apply(Architecture *glb,const string &p1,const string &p2,const string &p3) const;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -174,7 +174,17 @@ void PrintC::pushPrototypeInputs(const FuncProto *proto)
|
||||||
void PrintC::pushSymbolScope(const Symbol *symbol)
|
void PrintC::pushSymbolScope(const Symbol *symbol)
|
||||||
|
|
||||||
{
|
{
|
||||||
int4 scopedepth = symbol->getResolutionDepth(curscope);
|
int4 scopedepth;
|
||||||
|
if (namespc_strategy == MINIMAL_NAMESPACES)
|
||||||
|
scopedepth = symbol->getResolutionDepth(curscope);
|
||||||
|
else if (namespc_strategy == ALL_NAMESPACES) {
|
||||||
|
if (symbol->getScope() == curscope)
|
||||||
|
scopedepth = 0;
|
||||||
|
else
|
||||||
|
scopedepth = symbol->getResolutionDepth((const Scope *)0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scopedepth = 0;
|
||||||
if (scopedepth != 0) {
|
if (scopedepth != 0) {
|
||||||
vector<const Scope *> scopeList;
|
vector<const Scope *> scopeList;
|
||||||
const Scope *point = symbol->getScope();
|
const Scope *point = symbol->getScope();
|
||||||
|
@ -195,7 +205,17 @@ void PrintC::pushSymbolScope(const Symbol *symbol)
|
||||||
void PrintC::emitSymbolScope(const Symbol *symbol)
|
void PrintC::emitSymbolScope(const Symbol *symbol)
|
||||||
|
|
||||||
{
|
{
|
||||||
int4 scopedepth = symbol->getResolutionDepth(curscope);
|
int4 scopedepth;
|
||||||
|
if (namespc_strategy == MINIMAL_NAMESPACES)
|
||||||
|
scopedepth = symbol->getResolutionDepth(curscope);
|
||||||
|
else if (namespc_strategy == ALL_NAMESPACES) {
|
||||||
|
if (symbol->getScope() == curscope)
|
||||||
|
scopedepth = 0;
|
||||||
|
else
|
||||||
|
scopedepth = symbol->getResolutionDepth((const Scope *)0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
scopedepth = 0;
|
||||||
if (scopedepth != 0) {
|
if (scopedepth != 0) {
|
||||||
vector<const Scope *> scopeList;
|
vector<const Scope *> scopeList;
|
||||||
const Scope *point = symbol->getScope();
|
const Scope *point = symbol->getScope();
|
||||||
|
|
|
@ -575,6 +575,7 @@ void PrintLanguage::resetDefaultsInternal(void)
|
||||||
mods = 0;
|
mods = 0;
|
||||||
head_comment_type = Comment::header | Comment::warningheader;
|
head_comment_type = Comment::header | Comment::warningheader;
|
||||||
line_commentindent = 20;
|
line_commentindent = 20;
|
||||||
|
namespc_strategy = MINIMAL_NAMESPACES;
|
||||||
instr_comment_type = Comment::user2 | Comment::warning;
|
instr_comment_type = Comment::user2 | Comment::warning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,13 @@ public:
|
||||||
blanktoken ///< For anonymous types
|
blanktoken ///< For anonymous types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Strategies for displaying namespace tokens
|
||||||
|
enum namespace_strategy {
|
||||||
|
MINIMAL_NAMESPACES = 0, ///< (default) Print just enough namespace info to fully resolve symbol
|
||||||
|
NO_NAMESPACES = 1, ///< Never print namespace information
|
||||||
|
ALL_NAMESPACES = 2 ///< Always print all namespace information
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief An entry on the reverse polish notation (RPN) stack
|
/// \brief An entry on the reverse polish notation (RPN) stack
|
||||||
struct ReversePolish {
|
struct ReversePolish {
|
||||||
const OpToken *tok; ///< The operator token
|
const OpToken *tok; ///< The operator token
|
||||||
|
@ -245,6 +252,7 @@ protected:
|
||||||
uint4 mods; ///< Currently active printing modifications
|
uint4 mods; ///< Currently active printing modifications
|
||||||
uint4 instr_comment_type; ///< Type of instruction comments to display
|
uint4 instr_comment_type; ///< Type of instruction comments to display
|
||||||
uint4 head_comment_type; ///< Type of header comments to display
|
uint4 head_comment_type; ///< Type of header comments to display
|
||||||
|
namespace_strategy namespc_strategy; ///< How should namespace tokens be displayed
|
||||||
#ifdef CPUI_DEBUG
|
#ifdef CPUI_DEBUG
|
||||||
bool isStackEmpty(void) const { return (nodepend.empty()&&revpol.empty()); } ///< Return \b true if the RPN stack is empty
|
bool isStackEmpty(void) const { return (nodepend.empty()&&revpol.empty()); } ///< Return \b true if the RPN stack is empty
|
||||||
bool isModStackEmpty(void) const { return modstack.empty(); } ///< Return \b true if the printing modification stack is empty
|
bool isModStackEmpty(void) const { return modstack.empty(); } ///< Return \b true if the printing modification stack is empty
|
||||||
|
@ -412,6 +420,7 @@ public:
|
||||||
bool usecommentfill); ///< Establish comment delimiters for the language
|
bool usecommentfill); ///< Establish comment delimiters for the language
|
||||||
uint4 getInstructionComment(void) const { return instr_comment_type; } ///< Get the type of comments suitable within the body of a function
|
uint4 getInstructionComment(void) const { return instr_comment_type; } ///< Get the type of comments suitable within the body of a function
|
||||||
void setInstructionComment(uint4 val) { instr_comment_type = val; } ///< Set the type of comments suitable within the body of a function
|
void setInstructionComment(uint4 val) { instr_comment_type = val; } ///< Set the type of comments suitable within the body of a function
|
||||||
|
void setNamespaceStrategy(namespace_strategy strat) { namespc_strategy = strat; } ///< Set how namespace tokens are displayed
|
||||||
uint4 getHeaderComment(void) const { return head_comment_type; } ///< Get the type of comments suitable for a function header
|
uint4 getHeaderComment(void) const { return head_comment_type; } ///< Get the type of comments suitable for a function header
|
||||||
void setHeaderComment(uint4 val) { head_comment_type = val; } ///< Set the type of comments suitable for a function header
|
void setHeaderComment(uint4 val) { head_comment_type = val; } ///< Set the type of comments suitable for a function header
|
||||||
bool emitsXml(void) const { return emit->emitsXml(); } ///< Does the low-level emitter, emit XML markup
|
bool emitsXml(void) const { return emit->emitsXml(); } ///< Does the low-level emitter, emit XML markup
|
||||||
|
|
|
@ -31,7 +31,6 @@ import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.pcode.*;
|
import ghidra.program.model.pcode.*;
|
||||||
import ghidra.util.exception.CancelledException;
|
|
||||||
import ghidra.util.task.CancelledListener;
|
import ghidra.util.task.CancelledListener;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.xml.XmlPullParser;
|
import ghidra.xml.XmlPullParser;
|
||||||
|
@ -131,7 +130,7 @@ public class DecompInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if debug has been enabled for the current/next decompilation.
|
* @return true if debug has been enabled for the current/next decompilation.
|
||||||
*/
|
*/
|
||||||
public boolean debugEnabled() {
|
public boolean debugEnabled() {
|
||||||
return debug != null;
|
return debug != null;
|
||||||
|
@ -199,8 +198,8 @@ public class DecompInterface {
|
||||||
/**
|
/**
|
||||||
* This is the main routine for making sure that a decompiler
|
* This is the main routine for making sure that a decompiler
|
||||||
* process is active and that it is initialized properly
|
* process is active and that it is initialized properly
|
||||||
* @throws IOException
|
* @throws IOException for any problems with the pipe to the decompiler process
|
||||||
* @throws DecompileException
|
* @throws DecompileException for errors initializing decompiler options etc.
|
||||||
*/
|
*/
|
||||||
protected void initializeProcess() throws IOException, DecompileException {
|
protected void initializeProcess() throws IOException, DecompileException {
|
||||||
if (decompCallback == null) {
|
if (decompCallback == null) {
|
||||||
|
@ -233,7 +232,6 @@ public class DecompInterface {
|
||||||
}
|
}
|
||||||
if (xmlOptions != null) {
|
if (xmlOptions != null) {
|
||||||
decompProcess.setMaxResultSize(xmlOptions.getMaxPayloadMBytes());
|
decompProcess.setMaxResultSize(xmlOptions.getMaxPayloadMBytes());
|
||||||
decompProcess.setShowNamespace(xmlOptions.isDisplayNamespaces());
|
|
||||||
if (!decompProcess.sendCommand1Param("setOptions",
|
if (!decompProcess.sendCommand1Param("setOptions",
|
||||||
xmlOptions.getXML(this)).toString().equals("t")) {
|
xmlOptions.getXML(this)).toString().equals("t")) {
|
||||||
throw new IOException("Did not accept decompiler options");
|
throw new IOException("Did not accept decompiler options");
|
||||||
|
@ -590,7 +588,6 @@ public class DecompInterface {
|
||||||
try {
|
try {
|
||||||
verifyProcess();
|
verifyProcess();
|
||||||
decompProcess.setMaxResultSize(xmlOptions.getMaxPayloadMBytes());
|
decompProcess.setMaxResultSize(xmlOptions.getMaxPayloadMBytes());
|
||||||
decompProcess.setShowNamespace(xmlOptions.isDisplayNamespaces());
|
|
||||||
return decompProcess.sendCommand1Param("setOptions",
|
return decompProcess.sendCommand1Param("setOptions",
|
||||||
xmloptions.getXML(this)).toString().equals("t");
|
xmloptions.getXML(this)).toString().equals("t");
|
||||||
}
|
}
|
||||||
|
@ -701,8 +698,7 @@ public class DecompInterface {
|
||||||
|
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
return new DecompileResults(func, pcodelanguage, null, dtmanage, decompileMessage, null,
|
return new DecompileResults(func, pcodelanguage, null, dtmanage, decompileMessage, null,
|
||||||
DecompileProcess.DisposeState.DISPOSED_ON_CANCEL,
|
DecompileProcess.DisposeState.DISPOSED_ON_CANCEL);
|
||||||
false /* cancelled--doesn't matter */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -747,7 +743,7 @@ public class DecompInterface {
|
||||||
stream = res.getInputStream();
|
stream = res.getInputStream();
|
||||||
}
|
}
|
||||||
return new DecompileResults(func, pcodelanguage, compilerSpec, dtmanage, decompileMessage,
|
return new DecompileResults(func, pcodelanguage, compilerSpec, dtmanage, decompileMessage,
|
||||||
stream, processState, isDisplayNamespace());
|
stream, processState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -796,12 +792,4 @@ public class DecompInterface {
|
||||||
public CompilerSpec getCompilerSpec() {
|
public CompilerSpec getCompilerSpec() {
|
||||||
return compilerSpec;
|
return compilerSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDisplayNamespace() {
|
|
||||||
if (xmlOptions == null) {
|
|
||||||
return false; // not sure if this can happen
|
|
||||||
}
|
|
||||||
return xmlOptions.isDisplayNamespaces();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ public class DecompileCallback {
|
||||||
private PcodeDataTypeManager dtmanage;
|
private PcodeDataTypeManager dtmanage;
|
||||||
private Charset utf8Charset;
|
private Charset utf8Charset;
|
||||||
private String nativeMessage;
|
private String nativeMessage;
|
||||||
private boolean showNamespace;
|
|
||||||
|
|
||||||
private InstructionBlock lastPseudoInstructionBlock;
|
private InstructionBlock lastPseudoInstructionBlock;
|
||||||
private Disassembler pseudoDisassembler;
|
private Disassembler pseudoDisassembler;
|
||||||
|
@ -154,10 +153,6 @@ public class DecompileCallback {
|
||||||
nativeMessage = msg;
|
nativeMessage = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowNamespace(boolean showNamespace) {
|
|
||||||
this.showNamespace = showNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int readXMLSize(String addrxml) {
|
public synchronized int readXMLSize(String addrxml) {
|
||||||
int attrstart = addrxml.indexOf("size=\"");
|
int attrstart = addrxml.indexOf("size=\"");
|
||||||
if (attrstart >= 4) {
|
if (attrstart >= 4) {
|
||||||
|
@ -770,8 +765,7 @@ public class DecompileCallback {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
HighFunction hfunc =
|
HighFunction hfunc = new HighFunction(func, pcodelanguage, pcodecompilerspec, dtmanage);
|
||||||
new HighFunction(func, pcodelanguage, pcodecompilerspec, dtmanage, showNamespace);
|
|
||||||
|
|
||||||
int extrapop = getExtraPopOverride(func, addr);
|
int extrapop = getExtraPopOverride(func, addr);
|
||||||
hfunc.grabFromFunction(extrapop, false, (extrapop != default_extrapop));
|
hfunc.grabFromFunction(extrapop, false, (extrapop != default_extrapop));
|
||||||
|
@ -1012,7 +1006,7 @@ public class DecompileCallback {
|
||||||
long diff = addr.getOffset() - entry.getOffset();
|
long diff = addr.getOffset() - entry.getOffset();
|
||||||
if ((diff >= 0) && (diff < 8)) {
|
if ((diff >= 0) && (diff < 8)) {
|
||||||
HighFunction hfunc = new HighFunction(func, pcodelanguage, pcodecompilerspec,
|
HighFunction hfunc = new HighFunction(func, pcodelanguage, pcodecompilerspec,
|
||||||
dtmanage, showNamespace);
|
dtmanage);
|
||||||
|
|
||||||
int extrapop = getExtraPopOverride(func, addr);
|
int extrapop = getExtraPopOverride(func, addr);
|
||||||
hfunc.grabFromFunction(extrapop, includeDefaultNames,
|
hfunc.grabFromFunction(extrapop, includeDefaultNames,
|
||||||
|
|
|
@ -230,6 +230,35 @@ public class DecompileOptions {
|
||||||
private final static boolean COMMENTHEAD_OPTIONDEFAULT = true;
|
private final static boolean COMMENTHEAD_OPTIONDEFAULT = true;
|
||||||
private boolean commentHeadInclude;
|
private boolean commentHeadInclude;
|
||||||
|
|
||||||
|
public enum NamespaceStrategy {
|
||||||
|
Minimal("minimal", "Minimally"),
|
||||||
|
All("all", "Always"),
|
||||||
|
Never("none", "Never");
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
private String optionString;
|
||||||
|
|
||||||
|
private NamespaceStrategy(String optString, String label) {
|
||||||
|
this.label = label;
|
||||||
|
this.optionString = optString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOptionString() {
|
||||||
|
return optionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static String NAMESPACE_OPTIONSTRING = "Display.Display Namespaces";
|
||||||
|
private final static String NAMESPACE_OPTIONDESCRIPTION =
|
||||||
|
"Choose how/if namespace tokens should be displayed along with symbol names";
|
||||||
|
private final static NamespaceStrategy NAMESPACE_OPTIONDEFAULT = NamespaceStrategy.Minimal;
|
||||||
|
private NamespaceStrategy namespaceStrategy;
|
||||||
|
|
||||||
private final static String INTEGERFORMAT_OPTIONSTRING = "Display.Integer format";
|
private final static String INTEGERFORMAT_OPTIONSTRING = "Display.Integer format";
|
||||||
private final static String INTEGERFORMAT_OPTIONDESCRIPTION =
|
private final static String INTEGERFORMAT_OPTIONDESCRIPTION =
|
||||||
"Choose how to display integers: as hexadecimal, decimal, or best fit";
|
"Choose how to display integers: as hexadecimal, decimal, or best fit";
|
||||||
|
@ -317,13 +346,10 @@ public class DecompileOptions {
|
||||||
"Number of Decompiled Functions to Cache in the Decompile Window";
|
"Number of Decompiled Functions to Cache in the Decompile Window";
|
||||||
|
|
||||||
private final static String LINE_NUMBER_MSG = "Display.Display Line Numbers";
|
private final static String LINE_NUMBER_MSG = "Display.Display Line Numbers";
|
||||||
private final static String NAMESPACE_MSG = "Display.Display Namespaces";
|
|
||||||
private final static String DECOMPILE_TIMEOUT = "Decompiler Timeout (seconds)";
|
private final static String DECOMPILE_TIMEOUT = "Decompiler Timeout (seconds)";
|
||||||
private final static String PAYLOAD_LIMIT = "Decompiler Max-Payload (MBytes)";
|
private final static String PAYLOAD_LIMIT = "Decompiler Max-Payload (MBytes)";
|
||||||
private final static Boolean LINE_NUMBER_DEF = Boolean.TRUE;
|
private final static Boolean LINE_NUMBER_DEF = Boolean.TRUE;
|
||||||
private final static Boolean NAMESPACES_DEF = Boolean.FALSE;
|
|
||||||
private boolean displayLineNumbers;
|
private boolean displayLineNumbers;
|
||||||
private boolean displayNamespaces;
|
|
||||||
private int decompileTimeoutSeconds;
|
private int decompileTimeoutSeconds;
|
||||||
private int payloadLimitMBytes;
|
private int payloadLimitMBytes;
|
||||||
private int cachedResultsSize;
|
private int cachedResultsSize;
|
||||||
|
@ -354,6 +380,7 @@ public class DecompileOptions {
|
||||||
commentEOLInclude = COMMENTEOL_OPTIONDEFAULT;
|
commentEOLInclude = COMMENTEOL_OPTIONDEFAULT;
|
||||||
commentWARNInclude = COMMENTWARN_OPTIONDEFAULT;
|
commentWARNInclude = COMMENTWARN_OPTIONDEFAULT;
|
||||||
commentHeadInclude = COMMENTHEAD_OPTIONDEFAULT;
|
commentHeadInclude = COMMENTHEAD_OPTIONDEFAULT;
|
||||||
|
namespaceStrategy = NAMESPACE_OPTIONDEFAULT;
|
||||||
integerFormat = INTEGERFORMAT_OPTIONDEFAULT;
|
integerFormat = INTEGERFORMAT_OPTIONDEFAULT;
|
||||||
keywordColor = HIGHLIGHT_KEYWORD_DEF;
|
keywordColor = HIGHLIGHT_KEYWORD_DEF;
|
||||||
functionColor = HIGHLIGHT_FUNCTION_DEF;
|
functionColor = HIGHLIGHT_FUNCTION_DEF;
|
||||||
|
@ -367,7 +394,6 @@ public class DecompileOptions {
|
||||||
codeViewerBackgroundColor = CODE_VIEWER_BACKGROUND_COLOR;
|
codeViewerBackgroundColor = CODE_VIEWER_BACKGROUND_COLOR;
|
||||||
defaultFont = DEFAULT_FONT;
|
defaultFont = DEFAULT_FONT;
|
||||||
displayLineNumbers = LINE_NUMBER_DEF;
|
displayLineNumbers = LINE_NUMBER_DEF;
|
||||||
displayNamespaces = NAMESPACES_DEF;
|
|
||||||
displayLanguage = BasicCompilerSpec.DECOMPILER_OUTPUT_DEF;
|
displayLanguage = BasicCompilerSpec.DECOMPILER_OUTPUT_DEF;
|
||||||
protoEvalModel = "default";
|
protoEvalModel = "default";
|
||||||
decompileTimeoutSeconds = SUGGESTED_DECOMPILE_TIMEOUT_SECS;
|
decompileTimeoutSeconds = SUGGESTED_DECOMPILE_TIMEOUT_SECS;
|
||||||
|
@ -414,6 +440,7 @@ public class DecompileOptions {
|
||||||
commentPLATEInclude = opt.getBoolean(COMMENTPLATE_OPTIONSTRING, COMMENTPLATE_OPTIONDEFAULT);
|
commentPLATEInclude = opt.getBoolean(COMMENTPLATE_OPTIONSTRING, COMMENTPLATE_OPTIONDEFAULT);
|
||||||
commentWARNInclude = opt.getBoolean(COMMENTWARN_OPTIONSTRING, COMMENTWARN_OPTIONDEFAULT);
|
commentWARNInclude = opt.getBoolean(COMMENTWARN_OPTIONSTRING, COMMENTWARN_OPTIONDEFAULT);
|
||||||
commentHeadInclude = opt.getBoolean(COMMENTHEAD_OPTIONSTRING, COMMENTHEAD_OPTIONDEFAULT);
|
commentHeadInclude = opt.getBoolean(COMMENTHEAD_OPTIONSTRING, COMMENTHEAD_OPTIONDEFAULT);
|
||||||
|
namespaceStrategy = opt.getEnum(NAMESPACE_OPTIONSTRING, NAMESPACE_OPTIONDEFAULT);
|
||||||
integerFormat = opt.getEnum(INTEGERFORMAT_OPTIONSTRING, INTEGERFORMAT_OPTIONDEFAULT);
|
integerFormat = opt.getEnum(INTEGERFORMAT_OPTIONSTRING, INTEGERFORMAT_OPTIONDEFAULT);
|
||||||
keywordColor = opt.getColor(HIGHLIGHT_KEYWORD_MSG, HIGHLIGHT_KEYWORD_DEF);
|
keywordColor = opt.getColor(HIGHLIGHT_KEYWORD_MSG, HIGHLIGHT_KEYWORD_DEF);
|
||||||
typeColor = opt.getColor(HIGHLIGHT_TYPE_MSG, HIGHLIGHT_TYPE_DEF);
|
typeColor = opt.getColor(HIGHLIGHT_TYPE_MSG, HIGHLIGHT_TYPE_DEF);
|
||||||
|
@ -432,7 +459,6 @@ public class DecompileOptions {
|
||||||
defaultFont = SystemUtilities.adjustForFontSizeOverride(defaultFont);
|
defaultFont = SystemUtilities.adjustForFontSizeOverride(defaultFont);
|
||||||
defaultSearchHighlightColor = opt.getColor(SEARCH_HIGHLIGHT_MSG, SEARCH_HIGHLIGHT_DEF);
|
defaultSearchHighlightColor = opt.getColor(SEARCH_HIGHLIGHT_MSG, SEARCH_HIGHLIGHT_DEF);
|
||||||
displayLineNumbers = opt.getBoolean(LINE_NUMBER_MSG, LINE_NUMBER_DEF);
|
displayLineNumbers = opt.getBoolean(LINE_NUMBER_MSG, LINE_NUMBER_DEF);
|
||||||
displayNamespaces = opt.getBoolean(NAMESPACE_MSG, NAMESPACES_DEF);
|
|
||||||
decompileTimeoutSeconds = opt.getInt(DECOMPILE_TIMEOUT, SUGGESTED_DECOMPILE_TIMEOUT_SECS);
|
decompileTimeoutSeconds = opt.getInt(DECOMPILE_TIMEOUT, SUGGESTED_DECOMPILE_TIMEOUT_SECS);
|
||||||
payloadLimitMBytes = opt.getInt(PAYLOAD_LIMIT, SUGGESTED_MAX_PAYLOAD_BYTES);
|
payloadLimitMBytes = opt.getInt(PAYLOAD_LIMIT, SUGGESTED_MAX_PAYLOAD_BYTES);
|
||||||
cachedResultsSize = opt.getInt(CACHED_RESULTS_SIZE_MSG, SUGGESTED_CACHED_RESULTS_SIZE);
|
cachedResultsSize = opt.getInt(CACHED_RESULTS_SIZE_MSG, SUGGESTED_CACHED_RESULTS_SIZE);
|
||||||
|
@ -541,6 +567,8 @@ public class DecompileOptions {
|
||||||
COMMENTWARN_OPTIONDESCRIPTION);
|
COMMENTWARN_OPTIONDESCRIPTION);
|
||||||
opt.registerOption(COMMENTHEAD_OPTIONSTRING, COMMENTHEAD_OPTIONDEFAULT, help,
|
opt.registerOption(COMMENTHEAD_OPTIONSTRING, COMMENTHEAD_OPTIONDEFAULT, help,
|
||||||
COMMENTHEAD_OPTIONDESCRIPTION);
|
COMMENTHEAD_OPTIONDESCRIPTION);
|
||||||
|
opt.registerOption(NAMESPACE_OPTIONSTRING, NAMESPACE_OPTIONDEFAULT, help,
|
||||||
|
NAMESPACE_OPTIONDESCRIPTION);
|
||||||
opt.registerOption(INTEGERFORMAT_OPTIONSTRING, INTEGERFORMAT_OPTIONDEFAULT, help,
|
opt.registerOption(INTEGERFORMAT_OPTIONSTRING, INTEGERFORMAT_OPTIONDEFAULT, help,
|
||||||
INTEGERFORMAT_OPTIONDESCRIPTION);
|
INTEGERFORMAT_OPTIONDESCRIPTION);
|
||||||
opt.registerOption(HIGHLIGHT_KEYWORD_MSG, HIGHLIGHT_KEYWORD_DEF, help,
|
opt.registerOption(HIGHLIGHT_KEYWORD_MSG, HIGHLIGHT_KEYWORD_DEF, help,
|
||||||
|
@ -569,8 +597,6 @@ public class DecompileOptions {
|
||||||
"The color used to highlight matches using the Find Dialog.");
|
"The color used to highlight matches using the Find Dialog.");
|
||||||
opt.registerOption(LINE_NUMBER_MSG, LINE_NUMBER_DEF, help,
|
opt.registerOption(LINE_NUMBER_MSG, LINE_NUMBER_DEF, help,
|
||||||
"Toggle for displaying line numbers in the decompiler.");
|
"Toggle for displaying line numbers in the decompiler.");
|
||||||
opt.registerOption(NAMESPACE_MSG, NAMESPACES_DEF, help,
|
|
||||||
"Toggle for dislaying namespaces for functions.");
|
|
||||||
opt.registerOption(DECOMPILE_TIMEOUT, SUGGESTED_DECOMPILE_TIMEOUT_SECS, help,
|
opt.registerOption(DECOMPILE_TIMEOUT, SUGGESTED_DECOMPILE_TIMEOUT_SECS, help,
|
||||||
"The number of seconds to allow the decompiler to run before terminating the " +
|
"The number of seconds to allow the decompiler to run before terminating the " +
|
||||||
"decompiler.\nCurrently this does not affect the UI, which will run indefinitely. " +
|
"decompiler.\nCurrently this does not affect the UI, which will run indefinitely. " +
|
||||||
|
@ -654,6 +680,8 @@ public class DecompileOptions {
|
||||||
appendOption(buf, "commentheader", "header", commentHeadInclude ? "on" : "off", "");
|
appendOption(buf, "commentheader", "header", commentHeadInclude ? "on" : "off", "");
|
||||||
appendOption(buf, "commentheader", "warningheader", commentWARNInclude ? "on" : "off", "");
|
appendOption(buf, "commentheader", "warningheader", commentWARNInclude ? "on" : "off", "");
|
||||||
|
|
||||||
|
appendOption(buf, "namespacestrategy", namespaceStrategy.getOptionString(), "", "");
|
||||||
|
|
||||||
appendOption(buf, "integerformat", integerFormat.getOptionString(), "", "");
|
appendOption(buf, "integerformat", integerFormat.getOptionString(), "", "");
|
||||||
|
|
||||||
appendOption(buf, "protoeval", protoEvalModel, "", "");
|
appendOption(buf, "protoeval", protoEvalModel, "", "");
|
||||||
|
@ -793,10 +821,6 @@ public class DecompileOptions {
|
||||||
return displayLineNumbers;
|
return displayLineNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDisplayNamespaces() {
|
|
||||||
return displayNamespaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecompilerLanguage getDisplayLanguage() {
|
public DecompilerLanguage getDisplayLanguage() {
|
||||||
return displayLanguage;
|
return displayLanguage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,6 @@ public class DecompileProcess {
|
||||||
private int archId = -1; // architecture id for decomp process
|
private int archId = -1; // architecture id for decomp process
|
||||||
private DecompileCallback callback; // Callback interface for decompiler
|
private DecompileCallback callback; // Callback interface for decompiler
|
||||||
private int maxResultSizeMBYtes = 50; // maximum result size in MBytes to allow from decompiler
|
private int maxResultSizeMBYtes = 50; // maximum result size in MBytes to allow from decompiler
|
||||||
private boolean showNamespace; // whether to show namespaces for functions
|
|
||||||
|
|
||||||
public enum DisposeState {
|
public enum DisposeState {
|
||||||
NOT_DISPOSED, // Process was/is not disposed
|
NOT_DISPOSED, // Process was/is not disposed
|
||||||
|
@ -441,7 +440,6 @@ public class DecompileProcess {
|
||||||
String cspecxml, String tspecxml, String coretypesxml)
|
String cspecxml, String tspecxml, String coretypesxml)
|
||||||
throws IOException, DecompileException {
|
throws IOException, DecompileException {
|
||||||
callback = cback;
|
callback = cback;
|
||||||
callback.setShowNamespace(showNamespace);
|
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
String restring = null;
|
String restring = null;
|
||||||
|
@ -591,11 +589,6 @@ public class DecompileProcess {
|
||||||
this.maxResultSizeMBYtes = maxResultSizeMBytes;
|
this.maxResultSizeMBYtes = maxResultSizeMBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowNamespace(boolean showNamespace) {
|
|
||||||
this.showNamespace = showNamespace;
|
|
||||||
callback.setShowNamespace(showNamespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a command to the decompiler with one parameter and return the result
|
* Send a command to the decompiler with one parameter and return the result
|
||||||
* @param command is the command string
|
* @param command is the command string
|
||||||
|
|
|
@ -62,12 +62,10 @@ public class DecompileResults {
|
||||||
private ClangTokenGroup docroot; // C code parsed from XML
|
private ClangTokenGroup docroot; // C code parsed from XML
|
||||||
private String errMsg; // Error message from decompiler
|
private String errMsg; // Error message from decompiler
|
||||||
private DecompileProcess.DisposeState processState;
|
private DecompileProcess.DisposeState processState;
|
||||||
private boolean showNamespace; // include namespace when displaying function names
|
|
||||||
|
|
||||||
public DecompileResults(Function f, Language language, CompilerSpec compilerSpec,
|
public DecompileResults(Function f, Language language, CompilerSpec compilerSpec,
|
||||||
PcodeDataTypeManager d, String e, InputStream raw,
|
PcodeDataTypeManager d, String e, InputStream raw,
|
||||||
DecompileProcess.DisposeState processState,
|
DecompileProcess.DisposeState processState) {
|
||||||
boolean showNamespace) {
|
|
||||||
function = f;
|
function = f;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
this.compilerSpec = compilerSpec;
|
this.compilerSpec = compilerSpec;
|
||||||
|
@ -76,7 +74,6 @@ public class DecompileResults {
|
||||||
hfunc = null;
|
hfunc = null;
|
||||||
hparamid = null;
|
hparamid = null;
|
||||||
docroot = null;
|
docroot = null;
|
||||||
this.showNamespace = showNamespace;
|
|
||||||
//dumpResults(raw);
|
//dumpResults(raw);
|
||||||
parseRawString(raw);
|
parseRawString(raw);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +223,7 @@ public class DecompileResults {
|
||||||
XmlElement el = parser.peek();
|
XmlElement el = parser.peek();
|
||||||
if (el.getName().equals("function")) {
|
if (el.getName().equals("function")) {
|
||||||
if (hfunc == null) {
|
if (hfunc == null) {
|
||||||
hfunc = new HighFunction(function, language, compilerSpec, dtmanage, showNamespace);
|
hfunc = new HighFunction(function, language, compilerSpec, dtmanage);
|
||||||
hfunc.readXML(parser);
|
hfunc.readXML(parser);
|
||||||
}
|
}
|
||||||
else { // TODO: This is an ugly kludge to get around duplicate XML tag names
|
else { // TODO: This is an ugly kludge to get around duplicate XML tag names
|
||||||
|
@ -237,9 +234,7 @@ public class DecompileResults {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (el.getName().equals("parammeasures")) {
|
else if (el.getName().equals("parammeasures")) {
|
||||||
hparamid =
|
hparamid = new HighParamID(function, language, compilerSpec, dtmanage);
|
||||||
new HighParamID(function, language, compilerSpec, dtmanage,
|
|
||||||
showNamespace);
|
|
||||||
hparamid.readXML(parser);
|
hparamid.readXML(parser);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -51,22 +51,19 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
private GlobalSymbolMap globalSymbols;
|
private GlobalSymbolMap globalSymbols;
|
||||||
private List<JumpTable> jumpTables;
|
private List<JumpTable> jumpTables;
|
||||||
private List<DataTypeSymbol> protoOverrides;
|
private List<DataTypeSymbol> protoOverrides;
|
||||||
private boolean showNamespace = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param function function associated with the higher level function abstraction.
|
* @param function function associated with the higher level function abstraction.
|
||||||
* @param language description of the processor language of the function
|
* @param language description of the processor language of the function
|
||||||
* @param compilerSpec description of the compiler that produced the function
|
* @param compilerSpec description of the compiler that produced the function
|
||||||
* @param dtManager data type manager
|
* @param dtManager data type manager
|
||||||
* @param showNamespace true signals to print function names with their namespace
|
|
||||||
*/
|
*/
|
||||||
public HighFunction(Function function, Language language, CompilerSpec compilerSpec,
|
public HighFunction(Function function, Language language, CompilerSpec compilerSpec,
|
||||||
PcodeDataTypeManager dtManager, boolean showNamespace) {
|
PcodeDataTypeManager dtManager) {
|
||||||
super(function.getProgram().getAddressFactory(), dtManager);
|
super(function.getProgram().getAddressFactory(), dtManager);
|
||||||
func = function;
|
func = function;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
this.compilerSpec = compilerSpec;
|
this.compilerSpec = compilerSpec;
|
||||||
this.showNamespace = showNamespace;
|
|
||||||
localSymbols = new LocalSymbolMap(this, "stack");
|
localSymbols = new LocalSymbolMap(this, "stack");
|
||||||
globalSymbols = new GlobalSymbolMap(this);
|
globalSymbols = new GlobalSymbolMap(this);
|
||||||
proto = new FunctionPrototype(localSymbols, function);
|
proto = new FunctionPrototype(localSymbols, function);
|
||||||
|
@ -260,9 +257,9 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
public void readXML(XmlPullParser parser) throws PcodeXMLException {
|
public void readXML(XmlPullParser parser) throws PcodeXMLException {
|
||||||
XmlElement start = parser.start("function");
|
XmlElement start = parser.start("function");
|
||||||
String name = start.getAttribute("name");
|
String name = start.getAttribute("name");
|
||||||
if (!func.getName(showNamespace).equals(name)) {
|
if (!func.getName().equals(name)) {
|
||||||
throw new PcodeXMLException(
|
throw new PcodeXMLException(
|
||||||
"Function name mismatch: " + func.getName(showNamespace) + " + " + name);
|
"Function name mismatch: " + func.getName() + " + " + name);
|
||||||
}
|
}
|
||||||
while (!parser.peek().isEnd()) {
|
while (!parser.peek().isEnd()) {
|
||||||
XmlElement subel = parser.peek();
|
XmlElement subel = parser.peek();
|
||||||
|
@ -449,7 +446,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", id);
|
SpecXmlUtils.encodeUnsignedIntegerAttribute(resBuf, "id", id);
|
||||||
}
|
}
|
||||||
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", func.getName(showNamespace));
|
SpecXmlUtils.xmlEscapeAttribute(resBuf, "name", func.getName());
|
||||||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "size", size);
|
||||||
if (func.isInline()) {
|
if (func.isInline()) {
|
||||||
SpecXmlUtils.encodeBooleanAttribute(resBuf, "inline", true);
|
SpecXmlUtils.encodeBooleanAttribute(resBuf, "inline", true);
|
||||||
|
|
|
@ -48,23 +48,20 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
private Integer protoextrapop;
|
private Integer protoextrapop;
|
||||||
private List<ParamMeasure> inputlist = new ArrayList<ParamMeasure>();
|
private List<ParamMeasure> inputlist = new ArrayList<ParamMeasure>();
|
||||||
private List<ParamMeasure> outputlist = new ArrayList<ParamMeasure>();
|
private List<ParamMeasure> outputlist = new ArrayList<ParamMeasure>();
|
||||||
private boolean showNamespace = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param function function associated with the higher level function abstraction.
|
* @param function function associated with the higher level function abstraction.
|
||||||
* @param language language parser used to disassemble/get info on the language.
|
* @param language language parser used to disassemble/get info on the language.
|
||||||
* @param compilerSpec the compiler spec.
|
* @param compilerSpec the compiler spec.
|
||||||
* @param dtManager data type manager.
|
* @param dtManager data type manager.
|
||||||
* @param showNamespace true to show the parameters namespace.
|
|
||||||
*/
|
*/
|
||||||
public HighParamID(Function function, Language language, CompilerSpec compilerSpec,
|
public HighParamID(Function function, Language language, CompilerSpec compilerSpec,
|
||||||
PcodeDataTypeManager dtManager, boolean showNamespace) {
|
PcodeDataTypeManager dtManager) {
|
||||||
super(function.getProgram().getAddressFactory(), dtManager);
|
super(function.getProgram().getAddressFactory(), dtManager);
|
||||||
func = function;
|
func = function;
|
||||||
|
|
||||||
modelname = null;
|
modelname = null;
|
||||||
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
||||||
this.showNamespace = showNamespace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,8 +134,8 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
public void readXML(XmlPullParser parser) throws PcodeXMLException {
|
public void readXML(XmlPullParser parser) throws PcodeXMLException {
|
||||||
XmlElement start = parser.start("parammeasures");
|
XmlElement start = parser.start("parammeasures");
|
||||||
functionname = start.getAttribute("name");
|
functionname = start.getAttribute("name");
|
||||||
if (!func.getName(showNamespace).equals(functionname)) {
|
if (!func.getName().equals(functionname)) {
|
||||||
throw new PcodeXMLException("Function name mismatch: " + func.getName(showNamespace) +
|
throw new PcodeXMLException("Function name mismatch: " + func.getName() +
|
||||||
" + " + functionname);
|
" + " + functionname);
|
||||||
}
|
}
|
||||||
while (!parser.peek().isEnd()) {
|
while (!parser.peek().isEnd()) {
|
||||||
|
@ -157,10 +154,12 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
subel = parser.start("proto");
|
subel = parser.start("proto");
|
||||||
modelname = subel.getAttribute("model");
|
modelname = subel.getAttribute("model");
|
||||||
String val = subel.getAttribute("extrapop");
|
String val = subel.getAttribute("extrapop");
|
||||||
if (val.equals("unknown"))
|
if (val.equals("unknown")) {
|
||||||
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
protoextrapop = SpecXmlUtils.decodeInt(val);
|
protoextrapop = SpecXmlUtils.decodeInt(val);
|
||||||
|
}
|
||||||
parser.end(subel);
|
parser.end(subel);
|
||||||
}
|
}
|
||||||
else if (subel.getName().equals("input")) {
|
else if (subel.getName().equals("input")) {
|
||||||
|
@ -243,23 +242,28 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
try {
|
try {
|
||||||
//TODO: Currently, only storing one output, so looking for the best to report. When possible, change this to report all
|
//TODO: Currently, only storing one output, so looking for the best to report. When possible, change this to report all
|
||||||
int best_index = 0;
|
int best_index = 0;
|
||||||
if (getNumOutputs() > 1)
|
if (getNumOutputs() > 1) {
|
||||||
for (int i = 1; i < getNumOutputs(); i++)
|
for (int i = 1; i < getNumOutputs(); i++) {
|
||||||
if (getOutput(i).getRank() < getOutput(best_index).getRank()) {//TODO: create mirror of ranks on high side (instead of using numbers?)
|
if (getOutput(i).getRank() < getOutput(best_index).getRank()) {//TODO: create mirror of ranks on high side (instead of using numbers?)
|
||||||
best_index = i;
|
best_index = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (getNumOutputs() != 0) {
|
if (getNumOutputs() != 0) {
|
||||||
ParamMeasure pm = getOutput(best_index);
|
ParamMeasure pm = getOutput(best_index);
|
||||||
pm.getRank(); //TODO (maybe): this value is not used or stored on the java side at this point
|
pm.getRank(); //TODO (maybe): this value is not used or stored on the java side at this point
|
||||||
Varnode vn = pm.getVarnode();
|
Varnode vn = pm.getVarnode();
|
||||||
DataType dataType;
|
DataType dataType;
|
||||||
if (storeDataTypes)
|
if (storeDataTypes) {
|
||||||
dataType = pm.getDataType();
|
dataType = pm.getDataType();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
dataType = dtManage.findUndefined(vn.getSize());
|
dataType = dtManage.findUndefined(vn.getSize());
|
||||||
|
}
|
||||||
//Msg.debug(this, "func: " + func.getName() + " -- type: " + dataType.getName());
|
//Msg.debug(this, "func: " + func.getName() + " -- type: " + dataType.getName());
|
||||||
if (!(dataType == null || dataType instanceof VoidDataType))
|
if (!(dataType == null || dataType instanceof VoidDataType)) {
|
||||||
func.setReturn(dataType, buildStorage(vn), SourceType.ANALYSIS);
|
func.setReturn(dataType, buildStorage(vn), SourceType.ANALYSIS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InvalidInputException e) {
|
catch (InvalidInputException e) {
|
||||||
|
@ -282,10 +286,12 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
DataType dataType;
|
DataType dataType;
|
||||||
//Msg.debug(this, "function(" + func.getName() + ")--param size: " + vn.getSize() +
|
//Msg.debug(this, "function(" + func.getName() + ")--param size: " + vn.getSize() +
|
||||||
// "--type before store: " + pm.getDataType().getName());
|
// "--type before store: " + pm.getDataType().getName());
|
||||||
if (storeDataTypes)
|
if (storeDataTypes) {
|
||||||
dataType = pm.getDataType();
|
dataType = pm.getDataType();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
dataType = dtManage.findUndefined(vn.getSize());
|
dataType = dtManage.findUndefined(vn.getSize());
|
||||||
|
}
|
||||||
Variable v =
|
Variable v =
|
||||||
new ParameterImpl(null, dataType, buildStorage(vn),
|
new ParameterImpl(null, dataType, buildStorage(vn),
|
||||||
func.getProgram());
|
func.getProgram());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue