1 /* Copyright (C) 2021 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
fname_fmt(NameFormat fmt)78   fname_fmt (NameFormat fmt)
79   {
80     return (fmt & ~SONAME);
81   }
82 
83   static bool
soname_fmt(NameFormat fmt)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
set_name(char * _name)101   set_name (char * _name)
102   {
103     name = _name;
104   }
105 
set_name_from_context(Expression::Context *)106   virtual void set_name_from_context (Expression::Context *) { }
107   virtual Type get_type () = 0;
108 
109   virtual int64_t
get_size()110   get_size ()
111   {
112     return 0;
113   }
114 
115   virtual uint64_t
get_addr()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
get_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
get_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 
DbeEA(DataObject * _dobj,Vaddr _eaddr)200   DbeEA (DataObject *_dobj, Vaddr _eaddr)
201   {
202     dobj = _dobj;
203     eaddr = _eaddr;
204   };
205 
206   virtual Type
get_type()207   get_type ()
208   {
209     return EADDR;
210   };
211 
212   virtual int64_t
get_size()213   get_size ()
214   {
215     return 1;
216   };
217 
218   virtual uint64_t
get_addr()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
get_type()279   get_type ()
280   {
281     return LINE;
282   }
283 
284   void
set_flag(Flag flag)285   set_flag (Flag flag)
286   {
287     flags |= flag;
288   }
289 
290   bool
is_set(Flag flag)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 */
334