Dynamic loading of libbfd, no more dependency on specific libbfd version!
This commit is contained in:
		@@ -9,6 +9,9 @@
 | 
			
		||||
    @license LGPL, see file <a href="license.html">COPYING</a>
 | 
			
		||||
 | 
			
		||||
    $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 <mrw/string.hpp>
 | 
			
		||||
#include <mrw/list.hpp>
 | 
			
		||||
#include <mrw/stdext.hpp>
 | 
			
		||||
#include <mrw/dynamiclibrary.hpp>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.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)
 | 
			
		||||
  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<char**>::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<bfd*>(static_cast<const bfd*>(abfd)))
 | 
			
		||||
        &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;
 | 
			
		||||
  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<char**>::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<bfd*>(static_cast<const bfd*>(abfd)))
 | 
			
		||||
          &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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------
 | 
			
		||||
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<std::string, mrw::StackTrace::Translator> mrw::StackTrace::_dic;
 | 
			
		||||
std::map<mrw::StackTrace::Translator::key_type, std::string>
 | 
			
		||||
  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;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,9 @@
 | 
			
		||||
    @license LGPL, see file <a href="license.html">COPYING</a>
 | 
			
		||||
 | 
			
		||||
    $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<bfd_vma, std::pair<bfd_vma, asection*> >
 | 
			
		||||
        Translator;
 | 
			
		||||
      typedef std::map<bfd_vma, std::pair<bfd_vma, asection*> > Translator;
 | 
			
		||||
      static int bfdClose(bfd*) throw();
 | 
			
		||||
      typedef mrw::AutoResource<bfd*, int(*)(bfd*), StackTrace::bfdClose, int>
 | 
			
		||||
        AutoBfd;
 | 
			
		||||
      //.............................................................. variables
 | 
			
		||||
      AddressTrace _trace;
 | 
			
		||||
      static std::map<std::string, Translator> _dic;
 | 
			
		||||
      static std::map<Translator::key_type, std::string> _addrs;
 | 
			
		||||
      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
 | 
			
		||||
      static BinFiles filename() throw(std::bad_exception);
 | 
			
		||||
      static void buildSectionMap(bfd*, asection*, void*)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user