HPCToolkit
SimpleSymbols.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 <iostream>
52 #include <vector>
53 #include <algorithm>
54 
55 #include <stdint.h>
56 #include <stdio.h>
57 #include <string.h>
58 
59 
60 
61 //******************************************************************************
62 // local includes
63 //******************************************************************************
64 
65 #include "SimpleSymbols.hpp"
66 
67 
68 
69 //******************************************************************************
70 // types
71 //******************************************************************************
72 
74  std::vector<SimpleSymbol*> simple_symbols;
75  std::string name;
76  bool sorted;
77 };
78 
79 
80 
81 //******************************************************************************
82 // private operations
83 //******************************************************************************
84 
85 static bool
87 {
88  return s1->addr() < s2->addr();
89 }
90 
91 
92 static std::string
94 {
95  std::string kind;
96  switch(_kind) {
97  case SimpleSymbolKind_Function: kind = "FUN"; break;
98  case SimpleSymbolKind_Data: kind = "DAT"; break;
99  case SimpleSymbolKind_Unknown: kind = "UNK"; break;
100  case SimpleSymbolKind_Other: default: kind = "OTR"; break;
101  }
102  return kind;
103 }
104 
105 
106 static std::string
108 {
109  std::string binding;
110  switch(_binding) {
111  case SimpleSymbolBinding_Local: binding = "LCL"; break;
112  case SimpleSymbolBinding_Global: binding = "GBL"; break;
113  case SimpleSymbolBinding_Weak: binding = " WK"; break;
114  case SimpleSymbolBinding_Unknown: binding = "UNK"; break;
115  case SimpleSymbolBinding_Other: default: binding = "OTR"; break;
116  }
117  return binding;
118 }
119 
120 
122 (
123  uint64_t __addr,
124  SimpleSymbolKind __kind,
125  SimpleSymbolBinding __binding,
126  const char *__name
127 ) : _addr(__addr), _kind(__kind), _binding(__binding), _name(__name)
128 {
129 }
130 
131 
132 void
134 {
135  std::cout << std::hex << _addr << std::dec
136  << " " << kindString(_kind) << " " << bindingString(_binding)
137  << " " << _name << std::endl;
138 }
139 
140 
141 
142 //******************************************************************************
143 // interface operations
144 //******************************************************************************
145 
147 {
148  R = new struct SimpleSymbolsRepr;
149  R->sorted = false;
150  R->name = name;
151 }
152 
153 
154 const std::string &
156 (
157  void
158 )
159 {
160  return R->name;
161 }
162 
163 
164 void
166 (
167  uint64_t addr,
168  SimpleSymbolKind kind,
169  SimpleSymbolBinding binding,
170  const char *name
171 )
172 {
173  R->sorted = false;
174  R->simple_symbols.push_back(new SimpleSymbol(addr, kind, binding, name));
175 }
176 
177 
178 uint64_t
180 {
181  return R->simple_symbols.size();
182 }
183 
184 
185 void
187 {
188  if (R->sorted == false) {
189  if (count() > 1) {
190  std::sort (R->simple_symbols.begin(), R->simple_symbols.end(), compareAddr);
191  }
192  R->sorted = true;
193  }
194 }
195 
196 
197 void
199 {
200  sort();
201  int nsyms = count();
202  int out = 0; // index of symbol to be output
203  for (int in = 1; in < nsyms; in++) {
204  if (R->simple_symbols[out]->addr() == R->simple_symbols[in]->addr()) {
205  // symbol[out] needs to be coalesced with symbol[in]
206  // note: coalesce produces the coalesced result in the first argument
207  coalesce_cb(R->simple_symbols[out], R->simple_symbols[in]);
208  } else {
209  R->simple_symbols[++out] = R->simple_symbols[in];
210  }
211  }
212  // erase vector after last symbol to be output
213  if (out < nsyms - 1) {
214  R->simple_symbols.erase(R->simple_symbols.begin() + out + 1,
215  R->simple_symbols.begin() + nsyms);
216  }
217 }
218 
219 
220 void
222 {
223  sort();
224  for (auto it = R->simple_symbols.begin();
225  it != R->simple_symbols.end(); ++it) {
226  (*it)->dump();
227  }
228 }
229 
230 
231 SimpleSymbol *
232 SimpleSymbols::find(uint64_t vma)
233 {
234  if (R->simple_symbols.size() <1)
235  return NULL;
236 
237  sort();
238 
239  int first = 0;
240  int last = R->simple_symbols.size() - 1;
241 
242  if (vma < R->simple_symbols[first]->addr()) {
243  return 0;
244  }
245 
246  if (vma >= R->simple_symbols[last]->addr()) {
247  return R->simple_symbols[last];
248  }
249 
250  for(;;) {
251  int mid = (first + last + 1) >> 1;
252  if (vma >= R->simple_symbols[mid]->addr()) {
253  first = mid;
254  } else if (vma < R->simple_symbols[mid]->addr()) {
255  last = mid;
256  }
257  if (last - first <= 1) {
258  return R->simple_symbols[first];
259  }
260  }
261  return NULL;
262 }
263 
264 
265 bool
267 (
268  uint64_t vma,
269  std::string &fnName
270 )
271 {
272  SimpleSymbol *symbol = find(vma);
273  if (symbol) fnName = symbol->name();
274  return symbol ? true : false;
275 }
276 
277 
278 void
280 (
281  SimpleSymbol *left,
282  const SimpleSymbol *right
283 )
284 {
285  if (left->binding() < right->binding()) {
286  left->setBinding(right->binding());
287  left->setKind(right->kind());
288  left->setName(right->name());
289  } else if (left->binding() == right->binding()) {
290  // prefer real names to pseudo-names
291  if (left->name()[0] == '<') left->setName(right->name());
292  else {
293  // prefer low-level names
294  if (right->name()[0] == '_') left->setName(right->name());
295  }
296  }
297 }
SimpleSymbolBinding
int find(char s1[], char s2[])
Definition: CStrUtil.cpp:177
SimpleSymbol(uint64_t __addr, SimpleSymbolKind __kind, SimpleSymbolBinding __binding, const char *__name)
std::vector< SimpleSymbol * > simple_symbols
void coalesce(SimpleSymbolsCoalesceCallback coalesce)
uint64_t count()
void setKind(SimpleSymbolKind __kind)
SimpleSymbol * find(uint64_t vma)
static std::string bindingString(SimpleSymbolBinding _binding)
void add(uint64_t addr, SimpleSymbolKind kind, SimpleSymbolBinding binding, const char *name)
uint64_t addr() const
void() SimpleSymbolsCoalesceCallback(SimpleSymbol *left, const SimpleSymbol *right)
SimpleSymbolBinding binding() const
const std::string & name() const
SimpleSymbols(const char *name)
void setName(std::string __name)
SimpleSymbolKind kind() const
static bool compareAddr(SimpleSymbol *s1, SimpleSymbol *s2)
SimpleSymbolKind
#define NULL
Definition: ElfHelper.cpp:85
static std::string kindString(SimpleSymbolKind _kind)
void setBinding(SimpleSymbolBinding __binding)
bool findEnclosingFunction(uint64_t vma, std::string &fnName)
cct_addr_t * addr
Definition: cct.c:130
static char * last
Definition: tokenize.c:65
const std::string & name()
void chooseHighestBinding(SimpleSymbol *left, const SimpleSymbol *right)