]>
Commit | Line | Data |
---|---|---|
76bdc726 | 1 | /* Copyright (C) 2021-2023 Free Software Foundation, Inc. |
bb368aad VM |
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 | } |