示例#1
0
文件: MyAgent.C 项目: dyninst/spi
  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
}