virtual bool check(SpPoint* pt) { PatchFunction* f = sp::Callee(pt); if (!f) return false; sp_print("StackArrayChecker"); // getAllVariables PatchObject* obj = pt->obj(); using namespace Dyninst::ParseAPI; using namespace Dyninst::SymtabAPI; SymtabCodeSource* cs = static_cast<SymtabCodeSource*>(obj->co()->cs()); Symtab* sym = cs->getSymtabObject(); std::vector<Symbol*> symbols; std::vector<SymtabAPI::Function*> funcs; sym->getAllFunctions(funcs); for (unsigned i = 0; i < funcs.size(); i ++) { if (funcs[i]->getOffset() == f->addr()) { std::vector<localVar*> vars; funcs[i]->getLocalVariables(vars); for (unsigned j = 0; j < vars.size(); j ++) { typeArray* t = vars[j]->getType()->getArrayType(); if (!t) continue; sp_print("%s: [%lx, %lx]", vars[j]->getName().c_str(), t->getLow(), t->getHigh()); } } } return true; }
// get all function symbols and statements for this linked object // that match an address in the passed AddressBuffer. void SymtabAPISymbols::getSymbols(const AddressBuffer& abuffer, const LinkedObjectEntry& linkedobject, SymbolTable& st) { std::set<Address> addresses; AddressCounts ac = abuffer.addresscounts; AddressCounts::const_iterator aci; std::set<Address>::iterator ai; for (aci = ac.begin(); aci != ac.end(); ++aci) { addresses.insert(aci->first); } std::string objname = linkedobject.getPath(); AddressRange lorange = linkedobject.getAddressRange(); std::set<AddressRange>::iterator si; // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_enabled) { std::cerr << "SymtabAPISymbols::getSymbols: Processing linked object " << objname << " with address range " << lorange << " addresses is " << addresses.size() << std::endl; } #endif Symtab *symtab; bool symtab_opened = Symtab::openFile(symtab, objname); //std::cerr << "SymtabAPISymbols::getSymbols: symtab_opened=" << symtab_opened << " symtab=" << symtab << std::endl; if (!symtab_opened || symtab == NULL) { // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_enabled) { std::cerr << "SymtabAPISymbols::getSymbols: linked object " << objname << " could not be opened by symtabAPI." << std::endl; } #endif return; } KrellInstitute::Core::Address image_offset(symtab->imageOffset()); KrellInstitute::Core::Address image_length(symtab->imageLength()); AddressRange image_range(image_offset,image_offset+image_length); // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_enabled) { std::cerr << "SymtabAPISymbols::getSymbols: Image range for" << objname << " " << image_range << std::endl; } #endif KrellInstitute::Core::Address base(0); if ( (image_range.getBegin() - lorange.getBegin()) < 0 ) { base = lorange.getBegin(); } std::vector <Dyninst::SymtabAPI::Function *>fsyms; // Make sure we get the full filename if(symtab) { symtab->setTruncateLinePaths(false); } if(symtab && !symtab->getAllFunctions(fsyms)) { #ifndef NDEBUG if(is_debug_symtabapi_symbols_enabled) { std::cerr << "Dyninst::SymtabAPI::Symbol::getAllFunctions unable to get functions\n`" << "from " << objname << " range: " << image_range << "\n" << Symtab::printError(Symtab::getLastSymtabError()).c_str() << std::endl; } #endif } #ifndef NDEBUG std::stringstream output; #endif std::set<Address>::iterator ai_begin = addresses.equal_range(lorange.getBegin()).first; std::set<Address>::iterator ai_end = addresses.equal_range(lorange.getEnd()).second; std::set<KrellInstitute::Core::Address> function_begin_addresses; std::vector <Function *>::iterator fsit; for(fsit = fsyms.begin(); fsit != fsyms.end(); ++fsit) { int sym_size = (*fsit)->getSize(); KrellInstitute::Core::Address begin((*fsit)->getOffset()); KrellInstitute::Core::Address end(begin + sym_size); // don't let an invalid range through... if (begin >= end) continue; AddressRange frange(begin,end); for (ai=ai_begin; ai!=ai_end; ++ai) { // normalize address for testing range from symtabapi. KrellInstitute::Core::Address theAddr(*ai - base.getValue()) ; if (frange.doesContain( theAddr )) { std::string fname = (*fsit)->getFirstSymbol()->getMangledName(); // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { output << "SymtabAPISymbols::getSymbols: ADDING FUNCTION " << fname << " " << frange << " pc:" << *ai << " adjusted pc:" << theAddr << std::endl; } #endif //st.addFunction(begin+base,end+base,fname); st.addFunction(begin,end,base,fname); // Record the function begin addresses, This allows the // cli and gui to focus on or display the first // statement of a function. // The function begin addresses will be processed later // for statement info and added to our statements. function_begin_addresses.insert(begin); break; } } } #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { std::cerr << output.str(); output.clear(); } #endif std::vector <Module *>mods; AddressRange module_range; std::string module_name; if(symtab && !symtab->getAllModules(mods)) { std::cerr << "SymtabAPISymbols::getSymbols: getAllModules unable to get all modules " << Symtab::printError(Symtab::getLastSymtabError()).c_str() << std::endl; } else { // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { for(unsigned i = 0; i< mods.size();i++){ module_range = AddressRange(mods[i]->addr(), mods[i]->addr() + symtab->imageLength()); module_name = mods[i]->fullName(); std::cerr << "SymtabAPISymbols::getSymbols: getAllModules for " << mods[i]->fullName() << " Range " << module_range << std::endl; } } #endif } // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_enabled) { std::cerr << "SymtabAPISymbols::getSymbols: image_offset:" << image_offset << " image_length:" << image_length << " image_range:" << image_range << std::endl; std::cerr << "USING BASE OFFSET " << base << std::endl; } #endif for (ai=ai_begin; ai!=ai_end; ++ai) { // normalize address for testing range from symtabapi. KrellInstitute::Core::Address theAddr(*ai - base.getValue()) ; Offset myoffset = theAddr.getValue(); for(unsigned i = 0; i< mods.size();i++) { std::vector< Dyninst::SymtabAPI::Statement *> mylines; mods[i]->getSourceLines(mylines,myoffset); if (mylines.size() > 0) { for (std::vector<Dyninst::SymtabAPI::Statement *>::iterator si = mylines.begin(); si != mylines.end(); si++) { // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { output << "SymtabAPISymbols::getSymbols: SAMPLE Address:" << theAddr + base << " " << (*si)->getFile() << ":" << (*si)->getLine() << ":" << (int) (*si)->getColumn() << ":" << KrellInstitute::Core::Address((*si)->startAddr()) +base << ":" << KrellInstitute::Core::Address((*si)->endAddr()) +base << std::endl; } #endif // add the base offset back when recording statement. st.addStatement(KrellInstitute::Core::Address((*si)->startAddr()) +base, KrellInstitute::Core::Address((*si)->endAddr()) +base, (*si)->getFile(), (*si)->getLine(), (int) (*si)->getColumn() ); } } } // mods loop } // sampled addresses loop #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { std::cerr << output.str(); output.clear(); } #endif // Find any statements for the beginning of a function that // contained a valid sample address. for(std::set<KrellInstitute::Core::Address>::const_iterator fi = function_begin_addresses.begin(); fi != function_begin_addresses.end(); ++fi) { // Lookup address by subtracting base offset. KrellInstitute::Core::Address theAddr(*fi - base.getValue()) ; Offset myoffset = theAddr.getValue(); for(unsigned i = 0; i< mods.size();i++) { std::vector< Dyninst::SymtabAPI::Statement *> mylines; mods[i]->getSourceLines(mylines,myoffset); if (mylines.size() > 0) { for(std::vector<Dyninst::SymtabAPI::Statement *>::iterator si = mylines.begin(); si != mylines.end(); si++) { // DEBUG #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { output << "SymtabAPISymbols::getSymbols: FUNCTION BEGIN" << " " << (*si)->getFile() << ":" << (*si)->getLine() << ":" << (int) (*si)->getColumn() << ":" << KrellInstitute::Core::Address((*si)->startAddr()) +base << ":" << KrellInstitute::Core::Address((*si)->endAddr()) +base << std::endl; } #endif // add the base offset back when recording statement. st.addStatement(KrellInstitute::Core::Address((*si)->startAddr()) +base, KrellInstitute::Core::Address((*si)->endAddr()) +base, (*si)->getFile(), (*si)->getLine(), (int) (*si)->getColumn() ); } } } // mods loop } // function begin statement loop #ifndef NDEBUG if(is_debug_symtabapi_symbols_detailed_enabled) { std::cerr << output.str(); output.clear(); } #endif }