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 // system includes
49 //*****************************************************************************
50 
51 #include <vector>
52 #include <string>
53 
54 #include <climits>
55 #include <cstdio>
56 #include <cstdlib>
57 
58 #define __STDC_FORMAT_MACROS
59 #include <inttypes.h>
60 
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #include <fcntl.h>
64 #include <setjmp.h>
65 #include <signal.h>
66 #include <unistd.h>
67 
68 //*****************************************************************************
69 // local includes
70 //*****************************************************************************
71 
72 #include "code-ranges.h"
73 #include "eh-frames.h"
74 #include "process-ranges.h"
75 #include "function-entries.h"
76 #include "variable-entries.h"
77 #include "sections.h"
78 #include "server.h"
79 #include "syserv-mesg.h"
80 
81 #include "Symtab.h"
82 
83 using namespace std;
84 using namespace Dyninst;
85 using namespace SymtabAPI;
86 
87 //*****************************************************************************
88 // macros
89 //*****************************************************************************
90 
91 #define PATHSCALE_EXCEPTION_HANDLER_PREFIX "Handler."
92 #define USE_PATHSCALE_SYMBOL_FILTER
93 #define USE_SYMTABAPI_EXCEPTION_BLOCKS
94 
95 #define STRLEN(s) (sizeof(s) - 1)
96 
97 //*****************************************************************************
98 // forward declarations
99 //*****************************************************************************
100 
101 static void usage(char *command, int status);
102 static void setup_segv_handler(void);
103 
104 //*****************************************************************************
105 // local variables
106 //*****************************************************************************
107 
108 // output is text mode unless C or server mode is specified.
109 
110 enum { MODE_TEXT = 1, MODE_C, MODE_SERVER };
111 static int the_mode = MODE_TEXT;
112 
113 static bool verbose = false; // additional verbosity
114 
115 static jmp_buf segv_recover; // handle longjmp "restart" from segv
116 
117 //*****************************************************************
118 // interface operations
119 //*****************************************************************
120 
121 // Now write one format (C or text) to stdout, or else binary format
122 // over a pipe in server mode. No output directory.
123 
124 int
125 main(int argc, char* argv[])
126 {
127  DiscoverFnTy fn_discovery = DiscoverFnTy_Aggressive;
128  char *object_file;
129  int n, fdin, fdout, query = SYSERV_QUERY;
130 
131  for (n = 1; n < argc; n++) {
132  if (strcmp(argv[n], "-c") == 0) {
133  the_mode = MODE_C;
134  }
135  else if (strcmp(argv[n], "-d") == 0) {
136  fn_discovery = DiscoverFnTy_Conservative;
137  }
138  else if (strcmp(argv[n], "-h") == 0 || strcmp(argv[n], "--help") == 0) {
139  usage(argv[0], 0);
140  }
141  else if (strcmp(argv[n], "-m") == 0) {
142  // datacentric usage to query static variables
143  query = SYSERV_QUERY_VAR;
144  }
145  else if (strcmp(argv[n], "-s") == 0) {
147  if (argc < n + 3 || sscanf(argv[n+1], "%d", &fdin) < 1
148  || sscanf(argv[n+2], "%d", &fdout) < 1) {
149  fprintf(stderr, "%s: missing file descriptors for server mode\n",
150  argv[0]);
151  exit(1);
152  }
153  n += 2;
154  }
155  else if (strcmp(argv[n], "-t") == 0) {
157  }
158  else if (strcmp(argv[n], "-v") == 0) {
159  verbose = true;
160  }
161  else if (strcmp(argv[n], "--") == 0) {
162  n++;
163  break;
164  }
165  else if (strncmp(argv[n], "-", 1) == 0) {
166  fprintf(stderr, "%s: unknown option: %s\n", argv[0], argv[n]);
167  usage(argv[0], 1);
168  }
169  else {
170  break;
171  }
172  }
173 
174  // Run as the system server.
175  if (server_mode()) {
176  system_server(fn_discovery, fdin, fdout);
177  exit(0);
178  }
179 
180  // Must specify at least the object file.
181  if (n >= argc) {
182  usage(argv[0], 1);
183  }
184  object_file = argv[n];
185 
187  if ( ! setjmp(segv_recover) ) {
188  dump_file_info(object_file, fn_discovery, query);
189  }
190  else {
191  fprintf(stderr,
192  "!!! INTERNAL hpcfnbounds-bin error !!!\n"
193  "argument string = ");
194  for (int i = 0; i < argc; i++)
195  fprintf(stderr, "%s ", argv[i]);
196  fprintf(stderr, "\n");
197  }
198  return 0;
199 }
200 
201 int
202 c_mode(void)
203 {
204  return the_mode == MODE_C;
205 }
206 
207 int
209 {
210  return the_mode == MODE_SERVER;
211 }
212 
213 
214 extern "C" {
215 
216 // we don't care about demangled names. define
217 // a no-op that meets symtabAPI semantic needs only
218 char *
219 cplus_demangle(char *s, int opts)
220 {
221 return strdup(s);
222 }
223 };
224 
225 
226 // Callback from dwarf_eh_frame_info() in eh-frames.cpp.
227 void
229 {
230  add_function_entry(addr, NULL, false, 0);
231 }
232 
233 
234 //*****************************************************************
235 // private operations
236 //*****************************************************************
237 
238 static void
239 usage(char *command, int status)
240 {
241  fprintf(stderr,
242  "Usage: hpcfnbounds [options] object-file\n\n"
243  "\t-c\twrite output in C source code\n"
244  "\t-d\tdon't perform function discovery on stripped code\n"
245  "\t-h\tprint this help message and exit\n"
246  "\t-s fdin fdout\trun in server mode\n"
247  "\t-t\twrite output in text format (default)\n"
248  "\t-v\tturn on verbose output in hpcfnbounds script\n\n"
249  "If no format is specified, then text mode is used.\n");
250 
251  exit(status);
252 }
253 
254 static void
255 segv_handler(int sig)
256 {
257  longjmp(segv_recover, 1);
258 }
259 
260 static void
262 {
263 #if 0
264  const struct sigaction segv_action= {
265  .sa_handler = segv_handler,
266  .sa_flags = 0
267  };
268 #endif
269  struct sigaction segv_action;
270  segv_action.sa_handler = segv_handler;
271  segv_action.sa_flags = 0;
272  sigemptyset(&segv_action.sa_mask);
273 
274  sigaction(SIGSEGV, &segv_action, NULL);
275 }
276 
277 
278 static bool
279 matches_prefix(string s, const char *pre, int n)
280 {
281  const char *sc = s.c_str();
282  return strncmp(sc, pre, n) == 0;
283 }
284 
285 #ifdef __PPC64__
286 static bool
287 matches_contains(string s, const char *substring)
288 {
289  const char *sc = s.c_str();
290  return strstr(sc, substring) != 0;
291 }
292 #endif
293 
294 static bool
295 pathscale_filter(Symbol *sym)
296 {
297  bool result = false;
298  // filter out function symbols for exception handlers
299  if (matches_prefix(sym->getMangledName(),
302  result = true;
303  return result;
304 }
305 
306 
307 static bool
308 report_symbol(Symbol *sym)
309 {
310 #ifdef USE_PATHSCALE_SYMBOL_FILTER
311  if (pathscale_filter(sym)) return false;
312 #endif
313  return true;
314 }
315 
316 
317 static string *
318 code_range_comment(string &name, string section, const char *which)
319 {
320  name = which;
321  name = name + " " + section + " section";
322  return &name;
323 }
324 
325 
326 static void
327 note_code_range(const char *sname, Region *s, long memaddr, DiscoverFnTy discover)
328 {
329  char *start = (char *) s->getDiskOffset();
330  char *end = start + s->getDiskSize();
331  string ntmp;
332  new_code_range(sname, start, end, memaddr, discover);
333 
334  add_function_entry(start, code_range_comment(ntmp, s->getRegionName(), "start"), true /* global */);
335  add_function_entry(end, code_range_comment(ntmp, s->getRegionName(), "end"), true /* global */);
336 }
337 
338 
339 static void
340 note_section(Symtab *syms, const char *sname, DiscoverFnTy discover)
341 {
342  long memaddr = (long) syms->mem_image();
343  Region *s;
344  if (syms->findRegion(s, sname) && s)
345  note_code_range(sname, s, memaddr - syms->imageOffset(), discover);
346 }
347 
348 
349 static void
350 note_code_ranges(Symtab *syms, DiscoverFnTy fn_discovery)
351 {
352  //TODO: instead of just considering specific segments below
353  // perhaps we should consider all segments marked executable.
354  // binaries could include "bonus" segments we don't
355  // know about explicitly as having code within.
356  note_section(syms, SECTION_INIT, fn_discovery);
358  note_section(syms, SECTION_TEXT, fn_discovery);
359  note_section(syms, SECTION_FINI, fn_discovery);
360 }
361 
362 
363 static void
364 dump_symbols(int dwarf_fd, Symtab *syms, vector<Symbol *> &symvec,
365  DiscoverFnTy fn_discovery)
366 {
367  note_code_ranges(syms, fn_discovery);
368 
369  //-----------------------------------------------------------------
370  // collect function start addresses and pair them with a comment
371  // that indicates what function (or functions) map to that start
372  // address. enter them into a data structure for reachable function
373  // processing
374  //-----------------------------------------------------------------
375  for (unsigned int i = 0; i < symvec.size(); i++) {
376  Symbol *s = symvec[i];
377  Symbol::SymbolLinkage sl = s->getLinkage();
378  if (report_symbol(s) && s->getOffset() != 0) {
379  string mname = s->getMangledName();
380  bool invisible = (sl & Symbol::SL_GLOBAL) || (sl & Symbol::SL_WEAK);
381 
382  add_function_entry((void *) s->getOffset(), &mname,
383  invisible, 0);
384  }
385  }
386 
387  dwarf_eh_frame_info(dwarf_fd);
388 
390 
391  //-----------------------------------------------------------------
392  // dump the address and comment for each function
393  //-----------------------------------------------------------------
395 }
396 
397 
398 static void
399 dump_symbols_var(int dwarf_fd, Symtab *syms, vector<Symbol *> &symvec,
400  DiscoverFnTy fn_discovery)
401 {
402  for (unsigned int i = 0; i < symvec.size(); i++) {
403  Symbol *s = symvec[i];
404  if (s->getOffset() != 0) {
405 
406  void *addr = (void*)s->getOffset();
407  long size = s->getSize();
408  string comment = s->getMangledName();
409 
410  add_variable_entry(addr, size, &comment, true);
411  }
412  }
413 
414  //-----------------------------------------------------------------
415  // dump the address and comment for each function
416  //-----------------------------------------------------------------
417  dump_variables();
418 }
419 
420 static void
421 dump_file_symbols(int dwarf_fd, Symtab *syms, vector<Symbol *> &symvec,
422  DiscoverFnTy fn_discovery, int query)
423 {
424  if (c_mode()) {
425  printf("unsigned long hpcrun_nm_addrs[] = {\n");
426  }
427 
428  switch (query) {
429  case SYSERV_QUERY:
430  dump_symbols(dwarf_fd, syms, symvec, fn_discovery);
431  break;
432  case SYSERV_QUERY_VAR:
433  dump_symbols_var(dwarf_fd, syms, symvec, fn_discovery);
434  break;
435  }
436 
437  if (c_mode()) {
438  printf("\n};\n");
439  }
440 }
441 
442 
443 // We call it "header", even though it comes at end of file.
444 //
445 static void
446 dump_header_info(int is_relocatable, uintptr_t ref_offset)
447 {
448  if (server_mode()) {
449  syserv_add_header(is_relocatable, ref_offset);
450  return;
451  }
452 
453  if (c_mode()) {
454  printf("unsigned long hpcrun_nm_addrs_len = "
455  "sizeof(hpcrun_nm_addrs) / sizeof(hpcrun_nm_addrs[0]);\n"
456  "unsigned long hpcrun_reference_offset = 0x%" PRIxPTR ";\n"
457  "int hpcrun_is_relocatable = %d;\n",
458  ref_offset, is_relocatable);
459  return;
460  }
461 
462  // default is text mode
463  printf("num symbols = %ld, reference offset = 0x%" PRIxPTR ", "
464  "relocatable = %d\n",
465  num_function_entries(), ref_offset, is_relocatable);
466 }
467 
468 
469 static void
470 assert_file_is_readable(const char *filename)
471 {
472  struct stat sbuf;
473  int ret = stat(filename, &sbuf);
474  if (ret != 0 || !S_ISREG(sbuf.st_mode)) {
475  fprintf(stderr, "hpcfnbounds: unable to open file: %s\n", filename);
476  exit(-1);
477  }
478 }
479 
480 
481 void
482 dump_file_info(const char *filename, DiscoverFnTy fn_discovery, int query)
483 {
484  Symtab *syms;
485  string sfile(filename);
486  vector<Symbol *> symvec;
487  uintptr_t image_offset = 0;
488 
489  assert_file_is_readable(filename);
490 
491  if ( ! Symtab::openFile(syms, sfile) ) {
492  fprintf(stderr,
493  "!!! INTERNAL hpcfnbounds-bin error !!!\n"
494  " -- file %s is readable, but Symtab::openFile fails !\n",
495  filename);
496  exit(1);
497  }
498  int relocatable = 0;
499 
500 #ifdef USE_SYMTABAPI_EXCEPTION_BLOCKS
501  //-----------------------------------------------------------------
502  // ensure that we don't infer function starts within try blocks or
503  // at the start of catch blocks
504  //-----------------------------------------------------------------
505  vector<ExceptionBlock *> exvec;
506  syms->getAllExceptions(exvec);
507 
508  for (unsigned int i = 0; i < exvec.size(); i++) {
509  ExceptionBlock *e = exvec[i];
510 
511 #ifdef DUMP_EXCEPTION_BLOCK_INFO
512  printf("tryStart = %p tryEnd = %p, catchStart = %p\n", e->tryStart(),
513  e->tryEnd(), e->catchStart());
514 #endif // DUMP_EXCEPTION_BLOCK_INFO
515  //-----------------------------------------------------------------
516  // prevent inference of function starts within the try block
517  //-----------------------------------------------------------------
518  add_protected_range((void *) e->tryStart(), (void *) e->tryEnd());
519 
520  //-----------------------------------------------------------------
521  // prevent inference of a function start at the beginning of a
522  // catch block. the extent of the catch block is unknown.
523  //-----------------------------------------------------------------
524  long cs = e->catchStart();
525  add_protected_range((void *) cs, (void *) (cs + 1));
526  }
527 #endif // USE_SYMTABAPI_EXCEPTION_BLOCKS
528 
529  switch (query) {
530  case SYSERV_QUERY:
531  syms->getAllSymbolsByType(symvec, Symbol::ST_FUNCTION);
532  break;
533  case SYSERV_QUERY_VAR:
534  syms->getAllSymbolsByType(symvec, Symbol::ST_OBJECT);
535  break;
536  default:
537  syms->getAllSymbolsByType(symvec, Symbol::ST_UNKNOWN);
538  }
539 
540 #ifdef __PPC64__
541  {
542  //-----------------------------------------------------------------
543  // collect addresses of trampolines for long distance calls as per
544  // ppc64 abi. empirically, the linker on BG/Q enters these symbols
545  // with the type NOTYPE and a name that contains the substring
546  // "long_branch"
547  //-----------------------------------------------------------------
548  vector<Symbol *> vec;
549  syms->getAllSymbolsByType(vec, Symbol::ST_NOTYPE);
550  for (unsigned int i = 0; i < vec.size(); i++) {
551  Symbol *s = vec[i];
552  string mname = s->getMangledName();
553  if (matches_contains(mname, "long_branch") && s->getOffset() != 0) {
554  add_function_entry((void *) s->getOffset(), &mname, true);
555  }
556  }
557  }
558 #endif
559 
560  if (syms->getObjectType() != obj_Unknown) {
561  int dwarf_fd = open(filename, O_RDONLY);
562 
563  if (dwarf_fd < 0) {
564  fprintf(stderr, "hpcfnbounds: unable to open: %s", filename);
565  }
566 
567  dump_file_symbols(dwarf_fd, syms, symvec, fn_discovery, query);
568  close(dwarf_fd);
569 
570  relocatable = syms->isExec() ? 0 : 1;
571  image_offset = syms->imageOffset();
572  }
573  dump_header_info(relocatable, image_offset);
574 
575  //-----------------------------------------------------------------
576  // free as many of the Symtab objects as we can
577  //-----------------------------------------------------------------
578 
579  Symtab::closeSymtab(syms);
580 }
void dump_variables()
void system_server(DiscoverFnTy fn_discovery, int fd1, int fd2)
Definition: server.cpp:470
static bool verbose
Definition: main.cpp:113
#define PATHSCALE_EXCEPTION_HANDLER_PREFIX
Definition: main.cpp:91
static void note_code_ranges(Symtab *syms, DiscoverFnTy fn_discovery)
Definition: main.cpp:350
const char * SECTION_INIT
Definition: sections.cpp:56
static void note_code_range(const char *sname, Region *s, long memaddr, DiscoverFnTy discover)
Definition: main.cpp:327
long num_function_entries(void)
void dump_reachable_functions()
static int fdout
Definition: server.cpp:105
void new_code_range(const char *sname, void *start, void *end, long offset, DiscoverFnTy discover)
static bool pathscale_filter(Symbol *sym)
Definition: main.cpp:295
void process_code_ranges()
const char * SECTION_FINI
Definition: sections.cpp:57
static void usage(char *command, int status)
Definition: main.cpp:239
const char * SECTION_TEXT
Definition: sections.cpp:58
const char * SECTION_PLT
Definition: sections.cpp:59
static void note_section(Symtab *syms, const char *sname, DiscoverFnTy discover)
Definition: main.cpp:340
static void assert_file_is_readable(const char *filename)
Definition: main.cpp:470
void add_variable_entry(void *addr, long size, const string *comment, bool isvisible)
static bool matches_prefix(string s, const char *pre, int n)
Definition: main.cpp:279
static jmp_buf segv_recover
Definition: main.cpp:115
static void dump_file_symbols(int dwarf_fd, Symtab *syms, vector< Symbol *> &symvec, DiscoverFnTy fn_discovery, int query)
Definition: main.cpp:421
void add_function_entry(void *addr, const string *comment, bool isvisible, int call_count)
static int fdin
Definition: server.cpp:104
static void setup_segv_handler(void)
Definition: main.cpp:261
static int the_mode
Definition: main.cpp:111
exit
Definition: names.cpp:1
void add_frame_addr(void *addr)
Definition: main.cpp:228
Definition: main.cpp:110
bool closeSymtab()
static bool report_symbol(Symbol *sym)
Definition: main.cpp:308
DiscoverFnTy
Definition: code-ranges.h:52
int main(int argc, char *argv[])
Definition: main.cpp:125
static BAnal::Struct::Options opts
Definition: Struct.cpp:160
void dump_file_info(const char *filename, DiscoverFnTy fn_discovery, int query)
Definition: main.cpp:482
void dwarf_eh_frame_info(int fd)
Definition: eh-frames.cpp:292
#define NULL
Definition: ElfHelper.cpp:85
longjmp
Definition: names.cpp:1
static void dump_header_info(int is_relocatable, uintptr_t ref_offset)
Definition: main.cpp:446
cct_addr_t * addr
Definition: cct.c:130
static void segv_handler(int sig)
Definition: main.cpp:255
int c_mode(void)
Definition: main.cpp:202
static void dump_symbols_var(int dwarf_fd, Symtab *syms, vector< Symbol *> &symvec, DiscoverFnTy fn_discovery)
Definition: main.cpp:399
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
int server_mode(void)
Definition: main.cpp:208
#define STRLEN(s)
Definition: main.cpp:95
void add_protected_range(void *start, void *end)
static string * code_range_comment(string &name, string section, const char *which)
Definition: main.cpp:318
void syserv_add_header(int is_relocatable, uintptr_t ref_offset)
Definition: server.cpp:249
char * cplus_demangle(char *s, int opts)
Definition: main.cpp:219
static void dump_symbols(int dwarf_fd, Symtab *syms, vector< Symbol *> &symvec, DiscoverFnTy fn_discovery)
Definition: main.cpp:364