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>
|
@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*)
|
||||||
|
Reference in New Issue
Block a user