libcsdbg  1.28
C++ exception (and generic) stack trace debug library
csdbg::symtab::symtab ( const i8 path,
mem_addr_t  base = 0 
)
explicit

Object constructor.

Parameters
[in]paththe path of the objective code file
[in]basethe load base address
Exceptions
std::bad_alloc
csdbg::exception

Definition at line 22 of file symtab.cpp.

References csdbg::util::dbg_info(), likely, m_base, m_path, m_table, and unlikely.

Referenced by clone().

22  :
23 m_path(NULL),
24 m_base(base),
25 m_table(NULL)
26 {
27  if ( unlikely(path == NULL) )
28  throw exception("invalid argument: path (=%p)", path);
29 
30  m_path = new i8[strlen(path) + 1];
31  strcpy(m_path, path);
32 
33  bfd *fd = NULL;
34  asymbol **tbl = NULL;
35  i8 *nm = NULL;
36  symbol *sym = NULL;
37 
38  /* If an exception occurs, release resources and rethrow it */
39  try {
40  /* Open the binary file and obtain a descriptor (the bfd) */
41  fd = bfd_openr(m_path, NULL);
42  if ( unlikely(fd == NULL) ) {
43  bfd_error bfd_errno = bfd_get_error();
44  throw exception(
45  "failed to open file '%s' (bfd errno %d - %s)",
46  m_path,
47  bfd_errno,
48  bfd_errmsg(bfd_errno)
49  );
50  }
51 
52  /* Verify that the file contains objective code */
53  if ( unlikely(!bfd_check_format(fd, bfd_object)) ) {
54  bfd_error bfd_errno = bfd_get_error();
55  throw exception(
56  "failed to verify file '%s' (bfd errno %d - %s)",
57  m_path,
58  bfd_errno,
59  bfd_errmsg(bfd_errno)
60  );
61  }
62 
63  /* Get the symbol table storage size */
64  i32 sz = bfd_get_symtab_upper_bound(fd);
65  if ( unlikely(sz == 0) )
66  throw exception("file '%s' is stripped", m_path);
67 
68  else if ( unlikely(sz < 0) ) {
69  bfd_error bfd_errno = bfd_get_error();
70  throw exception(
71  "failed to parse file '%s' (bfd errno %d - %s)",
72  m_path,
73  bfd_errno,
74  bfd_errmsg(bfd_errno)
75  );
76  }
77 
78  /* Canonicalize the symbol table and get the symbol count */
79  tbl = new asymbol*[sz];
80  i32 cnt = bfd_canonicalize_symtab(fd, tbl);
81  if ( unlikely(cnt == 0) )
82  throw exception("file '%s' is stripped", m_path);
83 
84  else if ( unlikely(cnt < 0) ) {
85  bfd_error bfd_errno = bfd_get_error();
86  throw exception(
87  "failed to canonicalize the symbol table of '%s' (bfd errno %d - %s)",
88  m_path,
89  bfd_errno,
90  bfd_errmsg(bfd_errno)
91  );
92  }
93 
94  /* Traverse the symbol table, discard non function symbols */
95  m_table = new chain<symbol>;
96  for (i32 i = 0; likely(i < cnt); i++) {
97  const asymbol *cur = tbl[i];
98 
99  /* If the entry is not in a code section */
100  if ( likely((cur->section->flags & SEC_CODE) == 0) )
101  continue;
102 
103  /* If the entry is not a function symbol */
104  if ( likely((cur->flags & BSF_FUNCTION) == 0) )
105  continue;
106 
107  /*
108  * A symbol runtime address is the load address, plus the section virtual
109  * memory address, plus the offset from the section base
110  */
111  mem_addr_t addr = m_base;
112  addr += bfd_get_section_vma(fd, cur->section);
113  addr += cur->value;
114 
115  /* Demangle and store the symbol */
116  nm = abi::__cxa_demangle(cur->name, NULL, NULL, NULL);
117  if ( likely(nm != NULL) ) {
118  sym = new symbol(addr, nm);
119  delete[] nm;
120  nm = NULL;
121  }
122  else
123  sym = new symbol(addr, cur->name);
124 
125  m_table->add(sym);
126  sym = NULL;
127  }
128 
129  delete[] tbl;
130  bfd_close(fd);
131 
132 #if CSDBG_DBG_LEVEL & CSDBG_DBGL_INFO
133  util::dbg_info("loaded the symbol table of '%s'", m_path);
134  util::dbg_info(" base address @ %p", m_base);
135  util::dbg_info(" number of symbols: %d", cnt);
136  util::dbg_info(" number of function symbols: %d", m_table->size());
137 #endif
138  }
139 
140  catch (...) {
141  delete[] m_path;
142  delete[] tbl;
143  delete[] nm;
144 
145  delete m_table;
146  delete sym;
147 
148  m_path = NULL;
149  m_table = NULL;
150 
151  if ( likely(fd != NULL) )
152  bfd_close(fd);
153 
154  throw;
155  }
156 }
char i8
8-bit signed integer
Definition: config.hpp:72
mem_addr_t m_base
Load base address.
Definition: symtab.hpp:35
#define likely(expr)
Offer a hint (positive) to the pipeline branch predictor.
Definition: config.hpp:344
int i32
32-bit signed integer
Definition: config.hpp:82
virtual const i8 * path() const
Get the objective code file path.
Definition: symtab.cpp:213
chain< symbol > * m_table
Function symbol table.
Definition: symtab.hpp:37
unsigned long long mem_addr_t
64-bit memory address
Definition: config.hpp:120
i8 * m_path
Objective code file path.
Definition: symtab.hpp:33
#define unlikely(expr)
Offer a hint (negative) to the pipeline branch predictor.
Definition: config.hpp:349
static void dbg_info(const i8 *,...)
Print an informational debug message on the standard error stream.
Definition: util.cpp:680
virtual mem_addr_t base() const
Get the load base address.
Definition: symtab.cpp:224

+ Here is the call graph for this function:

+ Here is the caller graph for this function: