Dynamic loading of libbfd, no more dependency on specific libbfd version!

master
Marc Wäckerlin 20 years ago
parent 0ff3cecc1c
commit d5d376fcd6
  1. 77
      mrw/stacktrace.cpp
  2. 14
      mrw/stacktrace.hpp

@ -9,6 +9,9 @@
@license LGPL, see file <a href="license.html">COPYING</a> @license LGPL, see file <a href="license.html">COPYING</a>
$Log$ $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 Revision 1.10 2005/01/28 07:51:24 marc
improved and corrected trace formatting improved and corrected trace formatting
@ -50,6 +53,7 @@
#include <mrw/string.hpp> #include <mrw/string.hpp>
#include <mrw/list.hpp> #include <mrw/list.hpp>
#include <mrw/stdext.hpp> #include <mrw/stdext.hpp>
#include <mrw/dynamiclibrary.hpp>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -213,29 +217,45 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs) 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 (_dic.find(fname)!=_dic.end()) return true; // already loaded
if (fname=="") return createSymtable(filename()); try {
AutoBfd abfd(bfd_openr(fname.c_str(), 0)); static DynamicLibrary lib("libbfd");
long memsz(-1); static bfd*(*bfd_openr)(const char*, const char*) =
Auto<char**>::Free m(0); (bfd*(*)(const char*, const char*))lib.symbol("bfd_openr");
if (!abfd || bfd_check_format(abfd, bfd_archive) || static bfd_boolean(*bfd_check_format)(bfd*, bfd_format) =
!bfd_check_format_matches(abfd, bfd_object, &(m.getClean())) || (bfd_boolean(*)(bfd*, bfd_format))lib.symbol("bfd_check_format");
!(bfd_get_file_flags(const_cast<bfd*>(static_cast<const bfd*>(abfd))) static bfd_boolean(*bfd_check_format_matches)(bfd*, bfd_format, char***) =
&HAS_SYMS) || (bfd_boolean(*)(bfd*, bfd_format, char***))
(memsz=bfd_get_symtab_upper_bound lib.symbol("bfd_check_format_matches");
(const_cast<bfd*>(static_cast<const bfd*>(abfd))))<0) static void(*bfd_map_over_sections)
return false; (bfd*, void(*)(bfd*, asection*, void*), void*) =
mrw::AutoPtr<asymbol*> syms(new asymbol*[memsz]); (void(*)(bfd*, void(*)(bfd*, asection*, void*), void*))
if (bfd_canonicalize_symtab(const_cast<bfd*>(static_cast<const bfd*>(abfd)), lib.symbol("bfd_map_over_sections");
syms)<0) if (fname=="") return createSymtable(filename());
return false; AutoBfd abfd((*bfd_openr)(fname.c_str(), 0));
_bfd[fname] = abfd; long memsz(-1);
_syms[fname] = syms; Auto<char**>::Free m(0);
_dic[fname]; if (!abfd || (*bfd_check_format)(abfd, bfd_archive) ||
std::pair<std::string, void*> fileoffs = std::make_pair(fname, offs); !(*bfd_check_format_matches)(abfd, bfd_object, &(m.getClean())) ||
bfd_map_over_sections(_bfd[fname], buildSectionMap, &fileoffs); !(bfd_get_file_flags(const_cast<bfd*>(static_cast<const bfd*>(abfd)))
return true; &HAS_SYMS) ||
(memsz=bfd_get_symtab_upper_bound
(const_cast<bfd*>(static_cast<const bfd*>(abfd))))<0)
return false;
mrw::AutoPtr<asymbol*> syms(new asymbol*[memsz]);
if (bfd_canonicalize_symtab(const_cast<bfd*>(static_cast<const bfd*>(abfd)),
syms)<0)
return false;
_bfd[fname] = abfd;
_syms[fname] = syms;
_dic[fname];
std::pair<std::string, void*> 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; 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() mrw::StackTrace::BinFiles mrw::StackTrace::filename()
throw(std::bad_exception) { throw(std::bad_exception) {
@ -308,5 +339,5 @@ void mrw::StackTrace::buildSectionMap(bfd* abfd, asection* section,
std::map<std::string, mrw::StackTrace::Translator> mrw::StackTrace::_dic; std::map<std::string, mrw::StackTrace::Translator> mrw::StackTrace::_dic;
std::map<mrw::StackTrace::Translator::key_type, std::string> std::map<mrw::StackTrace::Translator::key_type, std::string>
mrw::StackTrace::_addrs; mrw::StackTrace::_addrs;
std::map<std::string, mrw::AutoBfd> mrw::StackTrace::_bfd; std::map<std::string, mrw::StackTrace::AutoBfd> mrw::StackTrace::_bfd;
std::map<std::string, mrw::AutoPtr<asymbol*> > mrw::StackTrace::_syms; std::map<std::string, mrw::AutoPtr<asymbol*> > mrw::StackTrace::_syms;

@ -9,6 +9,9 @@
@license LGPL, see file <a href="license.html">COPYING</a> @license LGPL, see file <a href="license.html">COPYING</a>
$Log$ $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 Revision 1.12 2005/01/28 12:13:11 marc
interference between group name StackTrace and class name StackTrace 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 @note This method calls the other one for all files in
parameter @c files. parameter @c files.
*/ */
static bool createSymtable(const BinFiles& files) throw(std::bad_exception); static bool createSymtable(const BinFiles& files)
throw(std::bad_exception);
private: private:
//............................................................... typedefs //............................................................... typedefs
typedef std::map<bfd_vma, std::pair<bfd_vma, asection*> > typedef std::map<bfd_vma, std::pair<bfd_vma, asection*> > Translator;
Translator; static int bfdClose(bfd*) throw();
typedef mrw::AutoResource<bfd*, int(*)(bfd*), StackTrace::bfdClose, int>
AutoBfd;
//.............................................................. variables //.............................................................. variables
AddressTrace _trace; AddressTrace _trace;
static std::map<std::string, Translator> _dic; static std::map<std::string, Translator> _dic;
static std::map<Translator::key_type, std::string> _addrs; static std::map<Translator::key_type, std::string> _addrs;
static std::map<std::string, AutoBfd> _bfd; static std::map<std::string, AutoBfd> _bfd;
static std::map<std::string, mrw::AutoPtr<asymbol*> > _syms; static std::map<std::string, mrw::AutoPtr<asymbol*> > _syms;
//................................................................ methods //................................................................ methods
static BinFiles filename() throw(std::bad_exception); static BinFiles filename() throw(std::bad_exception);
static void buildSectionMap(bfd*, asection*, void*) static void buildSectionMap(bfd*, asection*, void*)

Loading…
Cancel
Save