HPCToolkit
main.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 <iostream>
63 using std::cerr;
64 using std::endl;
65 using std::hex;
66 using std::dec;
67 
68 #include <fstream>
69 #include <typeinfo>
70 #include <new>
71 
72 #include <map>
73 #include <list>
74 
75 #include <string>
76 using std::string;
77 
78 //*************************** User Include Files ****************************
79 
80 #include "Args.hpp"
81 
82 #include <lib/binutils/LM.hpp>
83 #include <lib/binutils/Seg.hpp>
84 #include <lib/binutils/Proc.hpp>
85 #include <lib/binutils/Insn.hpp>
87 
89 #include <lib/support/SrcFile.hpp>
90 
91 
92 //*************************** Forward Declarations ***************************
93 
94 static int
95 realmain(int argc, char* const* argv);
96 
97 // A list of addresses (VMAs)
98 typedef std::list<VMA> VMAList;
99 typedef std::list<VMA>::iterator VMAListIt;
100 typedef std::list<VMA>::const_iterator VMAListItC;
101 
102 // A map of a line number to an VMAList
103 typedef std::map<SrcFile::ln, VMAList*> LineToVMAListMap;
104 typedef std::map<SrcFile::ln, VMAList*>::iterator LineToVMAListMapIt;
105 typedef std::map<SrcFile::ln, VMAList*>::value_type LineToVMAListMapItVal;
106 
107 static void
109 
110 // Dump Helpers
111 static void
112 dumpSymbolicInfoOld(std::ostream& os, BinUtil::LM* lm);
113 
114 
115 //****************************************************************************
116 
117 int
118 main(int argc, char* const* argv)
119 {
120  int ret;
121 
122  try {
123  ret = realmain(argc, argv);
124  }
125  catch (const Diagnostics::Exception& x) {
126  DIAG_EMsg(x.message());
127  exit(1);
128  }
129  catch (const std::bad_alloc& x) {
130  DIAG_EMsg("[std::bad_alloc] " << x.what());
131  exit(1);
132  }
133  catch (const std::exception& x) {
134  DIAG_EMsg("[std::exception] " << x.what());
135  exit(1);
136  }
137  catch (...) {
138  DIAG_EMsg("Unknown exception encountered!");
139  exit(2);
140  }
141 
142  return ret;
143 }
144 
145 
146 static int
147 realmain(int argc, char* const argv[])
148 {
149  Args args(argc, argv);
150 
151  // ------------------------------------------------------------
152  // Read load module
153  // ------------------------------------------------------------
154  BinUtil::LM* lm = NULL;
155  try {
156  lm = new BinUtil::LM();
157  lm->open(args.inputFile.c_str());
158 
159  std::set<std::string> dir; // empty set of measurement directories
160  lm->read(dir, BinUtil::LM::ReadFlg_ALL);
161  }
162  catch (...) {
163  DIAG_EMsg("Exception encountered while reading '" << args.inputFile << "'");
164  throw;
165  }
166 
167  // ------------------------------------------------------------
168  // Dump load module
169  // ------------------------------------------------------------
170  try {
171  if (args.dumpOld) {
172  dumpSymbolicInfoOld(std::cout, lm);
173  }
174 
175  // Assume parser sanity checked arguments
177  if (args.dumpShort) {
179  }
180  if (args.dumpLong) {
182  }
183  if (args.dumpDecode) {
185  }
186 
187  lm->dump(std::cout, ty);
188 
189  }
190  catch (...) {
191  DIAG_EMsg("Exception encountered while dumping " << args.inputFile);
192  throw;
193  }
194 
195  delete lm;
196  return (0);
197 }
198 
199 
200 //****************************************************************************
201 
202 static void
203 dumpHeaderInfo(std::ostream& os, BinUtil::LM* lm, const char* pre = "")
204 {
205  os << "Begin LoadModule Stmt Dump\n";
206  os << pre << "Name: `" << lm->name() << "'\n";
207  os << pre << "Type: `";
208  switch (lm->type()) {
210  os << "Executable (fully linked except for possible DSOs)'\n";
211  break;
213  os << "Dynamically Shared Library'\n";
214  break;
215  default:
216  DIAG_Die("Unknown LM type!");
217  }
218  os << pre << "ISA: `" << typeid(*BinUtil::LM::isa).name() << "'\n"; // std::type_info
219 }
220 
221 //****************************************************************************
222 
223 static void
224 dumpSymbolicInfoForFunc(std::ostream& os, const char* pre,
225  const char* func, LineToVMAListMap* map,
226  const char* file);
227 
228 static void
229 dumpSymbolicInfoOld(std::ostream& os, BinUtil::LM* lm)
230 {
231  string pre = " ";
232  string pre1 = pre + " ";
233 
234  dumpHeaderInfo(os, lm, pre.c_str());
235 
236  // ------------------------------------------------------------------------
237  // Iterate through the VMA values of the text section, collect
238  // symbolic information on a source line basis, and output the results
239  // ------------------------------------------------------------------------
240 
241  os << pre << "Dump:\n";
242  for (BinUtil::LM::ProcMap::iterator it = lm->procs().begin();
243  it != lm->procs().end(); ++it) {
244  BinUtil::Proc* p = it->second;
245  string pName = BinUtil::canonicalizeProcName(p->name());
246 
247 
248  // We have a 'Procedure'. Iterate over VMA values
249  string theFunc = pName, theFile;
250  LineToVMAListMap map;
251 
252  for (BinUtil::ProcInsnIterator it1(*p); it1.isValid(); ++it1) {
253  BinUtil::Insn* inst = it1.current();
254  VMA vma = inst->vma();
255  VMA opVMA = BinUtil::LM::isa->convertVMAToOpVMA(vma, inst->opIndex());
256 
257  // 1. Attempt to find symbolic information
258  string func, file;
259  SrcFile::ln line;
260  p->findSrcCodeInfo(vma, inst->opIndex(), func, file, line);
261  func = BinUtil::canonicalizeProcName(func);
262 
263  // Bad line number: cannot fix; advance iteration
264  if ( !SrcFile::isValid(line) ) {
265  continue; // cannot continue without valid symbolic info
266  }
267 
268  // Bad/Different func name: ignore for now and use 'theFunc' (FIXME)
269  if (func.empty()) { func = theFunc; }
270 
271  // Bad/Different file name: ignore and try 'theFile' (FIXME)
272  if (file.empty() && !theFile.empty() // possible replacement...
273  && func == theFunc) { // ...the replacement is valid
274  file = theFile;
275  }
276 
277  // 2. We have decent symbolic info. Squirrel this away.
278  if (theFunc.empty()) { theFunc = func; }
279  if (theFile.empty()) { theFile = file; }
280 
281  LineToVMAListMapIt it2 = map.find(line);
282  VMAList* list;
283  if (it2 != map.end()) {
284  list = (*it2).second; // modify existing list
285  list->push_back(opVMA);
286  }
287  else {
288  list = new VMAList; // create a new list and insert pair
289  list->push_back(opVMA);
290  map.insert(LineToVMAListMapItVal(line, list));
291  }
292  }
293 
294  dumpSymbolicInfoForFunc(os, pre1.c_str(),
295  theFunc.c_str(), &map, theFile.c_str());
296  clearLineToVMAListMap(&map);
297  }
298  os << "\n" << "End LoadModule Stmt Dump\n";
299 }
300 
301 
302 static void
303 dumpSymbolicInfoForFunc(std::ostream& os, const char* pre,
304  const char* func, LineToVMAListMap* map,
305  const char* file)
306 {
307  string p = pre;
308  string p1 = p + " ";
309 
310  os << p << "* " << func << "\n"
311  << p << " [" << file << "]\n";
312 
314  for (it = map->begin(); it != map->end(); ++it) {
315  SrcFile::ln line = (*it).first;
316  VMAList* list = (*it).second;
317 
318  os << p1 << " " << line << ": {" << hex;
319 
320  VMAListIt it1;
321  for (it1 = list->begin(); it1 != list->end(); ++it1) {
322  VMA vma = *it1;
323  os << " 0x" << vma;
324  }
325  os << " }" << dec << endl;
326  }
327 }
328 
329 
330 static void
332 {
334  for (it = map->begin(); it != map->end(); ++it) {
335  delete (*it).second;
336  }
337  map->clear();
338 }
Definition: Args.hpp:79
bool dumpLong
Definition: Args.hpp:105
static void dumpHeaderInfo(std::ostream &os, BinUtil::LM *lm, const char *pre="")
Definition: main.cpp:203
bool dumpOld
Definition: Args.hpp:108
std::map< SrcFile::ln, VMAList * >::value_type LineToVMAListMapItVal
Definition: main.cpp:105
bool dumpDecode
Definition: Args.hpp:107
My_t::iterator iterator
ProcMap & procs()
Definition: LM.hpp:273
virtual VMA convertVMAToOpVMA(VMA vma, ushort GCC_ATTR_UNUSED opIndex) const
Definition: ISA.hpp:471
unsigned int ln
Definition: SrcFile.hpp:66
string canonicalizeProcName(const std::string &name, ProcNameMgr *procNameMgr)
Definition: BinUtils.cpp:69
bfd_vma VMA
Definition: ISATypes.hpp:79
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
const std::string & name() const
Definition: Proc.hpp:122
bool isValid() const
Definition: Proc.hpp:397
std::list< VMA >::const_iterator VMAListItC
Definition: main.cpp:100
bool isValid(SrcFile::ln line)
Definition: SrcFile.hpp:70
virtual void read(const std::set< std::string > &directorySet, ReadFlg readflg)
Definition: LM.cpp:460
virtual ushort opIndex() const =0
bool findSrcCodeInfo(VMA vma, ushort opIndex, std::string &func, std::string &file, SrcFile::ln &line) const
Definition: Proc.hpp:242
Type type() const
Definition: LM.hpp:175
std::list< VMA > VMAList
Definition: main.cpp:98
virtual std::string message() const
Definition: Exception.hpp:134
const std::string & name() const
Definition: LM.hpp:170
exit
Definition: names.cpp:1
std::string inputFile
Definition: Args.hpp:113
int main(int argc, char *argv[])
Definition: main.cpp:125
static void clearLineToVMAListMap(LineToVMAListMap *map)
Definition: main.cpp:331
std::map< SrcFile::ln, VMAList * >::iterator LineToVMAListMapIt
Definition: main.cpp:104
static void dumpSymbolicInfoForFunc(std::ostream &os, const char *pre, const char *func, LineToVMAListMap *map, const char *file)
Definition: main.cpp:303
bool dumpShort
Definition: Args.hpp:106
VMA vma() const
Definition: Insn.hpp:125
virtual void dump(std::ostream &o=std::cerr, int flags=DUMP_Short, const char *pre="") const
Definition: LM.cpp:715
#define NULL
Definition: ElfHelper.cpp:85
std::list< VMA >::iterator VMAListIt
Definition: main.cpp:99
std::map< SrcFile::ln, VMAList * > LineToVMAListMap
Definition: main.cpp:103
#define DIAG_Die(...)
Definition: diagnostics.h:267
static int realmain(int argc, char *const *argv)
static void dumpSymbolicInfoOld(std::ostream &os, BinUtil::LM *lm)
Definition: main.cpp:229
static ISA * isa
Definition: LM.hpp:493
virtual void open(const char *filenm)
Definition: LM.cpp:395