Skip to content

Commit

Permalink
pull from ghidra
Browse files Browse the repository at this point in the history
  • Loading branch information
cseagle committed Feb 21, 2020
1 parent c7103ce commit 25055e3
Show file tree
Hide file tree
Showing 43 changed files with 1,535 additions and 578 deletions.
2 changes: 1 addition & 1 deletion action.hh
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public:
warnings_given = 8 ///< Set if a warning for this rule has been given before
};
private:
friend class ActionPool;
friend struct ActionPool;
uint4 flags; ///< Properties enabled with \b this Rule
uint4 breakpoint; ///< Breakpoint(s) enabled for \b this Rule
string name; ///< Name of the Rule
Expand Down
2 changes: 1 addition & 1 deletion address.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ void Range::restoreXml(const Element *el,const AddrSpaceManager *manage)
s >> last;
}
else if (el->getAttributeName(i) == "name") {
const Translate *trans = manage->getDefaultSpace()->getTrans();
const Translate *trans = manage->getDefaultCodeSpace()->getTrans();
const VarnodeData &point(trans->getRegister(el->getAttributeValue(i)));
spc = point.space;
first = point.offset;
Expand Down
81 changes: 66 additions & 15 deletions architecture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ Architecture::Architecture(void)
aggressive_ext_trim = false;
readonlypropagate = false;
infer_pointers = true;
pointer_lowerbound = 0x1000;
funcptr_align = 0;
flowoptions = 0;
defaultfp = (ProtoModel *)0;
Expand Down Expand Up @@ -306,21 +305,19 @@ void Architecture::collectBehaviors(vector<OpBehavior *> &behave) const
}
}

/// A \b near pointer is some form of truncated pointer that needs
/// \e segment or other information to fully form an address.
/// This method searches for a user-defined segment op registered
/// for the space
/// for the given space.
/// \param spc is the address space to check
/// \return true if the space supports a segment operation
bool Architecture::hasNearPointers(AddrSpace *spc) const
/// \return the SegmentOp object or null
SegmentOp *Architecture::getSegmentOp(AddrSpace *spc) const

{
if (spc->getIndex() >= userops.numSegmentOps()) return false;
if (spc->getIndex() >= userops.numSegmentOps()) return (SegmentOp *)0;
SegmentOp *segdef = userops.getSegmentOp(spc->getIndex());
if (segdef == (SegmentOp *)0) return false;
if (segdef == (SegmentOp *)0) return (SegmentOp *)0;
if (segdef->getResolve().space != (AddrSpace *)0)
return true;
return false;
return segdef;
return (SegmentOp *)0;
}

/// Establish details of the prototype for a given function symbol
Expand Down Expand Up @@ -601,6 +598,12 @@ void Architecture::buildInstructions(DocumentStorage &store)
TypeOp::registerInstructions(inst,types,translate);
}

void Architecture::postSpecFile(void)

{
cacheAddrSpaceProperties();
}

/// Once the processor is known, the Translate object can be built and
/// fully initialized. Processor and compiler specific configuration is performed
/// \param store will hold parsed configuration information
Expand All @@ -615,8 +618,6 @@ void Architecture::restoreFromSpec(DocumentStorage &store)
insertSpace( new FspecSpace(this,translate,"fspec",numSpaces()));
insertSpace( new IopSpace(this,translate,"iop",numSpaces()));
insertSpace( new JoinSpace(this,translate,"join",numSpaces()));
if (translate->getDefaultSize() < 3) // For small architectures
pointer_lowerbound = 0x100; // assume constants are pointers starting at a much lower bound
userops.initialize(this);
if (translate->getAlignment() <= 8)
min_funcsymbol_size = translate->getAlignment();
Expand All @@ -642,6 +643,49 @@ void Architecture::initializeSegments(void)
}
}

/// Determine the minimum pointer size for the space and whether or not there are near pointers.
/// Set up an ordered list of inferable spaces (where constant pointers can be infered).
/// Inferable spaces include the default space and anything explicitly listed
/// in the cspec \<global> tag that is not a register space. An initial list of potential spaces is
/// passed in that needs to be ordered, filtered, and deduplicated.
void Architecture::cacheAddrSpaceProperties(void)

