1 /* Copyright (C) 2021-2023 Free Software Foundation, Inc.
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #ifndef _HISTABLE_H
22 #define _HISTABLE_H
23
24 //
25 // The Histable class hierarchy is used to build up a representation of
26 // the codeobjects (functions, modules, loadObjects, etc.) that make up the
27 // text address space of a program. The hierarchy is as follows:
28 //
29 // Histable (public)
30 // LoadObject (public)
31 // Module (public)
32 // Function (public)
33 //
34 // Dataobjects are objects from the data address space of a program.
35 // The reason for calling the base class "Histable" is because these
36 // objects are all valid objects for computing histograms on.
37
38 // A Histable object represents an object in the program text or data.
39
40 #include "dbe_structs.h"
41 #include "Emsg.h"
42 #include "Expression.h"
43
44 class DataObject;
45 class Function;
46 class SourceFile;
47 class DbeFile;
48 class DbeLine;
49 template <class ITEM> class Vector;
50
51 class Histable
52 {
53 friend class Hist_data;
54 public:
55
56 enum Type
57 {
58 INSTR, LINE, FUNCTION, MODULE, LOADOBJECT,
59 EADDR, MEMOBJ, INDEXOBJ, PAGE, DOBJECT,
60 SOURCEFILE, IOACTFILE, IOACTVFD, IOCALLSTACK,
61 HEAPCALLSTACK, EXPERIMENT, OTHER
62 };
63
64 // NameFormat for functions and function based objects
65
66 enum NameFormat
67 {
68 NA, LONG, SHORT, MANGLED, SONAME = 0x10
69 };
70
71 static NameFormat
72 make_fmt (int fnfmt, bool sofmt = false)
73 {
74 return (NameFormat) (sofmt ? fnfmt | SONAME : fnfmt);
75 }
76
77 static int
78 fname_fmt (NameFormat fmt)
79 {
80 return (fmt & ~SONAME);
81 }
82
83 static bool
84 soname_fmt (NameFormat fmt)
85 {
86 return (fmt & SONAME);
87 }
88
89 Histable ();
90 char *dump ();
91
92 virtual ~Histable ();
93
94 virtual char *
95 get_name (NameFormat = NA)
96 {
97 return name; // Return the name of the object
98 }
99
100 virtual void
101 set_name (char * _name)
102 {
103 name = _name;
104 }
105
106 virtual void set_name_from_context (Expression::Context *) { }
107 virtual Type get_type () = 0;
108
109 virtual int64_t
110 get_size ()
111 {
112 return 0;
113 }
114
115 virtual uint64_t
116 get_addr ()
117 {
118 return 0ULL;
119 }
120
121 virtual Vector<Histable*> *get_comparable_objs ();
122 Histable *get_compare_obj ();
123
124 virtual Histable *
125 convertto (Type, Histable* = NULL)
126 {
127 return this;
128 }
129
130 Vector<Histable*> *comparable_objs;
131 int64_t id; // A unique id of this object, within its specific Type
132
133 protected:
134 char *name; // Object name
135 int phaseCompareIdx;
136 void update_comparable_objs ();
137 void dump_comparable_objs ();
138 char *type_to_string ();
139 void delete_comparable_objs ();
140 };
141
142 typedef Histable::Type Histable_type;
143
144 // An Other object represents some random histable object
145 class Other : public Histable
146 {
147 public:
148
149 virtual Type
150 get_type ()
151 {
152 return OTHER;
153 }
154
155 uint64_t value64;
156 uint32_t tag;
157 };
158
159 // DbeInstr represents an instruction.
160 //
161 // Used by Analyzer for: Disassembly, PCs, Timeline, and Event tabs.
162 //
163 class DbeInstr : public Histable
164 {
165 public:
166 DbeInstr (uint64_t _id, int _flags, Function *_func, uint64_t _addr);
167
168 virtual Type
169 get_type ()
170 {
171 return INSTR;
172 }
173
174 virtual char *get_name (NameFormat = NA);
175 virtual int64_t get_size ();
176 virtual uint64_t get_addr ();
177 virtual Histable *convertto (Type type, Histable *obj = NULL);
178 DbeLine *mapPCtoLine (SourceFile *sf);
179 void add_inlined_info (StringBuilder *sb);
180 char *get_descriptor ();
181 int pc_cmp (DbeInstr *instr2);
182
183 uint64_t addr;
184 uint64_t img_offset; // file offset of the image
185 int flags;
186 Function *func;
187 int lineno;
188 int inlinedInd;
189 int64_t size;
190 bool isUsed;
191
192 private:
193 NameFormat current_name_format;
194 };
195
196 class DbeEA : public Histable
197 {
198 public:
199
200 DbeEA (DataObject *_dobj, Vaddr _eaddr)
201 {
202 dobj = _dobj;
203 eaddr = _eaddr;
204 };
205
206 virtual Type
207 get_type ()
208 {
209 return EADDR;
210 };
211
212 virtual int64_t
213 get_size ()
214 {
215 return 1;
216 };
217
218 virtual uint64_t
219 get_addr ()
220 {
221 return eaddr;
222 };
223
224 virtual char *get_name (NameFormat = NA);
225 virtual Histable *convertto (Type type, Histable *obj = NULL);
226
227 DataObject *dobj;
228 Vaddr eaddr;
229 };
230
231 // DbeLine represents a line in a source file.
232 //
233 // For each top-level DbeLine instance, there are three DbeLine subtypes:
234 //
235 // A The top-level DbeLine is associated with a sourceFile & lineno, but
236 // not any particular function. This form of DbeLine is used
237 // to represent Analyzer Source tab lines.
238 //
239 // B Function-specific lines, those associated with a function in addition
240 // to the the sourceFile & lineno, are stored in a linked list.
241 // (see "dbeline_func_next").
242 // This subtype is used to differentiate a line found in #included source
243 // that is referenced by multiple functions.
244 // It is used in the Analyzer Lines tab.
245 //
246 // C Function-specific "lines" that don't have line number info are referenced
247 // from each linked-list element's "dbeline_func_pseudo" field.
248 // This subtype is needed when a binary doesn't identify line numbers.
249 // It is used in the Analyzer Lines tab.
250 //
251 // When the user switches views between tabs, a selected object in the old
252 // tab must be translated to an approprate object in the new tab.
253 // When switching to the Source Tab, the top-level DbeLine (dbeline_base)
254 // should be used.
255 // When switching to the Lines Tab, a function-specific dbeline_func_*
256 // should be used.
257 //
258
259 class DbeLine : public Histable
260 {
261 public:
262
263 enum Flag
264 {
265 OMPPRAGMA = 1
266 };
267
268 DbeLine (Function *_func, SourceFile *sf, int _lineno);
269 virtual ~DbeLine ();
270 virtual char *get_name (NameFormat = NA);
271 virtual int64_t get_size ();
272 virtual uint64_t get_addr ();
273 virtual Histable *convertto (Type type, Histable *obj = NULL);
274
275 void init_Offset (uint64_t p_offset);
276 int line_cmp (DbeLine *dbl);
277
278 virtual Type
279 get_type ()
280 {
281 return LINE;
282 }
283
284 void
285 set_flag (Flag flag)
286 {
287 flags |= flag;
288 }
289
290 bool
291 is_set (Flag flag)
292 {
293 return (flags & flag) != 0;
294 }
295
296 Function *func; // note: will be NULL in the base (head) dbeline
297 int lineno;
298 int64_t size;
299 SourceFile *sourceFile; // Default source file
300 SourceFile *include; // included source file or NULL
301
302 DbeLine *dbeline_base;
303 // Head of list, a dbeline associated with sourceFile & lineno, but not func:
304 // dbeline_base->lineno: non-zero
305 // dbeline_base->sourceFile: non-null
306 // dbeline_base->func: NULL
307 // dbeline_base->dbeline_base: this
308 // dbeline_base->dbeline_func_next: first func-specific dbeline
309
310 DbeLine *dbeline_func_next;
311 // If non-null, pointer to a function-specific dbeline where:
312 // dbeline_func_next->lineno: same as dbeline_base->lineno
313 // dbeline_func_next->sourceFile: same as dbeline_base->sourceFile
314 // dbeline_func_next->func: pointer to unique function
315 // dbeline_func_next->dbeline_base: head of the linked list.
316 // dbeline_func_next->dbeline_func_next: next function-specific dbeline.
317
318 private:
319 int current_name_format;
320 int64_t offset;
321 int flags;
322 };
323
324 class HistableFile : public Histable, public DbeMessages
325 {
326 public:
327 HistableFile ();
328
329 bool isUsed;
330 DbeFile *dbeFile;
331 };
332
333 #endif /* _HISTABLE_H */