Skip to content

Commit

Permalink
Add dyninstAPI/src/function.C
Browse files Browse the repository at this point in the history
  • Loading branch information
hainest committed Apr 3, 2024
1 parent 784ccdf commit 400c252
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 39 deletions.
38 changes: 33 additions & 5 deletions docs/dyninstAPI/developer/function.h.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ function.h
.. cpp:function:: func_instance(const func_instance *parent, mapped_module *child_mod)
.. cpp:function:: ~func_instance()

We don't delete blocks, since they're shared between functions. We *do* delete context instPoints,
though Except that should get taken care of normally since the structures are static.

......

.. rubric::
Expand All @@ -36,9 +39,13 @@ function.h
Debuggering functions

.. cpp:function:: void debugPrint() const

warning: doesn't (and can't) force initialization of lazily-built
data structures because this function is declared to be constant

.. cpp:function:: void addSymTabName(const std::string name, bool isPrimary = false)

Don't make the std::string a reference we want a copy.
Add to mapped_object if a "new" name (true return from internal).

.. cpp:function:: void addPrettyName(const std::string name, bool isPrimary = false)
.. cpp:function:: Dyninst::Address getPtrAddress() const
Expand Down Expand Up @@ -72,7 +79,9 @@ function.h

.. cpp:function:: block_instance *setNewEntry(block_instance *def, std::set<block_instance *> &deadBlocks)

Parsing because things looked weird.
The original entry block is gone, we choose a new entry block from the function, whichever non-dead
block we can find that has no intraprocedural incoming edges. If there's no obvious block to
choose, we stick with the default block.

.. cpp:function:: bool isSignalHandler()

Expand All @@ -82,11 +91,18 @@ function.h
.. cpp:function:: Dyninst::Address getHandlerFaultAddrAddr()
.. cpp:function:: void setHandlerFaultAddr(Dyninst::Address fa)
.. cpp:function:: void setHandlerFaultAddrAddr(Dyninst::Address faa, bool set)

Sets the address in the structure at which the fault instruction's address is stored if "set" is
true. Accesses the fault address and translates it back to an original address if it corresponds to
relocated code in the Dyninst heap

.. cpp:function:: void triggerModified()
.. cpp:function:: block_instance *getBlockByEntry(const Dyninst::Address addr)
.. cpp:function:: bool getBlocks(const Dyninst::Address addr, std::set<block_instance *> &blks)

get all blocks that contain the given address
Return in ``blks`` all blocks that have an instruction starting at ``addr``.

If there are none, return all blocks containing ``addr``.

.. cpp:function:: block_instance *getBlock(const Dyninst::Address addr)

Expand Down Expand Up @@ -126,10 +142,16 @@ function.h
function), but the underlying parse_block records the sharing status. So dodge through to the image layer
and find out that info. Returns true if such functions exist.

Dig down to the low-level block of b, find the low-level functions that share it, and map up to
int-level functions and add them to the funcs list.

.. cpp:function:: bool getSharingFuncs(std::set<func_instance *> &funcs)

The same, but for any function that overlaps with any of our basic blocks.

Find sharing functions via checking all basic blocks. We might be able to check only exit points;
but we definitely need to check _all_ exits so for now we're checking everything.

OPTIMIZATION: we're not checking all blocks, only an exit point this _should_ work :) but needs to change
if we ever do flow-sensitive parsing

Expand All @@ -153,7 +175,12 @@ function.h
Fill the <callers> vector with pointers to the statically-determined list of functions that call this function.

.. cpp:function:: template <class OutputIterator> void getCallerFuncs(OutputIterator result)
.. cpp:function:: bool getLiveCallerBlocks(const std::set<block_instance *> &deadBlocks, const std::list<func_instance *> &deadFuncs, std::map<Dyninst::Address, vector<block_instance *>> &output_stubs)
.. cpp:function:: bool getLiveCallerBlocks(const std::set<block_instance *> &deadBlocks,\
const std::list<func_instance *> &deadFuncs, std::map<Dyninst::Address,\
vector<block_instance *>> &output_stubs)

Get caller blocks that aren't in deadBlocks

.. cpp:function:: bool savesReturnAddr() const
.. cpp:function:: callType func_instance::getCallingConvention()

Expand All @@ -164,7 +191,8 @@ function.h
.. cpp:function:: void getReachableBlocks(const std::set<block_instance *> &exceptBlocks, const std::list<block_instance *> &seedBlocks, std::set<block_instance *> &reachBlocks)
.. cpp:function:: bool consistency() const

So we can assert(consistency())
- Check for ``1:1`` block relationship in the block list and block map
- Check that all instPoints are in the correct block.

.. cpp:function:: instPoint *funcEntryPoint(bool create)

