|
|
|
@ -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> |
|
|
|
@ -215,12 +219,25 @@ mrw::StackTrace::CodePos mrw::StackTrace::translate(void* addr) |
|
|
|
|
bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs) |
|
|
|
|
throw(std::bad_exception) { |
|
|
|
|
if (_dic.find(fname)!=_dic.end()) return true; // already loaded
|
|
|
|
|
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)); |
|
|
|
|
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())) || |
|
|
|
|
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 |
|
|
|
@ -234,8 +251,11 @@ bool mrw::StackTrace::createSymtable(const std::string& fname, void* offs) |
|
|
|
|
_syms[fname] = syms; |
|
|
|
|
_dic[fname]; |
|
|
|
|
std::pair<std::string, void*> fileoffs = std::make_pair(fname, offs); |
|
|
|
|
bfd_map_over_sections(_bfd[fname], buildSectionMap, &fileoffs); |
|
|
|
|
(*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; |
|
|
|
|