mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 15:47:43 +08:00
GP-6985 Send back consistent function symbol or hole
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -43,7 +43,7 @@ void Action::issueWarning(Architecture *glb)
|
||||
{
|
||||
if ((flags&(rule_warnings_on|rule_warnings_given)) == rule_warnings_on) {
|
||||
flags |= rule_warnings_given;
|
||||
glb->printMessage("WARNING: Applied action "+name);
|
||||
glb->printWarning("Applied action "+name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ void Rule::issueWarning(Architecture *glb)
|
||||
{
|
||||
if ((flags&(warnings_on|warnings_given)) == warnings_on) {
|
||||
flags |= warnings_given;
|
||||
glb->printMessage("WARNING: Applied rule "+name);
|
||||
glb->printWarning("Applied rule "+name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,11 +862,11 @@ int4 ActionPool::processOp(PcodeOp *op,Funcdata &data)
|
||||
rule_index = 0;
|
||||
}
|
||||
}
|
||||
#ifdef CPUI_DEBUG
|
||||
else if (opc != op->code()) {
|
||||
data.getArch()->printMessage("ERROR: Rule " + rl->getName() + " changed op without returning result of 1!");
|
||||
opc = op->code();
|
||||
rule_index = 0;
|
||||
throw LowlevelError("ERROR: Rule " + rl->getName() + " changed op without returning result of 1!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
op_state++;
|
||||
rule_index = 0;
|
||||
|
||||
@@ -244,11 +244,11 @@ public:
|
||||
/// \return the description
|
||||
virtual string getDescription(void) const { return archid; }
|
||||
|
||||
/// \brief Print an error message to console
|
||||
/// \brief Print a warning message to console
|
||||
///
|
||||
/// Write the given message to whatever the registered error stream is
|
||||
/// Write the given message to a registered stream.
|
||||
/// \param message is the error message
|
||||
virtual void printMessage(const string &message) const=0;
|
||||
virtual void printWarning(const string &message) const=0;
|
||||
virtual void encode(Encoder &encoder) const; ///< Encode \b this architecture to a stream
|
||||
virtual void restoreXml(DocumentStorage &store); ///< Restore the Architecture state from XML documents
|
||||
virtual void nameFunction(const Address &addr,string &name) const; ///< Pick a default name for a function
|
||||
|
||||
@@ -2318,7 +2318,7 @@ int4 ActionReturnSplit::apply(Funcdata &data)
|
||||
count += 1;
|
||||
#ifdef BLOCKCONSISTENT_DEBUG
|
||||
if (!data.getBasicBlocks().isConsistent())
|
||||
data.getArch()->printMessage("Block structure is not consistent");
|
||||
data.getArch()->printWarning("Block structure is not consistent");
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1598,7 +1598,7 @@ Symbol *Scope::addMapSym(Decoder &decoder)
|
||||
SymbolEntry entry(sym);
|
||||
entry.decode(decoder);
|
||||
if (entry.isInvalid()) {
|
||||
glb->printMessage("WARNING: Throwing out symbol with invalid mapping: "+sym->getName());
|
||||
glb->printWarning("Throwing out symbol with invalid mapping: "+sym->getName());
|
||||
removeSymbol(sym);
|
||||
decoder.closeElement(elemId);
|
||||
return (Symbol *)0;
|
||||
@@ -1623,9 +1623,9 @@ FunctionSymbol *Scope::addFunction(const Address &addr,const string &nm)
|
||||
|
||||
SymbolEntry *overlap = queryContainer(addr,1,Address());
|
||||
if (overlap != (SymbolEntry *)0) {
|
||||
string errmsg = "WARNING: Function "+name;
|
||||
string errmsg = "Function "+nm;
|
||||
errmsg += " overlaps object: "+overlap->getSymbol()->getName();
|
||||
glb->printMessage(errmsg);
|
||||
glb->printWarning(errmsg);
|
||||
}
|
||||
sym = new FunctionSymbol(owner,nm,glb->min_funcsymbol_size);
|
||||
addSymbolInternal(sym);
|
||||
@@ -1672,9 +1672,12 @@ LabSymbol *Scope::addCodeLabel(const Address &addr,const string &nm)
|
||||
|
||||
SymbolEntry *overlap = queryContainer(addr,1,addr);
|
||||
if (overlap != (SymbolEntry *)0) {
|
||||
string errmsg = "WARNING: Codelabel "+nm;
|
||||
errmsg += " overlaps object: "+overlap->getSymbol()->getName();
|
||||
glb->printMessage(errmsg);
|
||||
FunctionSymbol *funcsym = dynamic_cast<FunctionSymbol *>(overlap->getSymbol());
|
||||
if (funcsym == (FunctionSymbol *)0) { // Overlapping with something that isn't a function body
|
||||
string errmsg = "Codelabel "+nm;
|
||||
errmsg += " overlaps object: "+overlap->getSymbol()->getName();
|
||||
glb->printWarning(errmsg);
|
||||
}
|
||||
}
|
||||
sym = new LabSymbol(owner,nm);
|
||||
addSymbolInternal(sym);
|
||||
|
||||
@@ -895,10 +895,13 @@ bool ArchitectureGhidra::getCPoolRef(const vector<uintb> &refs,Decoder &decoder)
|
||||
return readAll(sin,decoder);
|
||||
}
|
||||
|
||||
void ArchitectureGhidra::printMessage(const string &message) const
|
||||
void ArchitectureGhidra::printWarning(const string &message) const
|
||||
|
||||
{
|
||||
warnings += '\n'+message;
|
||||
sout.write("\000\000\001\022",4);
|
||||
sout << "Decompiler: " << message;
|
||||
sout.write("\000\000\001\023",4);
|
||||
sout.flush();
|
||||
}
|
||||
|
||||
/// \brief Construct given specification files and i/o streams
|
||||
|
||||
@@ -82,7 +82,6 @@ struct JavaError : public LowlevelError {
|
||||
class ArchitectureGhidra : public Architecture {
|
||||
istream &sin; ///< Input stream for interfacing with Ghidra
|
||||
ostream &sout; ///< Output stream for interfacing with Ghidra
|
||||
mutable string warnings; ///< Warnings accumulated by the decompiler
|
||||
string pspecxml; ///< XML pspec passed from Ghidra
|
||||
string cspecxml; ///< XML cspec passed from Ghidra
|
||||
string tspecxml; ///< Stripped down .sla file passed from Ghidra
|
||||
@@ -108,8 +107,6 @@ class ArchitectureGhidra : public Architecture {
|
||||
public:
|
||||
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
|
||||
bool getRegister(const string ®name,Decoder &decoder); ///< Retrieve a register description given a name
|
||||
string getRegisterName(const VarnodeData &vndata); ///< Retrieve a register name given its storage location
|
||||
bool getTrackedRegisters(const Address &addr,Decoder &decoder); ///< Retrieve \e tracked register values at the given address
|
||||
@@ -153,7 +150,7 @@ public:
|
||||
bool getSendParamMeasures(void) const { return sendParamMeasures; } ///< Get the current setting for emitting parameter info
|
||||
|
||||
void getStringData(vector<uint1> &buffer,const Address &addr,Datatype *ct,int4 maxBytes,bool &isTrunc);
|
||||
virtual void printMessage(const string &message) const;
|
||||
virtual void printWarning(const string &message) const;
|
||||
|
||||
static int4 readToAnyBurst(istream &s); ///< Read the next message protocol marker
|
||||
static bool readBoolStream(istream &s); ///< Read a boolean value from the client
|
||||
|
||||
@@ -99,18 +99,17 @@ void GhidraCommand::loadParameters(void)
|
||||
|
||||
if (ghidra == (ArchitectureGhidra *)0)
|
||||
throw JavaError("decompiler","No architecture registered with decompiler");
|
||||
ghidra->clearWarnings();
|
||||
}
|
||||
|
||||
/// This method sends any warnings accumulated during execution back, but it can be overloaded
|
||||
/// to send back any kind of information. Individual records are sent using
|
||||
/// the message protocol.
|
||||
void GhidraCommand::sendResult(void)
|
||||
/// This method can be overloaded to send back any kind of information as a string. Individual records
|
||||
/// are sent using the message protocol. If the command failed, a string describing the error is passed in.
|
||||
/// \param errorMsg is, if not empty, the error causing the commmand to fail
|
||||
void GhidraCommand::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
if (ghidra != (ArchitectureGhidra *)0) {
|
||||
sout.write("\000\000\001\020",4);
|
||||
sout << ghidra->getWarnings();
|
||||
sout << errorMsg;
|
||||
sout.write("\000\000\001\021",4);
|
||||
}
|
||||
}
|
||||
@@ -127,6 +126,7 @@ int4 GhidraCommand::doit(void)
|
||||
{
|
||||
status = 0;
|
||||
sout.write("\000\000\001\006",4); // Command response header
|
||||
string errorMsg;
|
||||
try {
|
||||
loadParameters();
|
||||
int4 type = ArchitectureGhidra::readToAnyBurst(sin);
|
||||
@@ -135,25 +135,19 @@ int4 GhidraCommand::doit(void)
|
||||
rawAction();
|
||||
}
|
||||
catch(DecoderError &err) {
|
||||
string errmsg;
|
||||
errmsg = "Marshaling error: " + err.explain;
|
||||
ghidra->printMessage( errmsg );
|
||||
errorMsg = "Marshaling error: " + err.explain;
|
||||
}
|
||||
catch(JavaError &err) {
|
||||
ArchitectureGhidra::passJavaException(sout,err.type,err.explain);
|
||||
return status; // Abort sending any results
|
||||
}
|
||||
catch(RecovError &err) {
|
||||
string errmsg;
|
||||
errmsg = "Recoverable Error: " + err.explain;
|
||||
ghidra->printMessage( errmsg );
|
||||
errorMsg = "Recoverable Error: " + err.explain;
|
||||
}
|
||||
catch(LowlevelError &err) {
|
||||
string errmsg;
|
||||
errmsg = "Low-level Error: " + err.explain;
|
||||
ghidra->printMessage( errmsg );
|
||||
errorMsg = "Low-level Error: " + err.explain;
|
||||
}
|
||||
sendResult();
|
||||
sendResult(errorMsg);
|
||||
sout.write("\000\000\001\007",4); // Command response closer
|
||||
sout.flush();
|
||||
return status;
|
||||
@@ -200,13 +194,13 @@ void RegisterProgram::rawAction(void)
|
||||
archid = open;
|
||||
}
|
||||
|
||||
void RegisterProgram::sendResult(void)
|
||||
void RegisterProgram::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
sout.write("\000\000\001\016",4);
|
||||
sout << dec << archid;
|
||||
sout.write("\000\000\001\017",4);
|
||||
GhidraCommand::sendResult();
|
||||
GhidraCommand::sendResult(errorMsg);
|
||||
}
|
||||
|
||||
void DeregisterProgram::loadParameters(void)
|
||||
@@ -225,7 +219,6 @@ void DeregisterProgram::loadParameters(void)
|
||||
|
||||
if (ghidra == (ArchitectureGhidra *)0)
|
||||
throw JavaError("decompiler","No architecture registered with decompiler");
|
||||
ghidra->clearWarnings();
|
||||
}
|
||||
|
||||
void DeregisterProgram::rawAction(void)
|
||||
@@ -250,13 +243,13 @@ void DeregisterProgram::rawAction(void)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
void DeregisterProgram::sendResult(void)
|
||||
void DeregisterProgram::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
sout.write("\000\000\001\016",4);
|
||||
sout << dec << res;
|
||||
sout.write("\000\000\001\017",4);
|
||||
GhidraCommand::sendResult();
|
||||
GhidraCommand::sendResult(errorMsg);
|
||||
}
|
||||
|
||||
void FlushNative::rawAction(void)
|
||||
@@ -272,13 +265,13 @@ void FlushNative::rawAction(void)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
void FlushNative::sendResult(void)
|
||||
void FlushNative::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
sout.write("\000\000\001\016",4);
|
||||
sout << dec << res;
|
||||
sout.write("\000\000\001\017",4);
|
||||
GhidraCommand::sendResult();
|
||||
GhidraCommand::sendResult(errorMsg);
|
||||
}
|
||||
|
||||
void DecompileAt::loadParameters(void)
|
||||
@@ -405,14 +398,14 @@ void SetAction::rawAction(void)
|
||||
res = true;
|
||||
}
|
||||
|
||||
void SetAction::sendResult(void)
|
||||
void SetAction::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
if (res)
|
||||
ArchitectureGhidra::writeStringStream(sout,"t");
|
||||
else
|
||||
ArchitectureGhidra::writeStringStream(sout,"f");
|
||||
GhidraCommand::sendResult();
|
||||
GhidraCommand::sendResult(errorMsg);
|
||||
}
|
||||
|
||||
void SetOptions::loadParameters(void)
|
||||
@@ -444,14 +437,14 @@ void SetOptions::rawAction(void)
|
||||
res = true;
|
||||
}
|
||||
|
||||
void SetOptions::sendResult(void)
|
||||
void SetOptions::sendResult(const string &errorMsg)
|
||||
|
||||
{
|
||||
if (res)
|
||||
ArchitectureGhidra::writeStringStream(sout,"t");
|
||||
else
|
||||
ArchitectureGhidra::writeStringStream(sout,"f");
|
||||
GhidraCommand::sendResult();
|
||||
GhidraCommand::sendResult(errorMsg);
|
||||
}
|
||||
|
||||
/// A command is read from the Ghidra client. The matching GhidraCommand object is
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -82,7 +82,7 @@ protected:
|
||||
ArchitectureGhidra *ghidra; ///< The Architecture on which to perform the command
|
||||
int4 status; ///< Meta-command to system (0=wait for next command, 1=terminate process)
|
||||
virtual void loadParameters(void); ///< Read parameters directing command execution
|
||||
virtual void sendResult(void); ///< Send results of the command (if any) back to the Ghidra client
|
||||
virtual void sendResult(const string &errorMsg); ///< Send back response to the command
|
||||
public:
|
||||
GhidraCommand(void) : sin(cin),sout(cout) {
|
||||
ghidra = (ArchitectureGhidra *)0;
|
||||
@@ -112,7 +112,7 @@ class RegisterProgram : public GhidraCommand {
|
||||
string tspec; ///< Configuration (address-spaces) for the Translate object
|
||||
string corespec; ///< A description of core data-types for the TypeFactory object
|
||||
virtual void loadParameters(void);
|
||||
virtual void sendResult(void);
|
||||
virtual void sendResult(const string &errorMsg);
|
||||
public:
|
||||
int4 archid; ///< Resulting id of the program to send back
|
||||
virtual void rawAction(void);
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
class DeregisterProgram : public GhidraCommand {
|
||||
int4 inid; ///< The id of the Architecture being terminated
|
||||
virtual void loadParameters(void);
|
||||
virtual void sendResult(void);
|
||||
virtual void sendResult(const string &errorMsg);
|
||||
public:
|
||||
int4 res; ///< The meta-command being issued to send back
|
||||
virtual void rawAction(void);
|
||||
@@ -140,7 +140,7 @@ public:
|
||||
/// (re)fetch any symbols as needed.
|
||||
/// The command expects a single string parameter encoding the id of the program to flush.
|
||||
class FlushNative : public GhidraCommand {
|
||||
virtual void sendResult(void);
|
||||
virtual void sendResult(const string &errorMsg);
|
||||
public:
|
||||
int4 res; ///< Success status returned to the client (0=success)
|
||||
virtual void rawAction(void);
|
||||
@@ -211,7 +211,7 @@ class SetAction : public GhidraCommand {
|
||||
string actionstring; ///< The \e root Action to switch to
|
||||
string printstring; ///< The \e printing output configuration to toggle
|
||||
virtual void loadParameters(void);
|
||||
virtual void sendResult(void);
|
||||
virtual void sendResult(const string &errorMsg);
|
||||
public:
|
||||
bool res; ///< Set to \b true if the configuration action was successful
|
||||
virtual void rawAction(void);
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
class SetOptions : public GhidraCommand {
|
||||
Decoder *decoder; ///< The \<optionslist> decoder
|
||||
virtual void loadParameters(void);
|
||||
virtual void sendResult(void);
|
||||
virtual void sendResult(const string &errorMsg);
|
||||
public:
|
||||
bool res; ///< Set to \b true if the option change succeeded
|
||||
SetOptions(void) { decoder = (Decoder *)0; res = false; } ///< Constructor
|
||||
|
||||
@@ -342,7 +342,7 @@ void SleighArchitecture::resolveArchitecture(void)
|
||||
if (description[i].getId() == baseid) {
|
||||
languageindex = i;
|
||||
if (description[i].isDeprecated())
|
||||
printMessage("WARNING: Language "+baseid+" is deprecated");
|
||||
printWarning("Language "+baseid+" is deprecated");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -476,6 +476,12 @@ void SleighArchitecture::restoreXmlHeader(const Element *el)
|
||||
target = el->getAttributeValue("target");
|
||||
}
|
||||
|
||||
void SleighArchitecture::printWarning(const string &message) const
|
||||
|
||||
{
|
||||
*errorstream << "WARNING: " << message << endl;
|
||||
}
|
||||
|
||||
/// Given an architecture target string try to recover an
|
||||
/// appropriate processor name for use in a normalized \e language \e id.
|
||||
/// \param nm is the given target string
|
||||
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
const string &getTarget(void) const { return target; } ///< Get the \e language \e id of the active processor
|
||||
void encodeHeader(Encoder &encoder) const; ///< Encode basic attributes of the active executable
|
||||
void restoreXmlHeader(const Element *el); ///< Restore from basic attributes of an executable
|
||||
virtual void printMessage(const string &message) const { *errorstream << message << endl; }
|
||||
virtual void printWarning(const string &message) const;
|
||||
virtual ~SleighArchitecture(void);
|
||||
virtual string getDescription(void) const;
|
||||
|
||||
|
||||
+41
-47
File diff suppressed because it is too large
Load Diff
+32
-26
@@ -50,6 +50,8 @@ public class DecompileCallback {
|
||||
|
||||
public final static int MAX_SYMBOL_COUNT = 16;
|
||||
|
||||
public final static int MAX_FUNCTION_OFFCUT = 8; // Maximum distance from function entry point where a query still returns the HighFunctionSymbol
|
||||
|
||||
/**
|
||||
* Data returned for a query about strings
|
||||
*/
|
||||
@@ -79,7 +81,7 @@ public class DecompileCallback {
|
||||
private AddressFactory addrfactory;
|
||||
private ConstantPool cpool;
|
||||
private PcodeDataTypeManager dtmanage;
|
||||
private String nativeMessage;
|
||||
private String errorMessage;
|
||||
|
||||
private InstructionBlock lastPseudoInstructionBlock;
|
||||
private Disassembler pseudoDisassembler;
|
||||
@@ -94,7 +96,7 @@ public class DecompileCallback {
|
||||
dtmanage = dt;
|
||||
default_extrapop = pcodecompilerspec.getDefaultCallingConvention().getExtrapop();
|
||||
cpool = null;
|
||||
nativeMessage = null;
|
||||
errorMessage = "";
|
||||
debug = null;
|
||||
}
|
||||
|
||||
@@ -116,7 +118,7 @@ public class DecompileCallback {
|
||||
if (debug != null) {
|
||||
debug.setPcodeDataTypeManager(dtmanage);
|
||||
}
|
||||
nativeMessage = null; // Clear last message
|
||||
errorMessage = ""; // Clear last message
|
||||
lastPseudoInstructionBlock = null;
|
||||
if (pseudoDisassembler != null) {
|
||||
pseudoDisassembler.resetDisassemblerContext();
|
||||
@@ -124,19 +126,19 @@ public class DecompileCallback {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last message from the decompiler
|
||||
* @return the last error message from the decompiler, or an empty string
|
||||
*/
|
||||
public String getNativeMessage() {
|
||||
return nativeMessage;
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache a message returned by the decompiler process
|
||||
* Cache an error message returned by the decompiler process
|
||||
*
|
||||
* @param msg is the message
|
||||
*/
|
||||
void setNativeMessage(String msg) {
|
||||
nativeMessage = msg;
|
||||
void setErrorMessage(String msg) {
|
||||
errorMessage = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -893,9 +895,14 @@ public class DecompileCallback {
|
||||
private void encodeFunction(Encoder encoder, Function func, Address addr,
|
||||
boolean includeDefaultNames) throws IOException {
|
||||
Address entry = func.getEntryPoint();
|
||||
if (entry.getAddressSpace().equals(addr.getAddressSpace())) {
|
||||
Address endHole = addr; // If all else fails, return hole [addr,addr]
|
||||
AddressRange range = func.getBody().getRangeContaining(addr);
|
||||
if (range != null && range.contains(entry)) {
|
||||
long diff = addr.getOffset() - entry.getOffset();
|
||||
if ((diff >= 0) && (diff < 8)) {
|
||||
if (diff < 0) {
|
||||
endHole = entry.subtract(1); // Return hole [addr,entry)
|
||||
}
|
||||
else if (diff < MAX_FUNCTION_OFFCUT) {
|
||||
HighFunction hfunc =
|
||||
new HighFunction(func, pcodelanguage, pcodecompilerspec, dtmanage);
|
||||
|
||||
@@ -903,7 +910,14 @@ public class DecompileCallback {
|
||||
hfunc.grabFromFunction(extrapop, includeDefaultNames,
|
||||
(extrapop != default_extrapop));
|
||||
|
||||
HighSymbol functionSymbol = new HighFunctionSymbol(entry, (int) (diff + 1), hfunc);
|
||||
long size = range.getMaxAddress().getOffset() - entry.getOffset() + 1;
|
||||
if (size <= 0) {
|
||||
size = 1;
|
||||
}
|
||||
else if (size > MAX_FUNCTION_OFFCUT) {
|
||||
size = MAX_FUNCTION_OFFCUT;
|
||||
}
|
||||
HighSymbol functionSymbol = new HighFunctionSymbol(entry, (int) size, hfunc);
|
||||
Namespace namespc = functionSymbol.getNamespace();
|
||||
if (debug != null) {
|
||||
debug.getFNTypes(hfunc);
|
||||
@@ -912,23 +926,15 @@ public class DecompileCallback {
|
||||
encodeResult(encoder, functionSymbol, namespc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AddressRangeIterator iter = func.getBody().getAddressRanges();
|
||||
while (iter.hasNext()) {
|
||||
AddressRange range = iter.next();
|
||||
if (range.contains(addr)) {
|
||||
Address first = range.getMinAddress();
|
||||
Address last = range.getMaxAddress();
|
||||
encodeHole(encoder, first.getAddressSpace(), first.getUnsignedOffset(),
|
||||
last.getUnsignedOffset(), MutabilitySettingsDefinition.CONSTANT);
|
||||
return;
|
||||
else {
|
||||
endHole = range.getMaxAddress();
|
||||
}
|
||||
}
|
||||
// There is probably some sort of error, just return a block
|
||||
// containing the single queried address
|
||||
else if (range != null) {
|
||||
endHole = range.getMaxAddress();
|
||||
}
|
||||
encodeHole(encoder, addr.getAddressSpace(), addr.getUnsignedOffset(),
|
||||
addr.getUnsignedOffset(), MutabilitySettingsDefinition.CONSTANT);
|
||||
endHole.getUnsignedOffset(), MutabilitySettingsDefinition.CONSTANT);
|
||||
}
|
||||
|
||||
private int getExtraPopOverride(Function func, Address addr) {
|
||||
|
||||
+18
-4
@@ -304,6 +304,17 @@ public class DecompileProcess {
|
||||
throw new DecompileException(type, message);
|
||||
}
|
||||
|
||||
private void generateWarning() throws IOException {
|
||||
stringDecoder.open(1 << 16, programSource);
|
||||
int type = readToBuffer(stringDecoder);
|
||||
if (type != 19) {
|
||||
throw new IOException("GHIDRA/decompiler alignment error");
|
||||
}
|
||||
stringDecoder.endIngest();
|
||||
Msg.warn(this, stringDecoder.toString());
|
||||
stringDecoder.clear();
|
||||
}
|
||||
|
||||
private void readResponse(ByteIngest mainResponse) throws IOException, DecompileException {
|
||||
mainResponse.clear();
|
||||
readToResponse();
|
||||
@@ -420,21 +431,24 @@ public class DecompileProcess {
|
||||
currentResponse.endIngest();
|
||||
currentResponse = null; // Reset current buffer as a native message may follow
|
||||
break;
|
||||
case 16: // Beginning of any native message from the decompiler
|
||||
if (currentResponse != null) { // Beginning of native message before end of main response
|
||||
case 16: // Beginning of any error message from the decompiler
|
||||
if (currentResponse != null) { // If error message comes before end of main response
|
||||
currentResponse.clear(); // Don't try to parse main response
|
||||
}
|
||||
currentResponse = stringDecoder;
|
||||
currentResponse.open(1 << 20, programSource);
|
||||
break;
|
||||
case 17: // End of the native message from the decompiler
|
||||
case 17: // End of the error message from the decompiler
|
||||
if (currentResponse == null) {
|
||||
throw new IOException("Mismatched message header");
|
||||
}
|
||||
currentResponse.endIngest();
|
||||
callback.setNativeMessage(currentResponse.toString());
|
||||
callback.setErrorMessage(currentResponse.toString());
|
||||
currentResponse = null;
|
||||
break;
|
||||
case 18: // Beginning of informational message
|
||||
generateWarning();
|
||||
break;
|
||||
default:
|
||||
throw new IOException("GHIDRA/decompiler alignment error");
|
||||
|
||||
|
||||
+3
-7
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -155,11 +155,7 @@ public class DecompileResults {
|
||||
|
||||
/**
|
||||
* Return any error message associated with the
|
||||
* decompilation producing these results. Generally,
|
||||
* there will only be an error if the decompilation was
|
||||
* aborted for some reason, but there could conceivably
|
||||
* be warnings obtainable via this method, even if the
|
||||
* decompilation did complete.
|
||||
* decompilation producing these results.
|
||||
* @return any error message associated with these results
|
||||
*/
|
||||
public String getErrorMessage() {
|
||||
|
||||
Reference in New Issue
Block a user