Expand Down
34 changes: 0 additions & 34 deletions dyninstAPI/src/function.C
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,13 @@ func_instance::func_instance(const func_instance *parFunc,
}

func_instance::~func_instance() {
// We don't delete blocks, since they're shared between functions
// We _do_ delete context instPoints, though
// Except that should get taken care of normally since the
// structures are static.
for (unsigned i = 0; i < parallelRegions_.size(); i++)
delete parallelRegions_[i];
if (wrapperSym_ != NULL) {
delete wrapperSym_;
}
}

// the original entry block is gone, we choose a new entry block from the
// function, whichever non-dead block we can find that has no intraprocedural
// incoming edges. If there's no obvious block to choose, we stick with the
// default block
block_instance * func_instance::setNewEntry(block_instance *def,
std::set<block_instance*> &deadBlocks)
{
Expand Down Expand Up @@ -225,10 +217,6 @@ void func_instance::setHandlerFaultAddr(Address fa) {
handlerFaultAddr_ = fa;
}

// Sets the address in the structure at which the fault instruction's
// address is stored if "set" is true. Accesses the fault address and
// translates it back to an original address if it corresponds to
// relocated code in the Dyninst heap
void func_instance::setHandlerFaultAddrAddr(Address faa, bool set) {
if (set) {
// save the faultAddrAddr
Expand Down Expand Up @@ -370,8 +358,6 @@ unsigned func_instance::getNumDynamicCalls()
}


// warning: doesn't (and can't) force initialization of lazily-built
// data structures because this function is declared to be constant
void func_instance::debugPrint() const {
fprintf(stderr, "Function debug dump (%p):\n", (const void*)this);
fprintf(stderr, " Symbol table names:\n");
Expand Down Expand Up @@ -407,8 +393,6 @@ void func_instance::debugPrint() const {
}
}

// Add to internal
// Add to mapped_object if a "new" name (true return from internal)
void func_instance::addSymTabName(const std::string name, bool isPrimary) {
if (ifunc()->addSymTabName(name, isPrimary))
obj()->addFunctionName(this, name, obj()->allFunctionsByMangledName);
Expand All @@ -419,9 +403,6 @@ void func_instance::addPrettyName(const std::string name, bool isPrimary) {
obj()->addFunctionName(this, name, obj()->allFunctionsByPrettyName);
}

// Dig down to the low-level block of b, find the low-level functions
// that share it, and map up to int-level functions and add them
// to the funcs list.
bool func_instance::getSharingFuncs(block_instance *b,
std::set<func_instance *> & funcs)
{
Expand All @@ -444,10 +425,6 @@ bool func_instance::getSharingFuncs(block_instance *b,
return ret;
}

// Find sharing functions via checking all basic blocks. We might be
// able to check only exit points; but we definitely need to check _all_
// exits so for now we're checking everything.

bool func_instance::getSharingFuncs(std::set<func_instance *> &funcs) {
bool ret = false;

Expand Down Expand Up @@ -528,11 +505,6 @@ const std::vector< int_parRegion* > &func_instance::parRegions()
}

bool func_instance::consistency() const {
// 1) Check for 1:1 block relationship in
// the block list and block map
// 2) Check that all instPoints are in the
// correct block.

auto img_blocks = ifunc()->blocks();
assert(ifunc()->num_blocks() == all_blocks_.size());
for (auto iter = img_blocks.begin();
Expand Down Expand Up @@ -586,8 +558,6 @@ block_instance *func_instance::getBlockByEntry(const Address addr) {
}


// get all blocks that have an instruction starting at addr, or if
// there are none, return all blocks containing addr
bool func_instance::getBlocks(const Address addr, set<block_instance*> &blks) {
set<block_instance*> objblks;
obj()->findBlocksByAddr(addr, objblks);
Expand Down Expand Up @@ -675,7 +645,6 @@ Symbol *func_instance::getWrapperSymbol() {

Symbol *func_instance::getRelocSymbol() {
// there should be only one...
// HIGHLANDER!

// find the Symbol corresponding to the func_instance
std::vector<Symbol *> syms;
Expand Down Expand Up @@ -721,8 +690,6 @@ void func_instance::createWrapperSymbol(Address entry, std::string name) {

}

/* PatchAPI stuffs */

instPoint *func_instance::funcEntryPoint(bool create) {
// Lookup the cached points
instPoint *p = IPCONV(proc()->mgr()->findPoint(Location::Function(this), Point::FuncEntry, create));
Expand Down Expand Up @@ -859,7 +826,6 @@ void func_instance::markModified() {
proc()->addModifiedFunction(this);
}

// get caller blocks that aren't in deadBlocks
bool func_instance::getLiveCallerBlocks
(const std::set<block_instance*> &deadBlocks,
const std::list<func_instance*> &deadFuncs,
Expand Down

0 comments on commit 400c252

Please sign in to comment.