// hasBeenBound: returns true if the runtime linker has bound the // function symbol corresponding to the relocation entry in at the address // specified by entry and base_addr. If it has been bound, then the callee // function is returned in "target_pdf", else it returns false. bool PCProcess::hasBeenBound(const relocationEntry &entry, func_instance *&target_pdf, Address base_addr) { if (isTerminated()) return false; // if the relocationEntry has not been bound yet, then the value // at rel_addr is the address of the instruction immediately following // the first instruction in the PLT entry (which is at the target_addr) // The PLT entries are never modified, instead they use an indirrect // jump to an address stored in the _GLOBAL_OFFSET_TABLE_. When the // function symbol is bound by the runtime linker, it changes the address // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry Address got_entry = entry.rel_addr() + base_addr; Address bound_addr = 0; if(!readDataSpace((const void*)got_entry, sizeof(Address), &bound_addr, true)){ sprintf(errorLine, "read error in process::hasBeenBound addr 0x%x, pid=%d\n (readDataSpace returns 0)",(unsigned)got_entry,getPid()); logLine(errorLine); print_read_error_info(entry, target_pdf, base_addr); return false; } if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) { // the callee function has been bound by the runtime linker // find the function and return it target_pdf = findOneFuncByAddr(bound_addr); if(!target_pdf){ return false; } return true; } return false; }
void print_read_error_info(const relocationEntry entry, func_instance *&target_pdf, Address base_addr) { sprintf(errorLine, " entry : target_addr 0x%x\n", (unsigned)entry.target_addr()); logLine(errorLine); sprintf(errorLine, " rel_addr 0x%x\n", (unsigned)entry.rel_addr()); logLine(errorLine); sprintf(errorLine, " name %s\n", (entry.name()).c_str()); logLine(errorLine); if (target_pdf) { sprintf(errorLine, " target_pdf : symTabName %s\n", (target_pdf->symTabName()).c_str()); logLine(errorLine); sprintf(errorLine , " prettyName %s\n", (target_pdf->symTabName()).c_str()); logLine(errorLine); /* // Size bad. <smack> sprintf(errorLine , " size %i\n", target_pdf->getSize()); logLine(errorLine); */ sprintf(errorLine , " addr 0x%x\n", (unsigned)target_pdf->addr()); logLine(errorLine); } sprintf(errorLine, " base_addr 0x%x\n", (unsigned)base_addr); logLine(errorLine); }