Skip to content

Commit

Permalink
Lookup functions in the binding table directly (#1337)
Browse files Browse the repository at this point in the history
instead of making multiple redundant copies of it. Copying and making
a map out of the table incurs a significant overhead.
  • Loading branch information
Maetveis committed Dec 15, 2022
1 parent 3937542 commit 42612b4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 28 deletions.
32 changes: 4 additions & 28 deletions dyninstAPI/src/unix.C
Original file line number Diff line number Diff line change
Expand Up @@ -743,45 +743,21 @@ func_instance *block_instance::callee() {

// get the relocation information for this image
Symtab *sym = obj()->parse_img()->getObject();
std::vector<relocationEntry> fbt;
if (!sym->getFuncBindingTable(fbt)) {
return NULL;
}


/**
* Object files and static binaries will not have a function binding table
* because the function binding table holds relocations used by the dynamic
* linker
*/
if (!fbt.size() && !sym->isStaticBinary() &&
sym->getObjectType() != obj_RelocatableFile )
{
fprintf(stderr, "%s[%d]: WARN: zero func bindings\n", FILE__, __LINE__);
}

std::map<Address, std::string> pltFuncs;
obj()->parse_img()->getPltFuncs(pltFuncs);

// find the target address in the list of relocationEntries
if (pltFuncs.find(target_addr) != pltFuncs.end()) {
relocationEntry function_binding;
if(sym->findPltEntryByTarget(target_addr, function_binding)) {
Address base_addr = obj()->codeBase();
for (u_int i=0; i < fbt.size(); i++) {
if (fbt[i].target_addr() == target_addr)
{
// check to see if this function has been bound yet...if the
// PLT entry for this function has been modified by the runtime
// linker
func_instance *target_pdf = 0;
if (proc()->hasBeenBound(fbt[i], target_pdf, base_addr)) {
if (proc()->hasBeenBound(function_binding, target_pdf, base_addr)) {
updateCallTarget(target_pdf);
obj()->setCalleeName(this, target_pdf->symTabName());
obj()->setCallee(this, target_pdf);
return target_pdf;
}
}
}
return callee(pltFuncs[target_addr]);
return callee(function_binding.name());
} else {
/*
* Sometimes, the PLT address and the CFG target aren't the same
Expand Down
1 change: 1 addition & 0 deletions symtabAPI/h/Symtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class SYMTAB_EXPORT Symtab : public LookupInterface,

// Relocation entries
bool getFuncBindingTable(std::vector<relocationEntry> &fbt) const;
bool findPltEntryByTarget(Address target_address, relocationEntry &result) const;
bool updateFuncBindingTable(Offset stub_addr, Offset plt_addr);

/**************************************
Expand Down
24 changes: 24 additions & 0 deletions symtabAPI/src/Symtab.C
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,30 @@ SYMTAB_EXPORT bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt
return true;
}

SYMTAB_EXPORT bool Symtab::findPltEntryByTarget(const Address target_address, relocationEntry &result) const
{
/**
* Object files and static binaries will not have a function binding table
* because the function binding table holds relocations used by the dynamic
* linker
*/
if(relocation_table_.empty() && !isStaticBinary() &&
getObjectType() != obj_RelocatableFile)
{
fprintf(stderr, "%s[%d]: WARN: zero func bindings\n", FILE__, __LINE__);
}

auto it = std::find_if(relocation_table_.cbegin(), relocation_table_.cend(),
[=](const relocationEntry& entry) {
return entry.target_addr() == target_address;
});
if(it == relocation_table_.cend())
return false;

result = *it;
return true;
}

SYMTAB_EXPORT bool Symtab::updateFuncBindingTable(Offset stub_addr, Offset plt_addr)
{
int stub_idx = -1, plt_idx = -1;
Expand Down

0 comments on commit 42612b4

Please sign in to comment.