From d5d376fcd639c258d22151c236370607ee7b6a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Fri, 18 Feb 2005 15:48:56 +0000 Subject: [PATCH] Dynamic loading of libbfd, no more dependency on specific libbfd version! --- mrw/stacktrace.cpp | 77 ++++++++++++++++++++++++++++++++-------------- mrw/stacktrace.hpp | 14 ++++++--- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/mrw/stacktrace.cpp b/mrw/stacktrace.cpp index 0334f5f..260c3d0 100644 --- a/mrw/stacktrace.cpp +++ b/mrw/stacktrace.cpp @@ -9,6 +9,9 @@ @license LGPL, see file COPYING $Log$ + Revision 1.11 2005/02/18 15:48:56 marc + Dynamic loading of libbfd, no more dependency on specific libbfd version! + Revision 1.10 2005/01/28 07:51:24 marc improved and corrected trace formatting @@ -50,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -213,29 +217,45 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr) //---------------------------------------------------------------------------- bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs) - throw(std::bad_exception) { + throw(std::bad_exception) { if (_dic.find(fname)!=_dic.end()) return true; // already loaded - if (fname=="") return createSymtable(filename()); - AutoBfd abfd(bfd_openr(fname.c_str(), 0)); - long memsz(-1); - Auto::Free m(0); - if (!abfd || bfd_check_format(abfd, bfd_archive) || - !bfd_check_format_matches(abfd, bfd_object, &(m.getClean())) || - !(bfd_get_file_flags(const_cast(static_cast(abfd))) - &HAS_SYMS) || - (memsz=bfd_get_symtab_upper_bound - (const_cast(static_cast(abfd))))<0) - return false; - mrw::AutoPtr syms(new asymbol*[memsz]); - if (bfd_canonicalize_symtab(const_cast(static_cast(abfd)), - syms)<0) - return false; - _bfd[fname] = abfd; - _syms[fname] = syms; - _dic[fname]; - std::pair fileoffs = std::make_pair(fname, offs); - bfd_map_over_sections(_bfd[fname], buildSectionMap, &fileoffs); - return true; + try { + static DynamicLibrary lib("libbfd"); + static bfd*(*bfd_openr)(const char*, const char*) = + (bfd*(*)(const char*, const char*))lib.symbol("bfd_openr"); + static bfd_boolean(*bfd_check_format)(bfd*, bfd_format) = + (bfd_boolean(*)(bfd*, bfd_format))lib.symbol("bfd_check_format"); + static bfd_boolean(*bfd_check_format_matches)(bfd*, bfd_format, char***) = + (bfd_boolean(*)(bfd*, bfd_format, char***)) + lib.symbol("bfd_check_format_matches"); + static void(*bfd_map_over_sections) + (bfd*, void(*)(bfd*, asection*, void*), void*) = + (void(*)(bfd*, void(*)(bfd*, asection*, void*), void*)) + lib.symbol("bfd_map_over_sections"); + if (fname=="") return createSymtable(filename()); + AutoBfd abfd((*bfd_openr)(fname.c_str(), 0)); + long memsz(-1); + Auto::Free m(0); + if (!abfd || (*bfd_check_format)(abfd, bfd_archive) || + !(*bfd_check_format_matches)(abfd, bfd_object, &(m.getClean())) || + !(bfd_get_file_flags(const_cast(static_cast(abfd))) + &HAS_SYMS) || + (memsz=bfd_get_symtab_upper_bound + (const_cast(static_cast(abfd))))<0) + return false; + mrw::AutoPtr syms(new asymbol*[memsz]); + if (bfd_canonicalize_symtab(const_cast(static_cast(abfd)), + syms)<0) + return false; + _bfd[fname] = abfd; + _syms[fname] = syms; + _dic[fname]; + std::pair fileoffs = std::make_pair(fname, offs); + (*bfd_map_over_sections)(_bfd[fname], buildSectionMap, &fileoffs); + return true; + } catch (...) { + return false; // shared library for bfd not found or similar + } } //---------------------------------------------------------------------------- @@ -249,6 +269,17 @@ bool mrw::StackTrace::createSymtable(const mrw::StackTrace::BinFiles& files) return success; } +//---------------------------------------------------------------------------- +int mrw::StackTrace::bfdClose(bfd* abfd) throw() { + try { + static DynamicLibrary lib(""); + static int(*bfd_close)(bfd*) = (int(*)(bfd*))lib.symbol("bfd_close"); + return (*bfd_close)(abfd); + } catch (...) { + return -1; // dynamic library loading problems + } +} + //---------------------------------------------------------------------------- mrw::StackTrace::BinFiles mrw::StackTrace::filename() throw(std::bad_exception) { @@ -308,5 +339,5 @@ void mrw::StackTrace::buildSectionMap(bfd* abfd, asection* section, std::map mrw::StackTrace::_dic; std::map mrw::StackTrace::_addrs; -std::map mrw::StackTrace::_bfd; +std::map mrw::StackTrace::_bfd; std::map > mrw::StackTrace::_syms; diff --git a/mrw/stacktrace.hpp b/mrw/stacktrace.hpp index 4b14b57..719b908 100644 --- a/mrw/stacktrace.hpp +++ b/mrw/stacktrace.hpp @@ -9,6 +9,9 @@ @license LGPL, see file COPYING $Log$ + Revision 1.13 2005/02/18 15:48:56 marc + Dynamic loading of libbfd, no more dependency on specific libbfd version! + Revision 1.12 2005/01/28 12:13:11 marc interference between group name StackTrace and class name StackTrace @@ -264,18 +267,21 @@ namespace mrw { @note This method calls the other one for all files in parameter @c files. */ - static bool createSymtable(const BinFiles& files) throw(std::bad_exception); + static bool createSymtable(const BinFiles& files) + throw(std::bad_exception); private: //............................................................... typedefs - typedef std::map > - Translator; + typedef std::map > Translator; + static int bfdClose(bfd*) throw(); + typedef mrw::AutoResource + AutoBfd; //.............................................................. variables AddressTrace _trace; static std::map _dic; static std::map _addrs; static std::map _bfd; - static std::map > _syms; + static std::map > _syms; //................................................................ methods static BinFiles filename() throw(std::bad_exception); static void buildSectionMap(bfd*, asection*, void*)