]> Git Repo - binutils.git/blob - gprofng/src/DataObject.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / DataObject.cc
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 #include "config.h"
22 #include <assert.h>
23 #include <string.h>
24 #include <ctype.h>
25
26 #include "util.h"
27 #include "DbeSession.h"
28 #include "Application.h"
29 #include "DataObject.h"
30 #include "Module.h"
31 #include "debug.h"
32
33 DataObject::DataObject ()
34 {
35   name = NULL;
36   parent = NULL;
37   master = NULL;
38   _unannotated_name = NULL;
39   _typename = NULL;
40   _instname = NULL;
41   scope = NULL;
42   EAs = new Vector<DbeEA*>;
43   size = 0;
44   offset = (uint64_t) (-1);
45 }
46
47 DataObject::~DataObject ()
48 {
49   free (_unannotated_name);
50   free (_typename);
51   free (_instname);
52   EAs->destroy ();
53   delete EAs;
54 }
55
56 // get_addr() doesn't return an actual address for a DataObject
57 // but rather synthesises an address-like identifier tuple.
58 // XXXX since an aggregate and its first element have identical tuples
59 // may need to arrange for special-purpose sorting "by address"
60 uint64_t
61 DataObject::get_addr ()
62 {
63   uint64_t addr;
64   if (parent && parent->get_typename ())
65     addr = MAKE_ADDRESS (parent->id, offset);   // element
66   else if (parent)
67     addr = MAKE_ADDRESS (parent->id, id) | 0x8000000000000000ULL; // Scalar, Unknown
68   else if (id == dbeSession->get_Scalars_DataObject ()->id)
69     addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Scalar aggregate
70   else if (id == dbeSession->get_Unknown_DataObject ()->id)
71     addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Unknown aggregate
72   else
73     addr = MAKE_ADDRESS (id, 0);     // aggregate
74   return addr;
75 }
76
77 Histable *
78 DataObject::convertto (Histable_type type, Histable *)
79 {
80   return type == DOBJECT ? this : NULL;
81 }
82
83 char
84 DataObject::get_offset_mark ()
85 {
86   enum
87   {
88     blocksize = 32
89   };
90
91   if (size == 0 || offset == -1)
92     return '?';     // undefined
93   if (size > blocksize)
94     return '#';     // requires multiple blocks
95   if (size == blocksize && (offset % blocksize == 0))
96     return '<';     // fits block entirely
97   if (offset % blocksize == 0)
98     return '/';     // starts block
99   if ((offset + size) % blocksize == 0)
100     return '\\';    // closes block
101   if (offset / blocksize == ((offset + size) / blocksize))
102     return '|';     // inside block
103   return 'X';       // crosses blocks unnecessarily
104 }
105
106 char *
107 DataObject::get_offset_name ()
108 {
109   char *offset_name;
110   if (parent && parent->get_typename ()) // element
111     offset_name = dbe_sprintf (GTXT ("%c%+6lld .{%s %s}"),
112                                get_offset_mark (), (long long) offset,
113                                _typename ? _typename : GTXT ("NO_TYPE"),
114                                _instname ? _instname : GTXT ("-")); // "NO_NAME"
115   else if ((offset != -1) && (offset > 0)) // filler
116     offset_name = dbe_sprintf (GTXT ("%c%+6lld %s"), get_offset_mark (),
117                                (long long) offset, get_name ());
118   else if (parent) // Scalar/Unknown element
119     offset_name = dbe_sprintf (GTXT ("        .%s"), get_unannotated_name ());
120   else // aggregate
121     offset_name = dbe_strdup (get_name ());
122   return offset_name;
123 }
124
125 void
126 DataObject::set_dobjname (char *type_name, char *inst_name)
127 {
128   _unannotated_name = _typename = _instname = NULL;
129   if (inst_name)
130     _instname = dbe_strdup (inst_name);
131
132   char *buf;
133   if (parent == dbeSession->get_Scalars_DataObject ())
134     {
135       if (type_name)
136         _typename = dbe_strdup (type_name);
137       _unannotated_name = dbe_sprintf (NTXT ("{%s %s}"), type_name,
138                                        inst_name ? inst_name : NTXT ("-"));
139       buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
140     }
141   else if (parent == dbeSession->get_Unknown_DataObject ())
142     {
143       _unannotated_name = dbe_strdup (type_name);
144       buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
145     }
146   else
147     {
148       if (type_name)
149         _typename = dbe_strdup (type_name);
150       if (parent && parent->get_typename ())
151         buf = dbe_sprintf (NTXT ("%s.{%s %s}"),
152                            parent->get_name () ? parent->get_name () : NTXT ("ORPHAN"),
153                            type_name ? type_name : NTXT ("NO_TYPE"),
154                            inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
155       else
156         buf = dbe_sprintf (NTXT ("{%s %s}"),
157                            type_name ? type_name : NTXT ("NO_TYPE"),
158                            inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
159     }
160   name = buf;
161   dbeSession->dobj_updateHT (this);
162 }
163
164 void
165 DataObject::set_name (char *string)
166 {
167   name = dbe_strdup (string);
168   dbeSession->dobj_updateHT (this);
169 }
170
171 DbeEA *
172 DataObject::find_dbeEA (Vaddr EA)
173 {
174   DbeEA *dbeEA;
175   int left = 0;
176   int right = EAs->size () - 1;
177   while (left <= right)
178     {
179       int index = (left + right) / 2;
180       dbeEA = EAs->fetch (index);
181       if (EA < dbeEA->eaddr)
182         right = index - 1;
183       else if (EA > dbeEA->eaddr)
184         left = index + 1;
185       else
186         return dbeEA;
187     }
188
189   // None found, create a new one
190   dbeEA = new DbeEA (this, EA);
191   EAs->insert (left, dbeEA);
192   return dbeEA;
193 }
This page took 0.035159 seconds and 4 git commands to generate.