From 70cc1f5f0d8acf54aec310d99540c75743881f61 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Wed, 24 Jun 2009 17:49:23 -0500 Subject: [PATCH] * Correctly open the first dependency that matches the ABI of its parent. * Only do a full dependency check if we're opening them * Scan for a thread library separately from opening dependent libs * Maintain proper recursion for opening dependent libraries & adding new ones --- dyninstAPI/h/BPatch_binaryEdit.h | 2 ++ dyninstAPI/src/BPatch_binaryEdit.C | 73 +++++++++----------------------------- dyninstAPI/src/binaryEdit.C | 41 +++++++++++++++++---- dyninstAPI/src/binaryEdit.h | 9 ++--- dyninstAPI/src/linux.C | 50 +++++++++++++++++++++----- 5 files changed, 98 insertions(+), 77 deletions(-) diff --git a/dyninstAPI/h/BPatch_binaryEdit.h b/dyninstAPI/h/BPatch_binaryEdit.h index bb8d797..3c5f655 100644 --- a/dyninstAPI/h/BPatch_binaryEdit.h +++ b/dyninstAPI/h/BPatch_binaryEdit.h @@ -99,12 +99,14 @@ class BPATCH_DLL_EXPORT BPatch_binaryEdit : public BPatch_addressSpace { bool creation_error; bool replaceTrapHandler(); + protected: void getAS(std::vector &as); public: + bool isMultiThreadCapable() const; bool getType(); bool getTerminated() {return false;} bool getMutationsActive() {return true;} diff --git a/dyninstAPI/src/BPatch_binaryEdit.C b/dyninstAPI/src/BPatch_binaryEdit.C index ac8f465..cf0271d 100644 --- a/dyninstAPI/src/BPatch_binaryEdit.C +++ b/dyninstAPI/src/BPatch_binaryEdit.C @@ -93,7 +93,6 @@ BPatch_binaryEdit::BPatch_binaryEdit(const char *path, bool openDependencies) : BPatch_addressSpace(), creation_error(false) { - bool has_thread_lib = false; pendingInsertions = new BPatch_Vector; pdvector argv_vec; @@ -112,34 +111,8 @@ BPatch_binaryEdit::BPatch_binaryEdit(const char *path, bool openDependencies) : } llBinEdits[path] = origBinEdit; - std::queue files; - origBinEdit->getAllDependencies(files); - - while (files.size()) { - string s = files.front(); - files.pop(); - - if (strstr(s.c_str(), "libpthread") || - strstr(s.c_str(), "libthread")) { - has_thread_lib = true; - } - - if (llBinEdits.count(s)) - continue; - if (!openDependencies) - continue; - - startup_printf("[%s:%u] - Opening dependant file %s\n", - FILE__, __LINE__, s.c_str()); - BinaryEdit *lib = BinaryEdit::openFile(s); - if (!lib) { - startup_printf("[%s:%u] - Creation error opening %s\n", - FILE__, __LINE__, s.c_str()); - creation_error = true; - return; - } - llBinEdits[s] = lib; - lib->getAllDependencies(files); + if(openDependencies) { + origBinEdit->getAllDependencies(llBinEdits); } origBinEdit->getDyninstRTLibName(); @@ -167,7 +140,7 @@ BPatch_binaryEdit::BPatch_binaryEdit(const char *path, bool openDependencies) : llBinEdit->set_up_ptr(this); llBinEdit->setupRTLibrary(rtLib); llBinEdit->setTrampGuard(masterTrampGuard); - llBinEdit->setMultiThreadCapable(has_thread_lib); + llBinEdit->setMultiThreadCapable(isMultiThreadCapable()); for (j = llBinEdits.begin(); j != llBinEdits.end(); j++) { llBinEdit->addSibling((*j).second); } @@ -176,6 +149,11 @@ BPatch_binaryEdit::BPatch_binaryEdit(const char *path, bool openDependencies) : image = new BPatch_image(this); } +bool BPatch_binaryEdit::isMultiThreadCapable() const +{ + return origBinEdit->isMultiThreadCapable(); +} + BPatch_image * BPatch_binaryEdit::getImageInt() { return image; } @@ -373,33 +351,16 @@ bool BPatch_binaryEdit::finalizeInsertionSetInt(bool /*atomic*/, bool * /*modifi bool BPatch_binaryEdit::loadLibraryInt(const char *libname, bool deps) { - std::queue libs; - libs.push(libname); - std::map newlibs; - while (libs.size()) { - string s = libs.front(); - libs.pop(); - - if (llBinEdits.count(s) || newlibs.count(s)) - continue; - BinaryEdit *file = BinaryEdit::openFile(s); - if (!file) { - std::map::iterator i; - for (i = newlibs.begin(); i != newlibs.end(); i++) - delete (*i).second; - return false; - } - newlibs[s] = file; - - if (deps) - file->getAllDependencies(libs); - } - - std::map::iterator i; - for (i = newlibs.begin(); i != newlibs.end(); i++) - llBinEdits[(*i).first] = (*i).second; + std::pair lib = origBinEdit->openResolvedLibraryName(libname); + if(!lib.second) + return false; - return true; + llBinEdits.insert(lib); + + if (deps) + return lib.second->getAllDependencies(llBinEdits); + return true; + } // Here's the story. We may need to install a trap handler for instrumentation diff --git a/dyninstAPI/src/binaryEdit.C b/dyninstAPI/src/binaryEdit.C index 57a3154..0a9fec3 100644 --- a/dyninstAPI/src/binaryEdit.C +++ b/dyninstAPI/src/binaryEdit.C @@ -338,20 +338,47 @@ bool BinaryEdit::getStatFileDescriptor(const std::string &name, fileDescriptor & } #if !defined(cap_binary_rewriter) -std::string BinaryEdit::resolveLibraryName(std::string) +std::pair BinaryEdit::openResolvedLibraryName(std::string filename) { - return NULL; + assert(!"Not implemented"); + return std::make_pair("", static_cast(NULL)); } + #endif -bool BinaryEdit::getAllDependencies(std::queue &deps) +bool BinaryEdit::isMultiThreadCapable() { Symtab *symtab = mobj->parse_img()->getObject(); std::vector depends = symtab->getDependencies(); - for (unsigned i=0; i::iterator curDep = depends.begin(); + curDep != depends.end(); curDep++) { + if((curDep->find("libpthread") != std::string::npos) || (curDep->find("libthread") != std::string::npos)) + return true; + } + return false; +} + +bool BinaryEdit::getAllDependencies(std::map& deps) +{ + Symtab *symtab = mobj->parse_img()->getObject(); + std::deque depends; + std::copy(symtab->getDependencies().begin(), symtab->getDependencies().end(), std::back_inserter(depends)); + while(!depends.empty()) + { + std::string lib = depends.front(); + if(deps.find(lib) == deps.end()) { + std::pair res = openResolvedLibraryName(lib); + if (res.second) { + deps.insert(res); + if(!res.second->getAllDependencies(deps)) + { + return false; + } + } else { + return false; + } + } + depends.pop_front(); } return true; } diff --git a/dyninstAPI/src/binaryEdit.h b/dyninstAPI/src/binaryEdit.h index 988abda..c64c60d 100644 --- a/dyninstAPI/src/binaryEdit.h +++ b/dyninstAPI/src/binaryEdit.h @@ -136,10 +136,6 @@ class BinaryEdit : public AddressSpace { bool writeFile(const std::string &newFileName); - // resolve a dynamic library name to a full path - // returns NULL if the library cannot be found - std::string resolveLibraryName(std::string filename); - virtual int_function *findOnlyOneFunction(const std::string &name, const std::string &libname = "", bool search_rt_lib = true); @@ -155,7 +151,7 @@ class BinaryEdit : public AddressSpace { void setupRTLibrary(BinaryEdit *r); BinaryEdit *rtLibrary(); - bool getAllDependencies(std::queue &deps); + bool getAllDependencies(std::map &deps); void markDirty(); bool isDirty(); @@ -172,9 +168,10 @@ class BinaryEdit : public AddressSpace { bool replaceTrapHandler(); bool usedATrap(); + bool isMultiThreadCapable(); + std::pair openResolvedLibraryName(std::string filename); private: - Address highWaterMark_; Address lowWaterMark_; bool isDirty_; diff --git a/dyninstAPI/src/linux.C b/dyninstAPI/src/linux.C index 2db925c..bfa292e 100644 --- a/dyninstAPI/src/linux.C +++ b/dyninstAPI/src/linux.C @@ -2580,9 +2580,9 @@ bool process::readAuxvInfo() } - #if defined(cap_binary_rewriter) -std::string BinaryEdit::resolveLibraryName(std::string filename) + +std::pair BinaryEdit::openResolvedLibraryName(std::string filename) { char *libPathStr, *libPath; std::vector libPaths; @@ -2593,7 +2593,14 @@ std::string BinaryEdit::resolveLibraryName(std::string filename) // prefer qualified file paths if (stat(filename.c_str(), &dummy) == 0) { - return std::string(filename); + BinaryEdit* temp = BinaryEdit::openFile(filename); + startup_printf("[%s:%u] - Opening dependant file %s\n", + FILE__, __LINE__, filename.c_str()); + if(temp && temp->getAddressWidth() == getAddressWidth()) + return std::make_pair(filename, temp); + startup_printf("[%s:%u] - Creation error opening %s\n", + FILE__, __LINE__, filename.c_str()); + delete temp; } // search paths from environment variables @@ -2608,7 +2615,15 @@ std::string BinaryEdit::resolveLibraryName(std::string filename) for (unsigned int i = 0; i < libPaths.size(); i++) { std::string str = libPaths[i] + "/" + filename; if (stat(str.c_str(), &dummy) == 0) { - return str; + BinaryEdit* temp = BinaryEdit::openFile(str); + startup_printf("[%s:%u] - Opening dependant file %s\n", + FILE__, __LINE__, str.c_str()); + if(temp && temp->getAddressWidth() == getAddressWidth()) + return std::make_pair(str, temp); + startup_printf("[%s:%u] - Creation error opening %s\n", + FILE__, __LINE__, str.c_str()); + delete temp; + } } @@ -2629,8 +2644,17 @@ std::string BinaryEdit::resolveLibraryName(std::string filename) while (*pos != '\n' && *pos != '\0') pos++; *pos = '\0'; if (strcmp(key, filename.c_str()) == 0) { - pclose(ldconfig); - return val; + startup_printf("[%s:%u] - Opening dependant file %s\n", + FILE__, __LINE__, val); + BinaryEdit* temp = BinaryEdit::openFile(val); + if(temp->getAddressWidth() == getAddressWidth()) { + pclose(ldconfig); + return std::make_pair(std::string(val), temp); + } + + startup_printf("[%s:%u] - Creation error opening %s\n", + FILE__, __LINE__, val); + delete temp; } } pclose(ldconfig); @@ -2645,11 +2669,21 @@ std::string BinaryEdit::resolveLibraryName(std::string filename) for (unsigned int i = 0; i < libPaths.size(); i++) { std::string str = libPaths[i] + "/" + filename; if (stat(str.c_str(), &dummy) == 0) { - return str; + startup_printf("[%s:%u] - Opening dependant file %s\n", + FILE__, __LINE__, str.c_str()); + BinaryEdit* temp = BinaryEdit::openFile(str); + if(temp && temp->getAddressWidth() == getAddressWidth()) + return std::make_pair(str, temp); + startup_printf("[%s:%u] - Creation error opening %s\n", + FILE__, __LINE__, str.c_str()); + delete temp; } } - return std::string(""); + startup_printf("[%s:%u] - Creation error opening %s\n", + FILE__, __LINE__, filename.c_str()); + return std::make_pair("", static_cast(NULL)); } + #endif bool process::detachForDebugger(const EventRecord &/*crash_event*/) { -- 1.8.3.1