{
vector<AddrSpace *> copyList = inferPtrSpaces;
copyList.push_back(getDefaultCodeSpace()); // Make sure the default code space is present
copyList.push_back(getDefaultDataSpace()); // Make sure the default data space is present
inferPtrSpaces.clear();
sort(copyList.begin(),copyList.end(),AddrSpace::compareByIndex);
AddrSpace *lastSpace = (AddrSpace *)0;
for(int4 i=0;i<copyList.size();++i) {
AddrSpace *spc = copyList[i];
if (spc == lastSpace) continue;
lastSpace = spc;
if (spc->getDelay() == 0) continue; // Don't put in a register space
if (spc->getType() == IPTR_SPACEBASE) continue;
if (spc->isOtherSpace()) continue;
if (spc->isOverlay()) continue;
inferPtrSpaces.push_back(spc);
}

int4 defPos = -1;
for(int4 i=0;i<inferPtrSpaces.size();++i) {
AddrSpace *spc = inferPtrSpaces[i];
if (spc == getDefaultDataSpace()) // Make the default for inferring pointers the data space
defPos = i;
SegmentOp *segOp = getSegmentOp(spc);
if (segOp != (SegmentOp *)0) {
int4 val = segOp->getInnerSize();
markNearPointers(spc, val);
}
}
if (defPos > 0) { // Make sure the default space comes first
AddrSpace *tmp = inferPtrSpaces[0];
inferPtrSpaces[0] = inferPtrSpaces[defPos];
inferPtrSpaces[defPos] = tmp;
}
}

/// Recover information out of a \<rule> tag and build the new Rule object.
/// \param el is the XML element
void Architecture::parseDynamicRule(const Element *el)
Expand Down Expand Up @@ -749,7 +793,9 @@ void Architecture::parseGlobal(const Element *el)
for(iter=list.begin();iter!=list.end();++iter) {
Range range;
range.restoreXml(*iter,this);
symboltab->addRange(scope,range.getSpace(),range.getFirst(),range.getLast());
AddrSpace *spc = range.getSpace();
inferPtrSpaces.push_back(spc);
symboltab->addRange(scope,spc,range.getFirst(),range.getLast());
if (range.getSpace()->isOverlayBase()) { // If the address space is overlayed
// We need to duplicate the range being marked as global into the overlay space(s)
int4 num = numSpaces();
Expand Down Expand Up @@ -1040,6 +1086,13 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
else if (elname == "register_data") {
parseLaneSizes(*iter);
}
else if (elname == "data_space") {
const string &spaceName( (*iter)->getAttributeValue("space"));
AddrSpace *spc = getSpaceByName(spaceName);
if (spc == (AddrSpace *)0)
throw LowlevelError("Undefined space: "+spaceName);
setDefaultDataSpace(spc->getIndex());
}
else if (elname == "segmented_address") {
}
else if (elname == "default_symbols") {
Expand All @@ -1050,8 +1103,6 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
}
else if (elname == "properties") {
}
else if (elname == "data_space") {
}
else
throw LowlevelError("Unknown element in <processor_spec>: "+elname);
}
Expand Down
8 changes: 4 additions & 4 deletions architecture.hh
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public:
bool aggressive_ext_trim; ///< Aggressively trim inputs that look like they are sign extended
bool readonlypropagate; ///< true if readonly values should be treated as constants
bool infer_pointers; ///< True if we should infer pointers from constants that are likely addresses
uintb pointer_lowerbound; ///< Zero or lowest value that can be inferred as an address
vector<AddrSpace *> inferPtrSpaces; ///< Set of address spaces in which a pointer constant is inferable
int4 funcptr_align; ///< How many bits of alignment a function ptr has
uint4 flowoptions; ///< options passed to flow following engine
vector<Rule *> extra_pool_rules; ///< Extra rules that go in the main pool (cpu specific, experimental)
Expand Down Expand Up @@ -173,7 +173,7 @@ public:
void clearAnalysis(Funcdata *fd); ///< Clear analysis specific to a function
void readLoaderSymbols(void); ///< Read any symbols from loader into database
void collectBehaviors(vector<OpBehavior *> &behave) const; ///< Provide a list of OpBehavior objects
bool hasNearPointers(AddrSpace *spc) const; ///< Does the given address space support \e near pointers
SegmentOp *getSegmentOp(AddrSpace *spc) const; ///< Retrieve the \e segment op for the given space if any
void setPrototype(const PrototypePieces &pieces); ///< Set the prototype for a particular function
void setPrintLanguage(const string &nm); ///< Establish a particular output language
void globalify(void); ///< Mark \e all spaces as global
Expand Down Expand Up @@ -241,14 +241,14 @@ protected:
/// \param trans is the processor disassembly object
virtual void modifySpaces(Translate *trans)=0;

virtual void postSpecFile(void) {} ///< Let components initialize after Translate is built

virtual void postSpecFile(void); ///< Let components initialize after Translate is built

virtual void resolveArchitecture(void)=0; ///< Figure out the processor and compiler of the target executable

void restoreFromSpec(DocumentStorage &store); ///< Fully initialize the Translate object
void fillinReadOnlyFromLoader(void); ///< Load info about read-only sections
void initializeSegments(); ///< Set up segment resolvers
void cacheAddrSpaceProperties(void); ///< Calculate some frequently used space properties and cache them

void parseProcessorConfig(DocumentStorage &store); ///< Apply processor specific configuration
void parseCompilerConfig(DocumentStorage &store); ///< Apply compiler specific configuration
Expand Down
Loading

0 comments on commit 25055e3

Please sign in to comment.