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*)