HPCToolkit
Dbg-LM.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 //************************* System Include Files ****************************
61 
62 #include <typeinfo>
63 
64 #include <string>
65 using std::string;
66 
67 #include <iostream>
68 using std::cerr;
69 using std::endl;
70 using std::hex;
71 using std::dec;
72 
73 #include <sstream>
74 
75 //*************************** User Include Files ****************************
76 
77 #include <include/hpctoolkit-config.h>
78 #include <include/gnu_bfd.h>
79 
80 #include "Dbg-LM.hpp"
81 #include "Dbg-Proc.hpp"
82 
85 #include <lib/support/SrcFile.hpp>
86 
87 //*************************** Forward Declarations **************************
88 
89 //***************************************************************************
90 
91 //***************************************************************************
92 // LM
93 //***************************************************************************
94 
96 {
97 }
98 
99 
101 {
102  clear();
103  clear1();
104 }
105 
106 
107 void
108 BinUtil::Dbg::LM::read(bfd* abfd, asymbol** bfdSymTab)
109 {
110 #if defined(HAVE_HPC_GNUBINUTILS)
111  if (!bfdSymTab) { return; }
112 
113  // Construct: Currently we only know about ELF/DWARF2
114  if (bfd_get_flavour(abfd) == bfd_target_elf_flavour) {
115  bfd_forall_dbg_funcinfo_fn_t callback =
116  (bfd_forall_dbg_funcinfo_fn_t)bfd_dbgInfoCallback;
117  //int cnt =
118  bfd_elf_forall_dbg_funcinfo(abfd, bfdSymTab, callback, this);
119  }
120 
121  // Post-process and set parent pointers
123  //dump(std::cout);
124 #endif /* HAVE_HPC_GNUBINUTILS */
125 }
126 
127 
128 void
130 {
131  for (const_iterator it = this->begin(); it != this->end(); ++it) {
132  delete it->second;
133  }
134  m_map.clear();
135 }
136 
137 
138 void
140 {
141  for (const_iterator1 it = this->begin1(); it != this->end1(); ++it) {
142  delete it->second;
143  }
144  m_map1.clear();
145 }
146 
147 
148 std::string
150 {
151  std::ostringstream os;
152  dump(os);
153  return os.str();
154 }
155 
156 
157 std::ostream&
158 BinUtil::Dbg::LM::dump(std::ostream& os) const
159 {
160  os << "{ Dbg::LM: \n";
161  for (const_iterator it = this->begin(); it != this->end(); ++it) {
162  os << "(" << hex << it->first << dec << " --> " << it->second << ") ";
163  it->second->dump(os);
164  }
165  for (const_iterator1 it = this->begin1(); it != this->end1(); ++it) {
166  os << "(" << it->first << " --> " << it->second << ") ";
167  it->second->dump(os);
168  }
169  os << "}\n";
170  os.flush();
171  return os;
172 }
173 
174 
175 void
177 {
178  dump(std::cerr);
179 }
180 
181 
182 //***************************************************************************
183 
184 // Should have function type of 'bfd_forall_dbg_funcinfo_fn_t'
185 int
187  void* parent, void* funcinfo)
188 {
189 #if defined(HAVE_HPC_GNUBINUTILS)
190  Dbg::LM* lminfo = (Dbg::LM*)callback_obj;
191 
192  Dbg::Proc* pinfo = new Dbg::Proc;
193 
194  // Collect information for 'funcinfo'
195  bfd_vma begVMA, endVMA;
196  const char* name, *filenm;
197  unsigned int begLine;
198  bfd_forall_dbg_funcinfo_get_decl_info(funcinfo, &name, &filenm, &begLine);
199  bfd_forall_dbg_funcinfo_get_vma_bounds(funcinfo, &begVMA, &endVMA);
200  if (!name) { name = ""; }
201  if (!filenm) { filenm = ""; }
202 
203  pinfo->begVMA = begVMA;
204  pinfo->endVMA = endVMA;
205  pinfo->name = name;
206  pinfo->filenm = filenm;
207  pinfo->begLine = (SrcFile::ln)begLine;
208 
209  // normalize file names -- sometimes filenames are of different
210  // forms within same load module
212 
213  // We are not guaranteed to see parent routines before children.
214  // Save begVMA for future processing.
215  begVMA = endVMA = 0;
216  if (parent) {
217  bfd_forall_dbg_funcinfo_get_vma_bounds(parent, &begVMA, &endVMA);
218  }
219  pinfo->parentVMA = begVMA;
220 
221  DIAG_DevMsg(10, "BinUtil::Dbg::LM::bfd_dbgInfoCallback:\n"
222  << pinfo->toString());
223 
224 
225  // -------------------------------------------------------
226  // store this 'pinfo' if it is of use
227  //
228  // NOTE: in the presense of inlining we may get multiple callbacks
229  // for what appears to be the same routine when only looking at
230  // begin VMAs:
231  //
232  // <1><93510>: Abbrev Number: 32 (DW_TAG_subprogram)
233  // <93511> DW_AT_external : 1
234  // <93512> DW_AT_name : moo
235  // <93519> DW_AT_low_pc : 0x421520
236  //
237  // <2><935c9>: Abbrev Number: 36 (DW_TAG_inlined_subroutine)
238  // <935ca> DW_AT_abstract_origin: <8b982> [moo]
239  // <935ce> DW_AT_low_pc : 0x421520
240  //
241  // Since all sorts of havok is created if the second entry is
242  // preferred to the first, there really should be a bit to
243  // distinguish between DW_TAG_subprogram and
244  // DW_TAG_inlined_subroutine. Below I employ the heuristic of
245  // keeping the entry with the widest VMA range.
246  // -------------------------------------------------------
247 
248  if (pinfo->begVMA != 0) {
249  std::pair<iterator, bool> fnd =
250  lminfo->insert(std::make_pair(pinfo->begVMA, pinfo));
251  if (!fnd.second) {
252  Dbg::Proc* map_pinfo = fnd.first->second;
253  Dbg::Proc* tokeep = map_pinfo;
254  Dbg::Proc* todel = pinfo;
255  if (pinfo->endVMA > map_pinfo->endVMA) {
256  tokeep = pinfo;
257  todel = map_pinfo;
258  (*lminfo)[pinfo->begVMA] = tokeep;
259  }
260  DIAG_Msg(5, "Multiple DWARF descriptors for the same procedure (VMA):\nkeeping: " << tokeep->toString() << "deleting: " << todel->toString());
261  delete todel;
262  }
263  }
264  else if (!pinfo->filenm.empty()) {
265  std::pair<iterator1, bool> fnd =
266  lminfo->insert1(std::make_pair(pinfo->name, pinfo));
267  if (!fnd.second) {
268  Dbg::Proc* map_pinfo = fnd.first->second;
269  Dbg::Proc* tokeep = map_pinfo;
270  Dbg::Proc* todel = pinfo;
271  if (pinfo->begVMA < map_pinfo->begVMA
272  || pinfo->endVMA > map_pinfo->endVMA) {
273  tokeep = pinfo;
274  todel = map_pinfo;
275  (*lminfo)[pinfo->name] = tokeep;
276  }
277  DIAG_Msg(5, "Multiple DWARF descriptors for the same procedure (name):\nkeeping: " << tokeep->toString() << "deleting: " << todel->toString());
278  delete todel;
279  // FIXME: Would it be a good idea to delete *all* entries if
280  // line numbers and files names don't match?
281  }
282  }
283  else {
284  delete pinfo; // the 'pinfo' is useless
285  }
286 #endif /* HAVE_HPC_GNUBINUTILS */
287 
288  return 0;
289 }
290 
291 
292 void
294 {
295  // Set parent pointers assuming begVMA has been set.
296  for (const_iterator it = this->begin(); it != this->end(); ++it) {
297  Dbg::Proc* x = it->second;
298  if (x->parentVMA != 0) {
299  Dbg::Proc* parent = (*this)[x->parentVMA];
300  if (x != parent) {
301  x->parent = parent; // sanity check
302  }
303  }
304  }
305 }
306 
307 //***************************************************************************
My1_t::const_iterator const_iterator1
Definition: Dbg-LM.hpp:123
std::string toString() const
Definition: Dbg-LM.cpp:149
unsigned int ln
Definition: SrcFile.hpp:66
void setParentPointers()
Definition: Dbg-LM.cpp:293
iterator1 end1()
Definition: Dbg-LM.hpp:187
iterator1 begin1()
Definition: Dbg-LM.hpp:183
static RealPathMgr & singleton()
bool realpath(std::string &pathNm) const
std::string toString() const
Definition: Dbg-Proc.cpp:91
std::string name
Definition: Dbg-Proc.hpp:123
std::pair< iterator1, bool > insert1(const value_type1 &x)
Definition: Dbg-LM.hpp:201
#define DIAG_DevMsg(level,...)
Definition: diagnostics.h:246
iterator end()
Definition: Dbg-LM.hpp:141
static int bfd_dbgInfoCallback(void *callback_obj, void *parent, void *funcinfo)
Definition: Dbg-LM.cpp:186
#define DIAG_Msg(level,...)
Definition: diagnostics.h:241
void ddump() const
Definition: Dbg-LM.cpp:176
std::ostream & dump(std::ostream &os) const
Definition: Dbg-LM.cpp:158
My_t::const_iterator const_iterator
Definition: Dbg-LM.hpp:110
void read(bfd *abfd, asymbol **bfdSymTab)
Definition: Dbg-LM.cpp:108
SrcFile::ln begLine
Definition: Dbg-Proc.hpp:124
std::pair< iterator, bool > insert(const value_type &x)
Definition: Dbg-LM.hpp:155
std::string filenm
Definition: Dbg-Proc.hpp:123
iterator begin()
Definition: Dbg-LM.hpp:137