xref: /netbsd-src/external/gpl3/gdb/dist/gdb/dwarf2/attribute.c (revision 4439cfd0acf9c7dc90625e5cd83b2317a9ab8967)
1 /* DWARF attributes
2 
3    Copyright (C) 1994-2024 Free Software Foundation, Inc.
4 
5    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
6    Inc.  with support from Florida State University (under contract
7    with the Ada Joint Program Office), and Silicon Graphics, Inc.
8    Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
9    based on Fred Fish's (Cygnus Support) implementation of DWARF 1
10    support.
11 
12    This file is part of GDB.
13 
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
26 
27 #include "dwarf2/attribute.h"
28 #include "dwarf2/stringify.h"
29 #include "complaints.h"
30 
31 /* See attribute.h.  */
32 
33 unrelocated_addr
34 attribute::as_address () const
35 {
36   unrelocated_addr addr;
37 
38   gdb_assert (!requires_reprocessing);
39 
40   if (form != DW_FORM_addr && form != DW_FORM_addrx
41       && form != DW_FORM_GNU_addr_index)
42     {
43       /* Aside from a few clearly defined exceptions, attributes that
44 	 contain an address must always be in DW_FORM_addr form.
45 	 Unfortunately, some compilers happen to be violating this
46 	 requirement by encoding addresses using other forms, such
47 	 as DW_FORM_data4 for example.  For those broken compilers,
48 	 we try to do our best, without any guarantee of success,
49 	 to interpret the address correctly.  It would also be nice
50 	 to generate a complaint, but that would require us to maintain
51 	 a list of legitimate cases where a non-address form is allowed,
52 	 as well as update callers to pass in at least the CU's DWARF
53 	 version.  This is more overhead than what we're willing to
54 	 expand for a pretty rare case.  */
55       addr = (unrelocated_addr) u.unsnd;
56     }
57   else
58     addr = u.addr;
59 
60   return addr;
61 }
62 
63 /* See attribute.h.  */
64 
65 bool
66 attribute::form_is_string () const
67 {
68   return (form == DW_FORM_strp || form == DW_FORM_line_strp
69 	  || form == DW_FORM_string
70 	  || form == DW_FORM_strx
71 	  || form == DW_FORM_strx1
72 	  || form == DW_FORM_strx2
73 	  || form == DW_FORM_strx3
74 	  || form == DW_FORM_strx4
75 	  || form == DW_FORM_GNU_str_index
76 	  || form == DW_FORM_GNU_strp_alt);
77 }
78 
79 /* See attribute.h.  */
80 
81 const char *
82 attribute::as_string () const
83 {
84   gdb_assert (!requires_reprocessing);
85   if (form_is_string ())
86     return u.str;
87   return nullptr;
88 }
89 
90 /* See attribute.h.  */
91 
92 bool
93 attribute::form_is_block () const
94 {
95   return (form == DW_FORM_block1
96 	  || form == DW_FORM_block2
97 	  || form == DW_FORM_block4
98 	  || form == DW_FORM_block
99 	  || form == DW_FORM_exprloc
100 	  || form == DW_FORM_data16);
101 }
102 
103 /* See attribute.h.  */
104 
105 bool
106 attribute::form_is_section_offset () const
107 {
108   return (form == DW_FORM_data4
109 	  || form == DW_FORM_data8
110 	  || form == DW_FORM_sec_offset
111 	  || form == DW_FORM_loclistx);
112 }
113 
114 /* See attribute.h.  */
115 
116 bool
117 attribute::form_is_constant () const
118 {
119   switch (form)
120     {
121     case DW_FORM_sdata:
122     case DW_FORM_udata:
123     case DW_FORM_data1:
124     case DW_FORM_data2:
125     case DW_FORM_data4:
126     case DW_FORM_data8:
127     case DW_FORM_implicit_const:
128       return true;
129     default:
130       return false;
131     }
132 }
133 
134 /* See attribute.h.  */
135 
136 void
137 attribute::get_ref_die_offset_complaint () const
138 {
139   complaint (_("unsupported die ref attribute form: '%s'"),
140 	     dwarf_form_name (form));
141 }
142 
143 /* See attribute.h.  */
144 
145 LONGEST
146 attribute::constant_value (int default_value) const
147 {
148   if (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
149     return u.snd;
150   else if (form == DW_FORM_udata
151 	   || form == DW_FORM_data1
152 	   || form == DW_FORM_data2
153 	   || form == DW_FORM_data4
154 	   || form == DW_FORM_data8)
155     return u.unsnd;
156   else
157     {
158       /* For DW_FORM_data16 see attribute::form_is_constant.  */
159       complaint (_("Attribute value is not a constant (%s)"),
160 		 dwarf_form_name (form));
161       return default_value;
162     }
163 }
164 
165 /* See attribute.h.  */
166 
167 bool
168 attribute::form_is_unsigned () const
169 {
170   return (form == DW_FORM_ref_addr
171 	  || form == DW_FORM_GNU_ref_alt
172 	  || form == DW_FORM_data2
173 	  || form == DW_FORM_data4
174 	  || form == DW_FORM_data8
175 	  || form == DW_FORM_sec_offset
176 	  || form == DW_FORM_data1
177 	  || form == DW_FORM_flag
178 	  || form == DW_FORM_flag_present
179 	  || form == DW_FORM_udata
180 	  || form == DW_FORM_rnglistx
181 	  || form == DW_FORM_loclistx
182 	  || form == DW_FORM_ref1
183 	  || form == DW_FORM_ref2
184 	  || form == DW_FORM_ref4
185 	  || form == DW_FORM_ref8
186 	  || form == DW_FORM_ref_udata);
187 }
188 
189 /* See attribute.h.  */
190 
191 bool
192 attribute::form_is_signed () const
193 {
194   return form == DW_FORM_sdata || form == DW_FORM_implicit_const;
195 }
196 
197 /* See attribute.h.  */
198 
199 bool
200 attribute::form_requires_reprocessing () const
201 {
202   return (form == DW_FORM_strx
203 	  || form == DW_FORM_strx1
204 	  || form == DW_FORM_strx2
205 	  || form == DW_FORM_strx3
206 	  || form == DW_FORM_strx4
207 	  || form == DW_FORM_GNU_str_index
208 	  || form == DW_FORM_addrx
209 	  || form == DW_FORM_GNU_addr_index
210 	  || form == DW_FORM_rnglistx
211 	  || form == DW_FORM_loclistx);
212 }
213 
214 /* See attribute.h.  */
215 
216 dwarf_defaulted_attribute
217 attribute::defaulted () const
218 {
219   LONGEST value = constant_value (-1);
220 
221   switch (value)
222     {
223     case DW_DEFAULTED_no:
224     case DW_DEFAULTED_in_class:
225     case DW_DEFAULTED_out_of_class:
226       return (dwarf_defaulted_attribute) value;
227     }
228 
229   /* If the form was not constant, we already complained in
230      constant_value, so there's no need to complain again.  */
231   if (form_is_constant ())
232     complaint (_("unrecognized DW_AT_defaulted value (%s)"),
233 	       plongest (value));
234   return DW_DEFAULTED_no;
235 }
236 
237 /* See attribute.h.  */
238 
239 dwarf_virtuality_attribute
240 attribute::as_virtuality () const
241 {
242   LONGEST value = constant_value (-1);
243 
244   switch (value)
245     {
246     case DW_VIRTUALITY_none:
247     case DW_VIRTUALITY_virtual:
248     case DW_VIRTUALITY_pure_virtual:
249       return (dwarf_virtuality_attribute) value;
250     }
251 
252   /* If the form was not constant, we already complained in
253      constant_value, so there's no need to complain again.  */
254   if (form_is_constant ())
255     complaint (_("unrecognized DW_AT_virtuality value (%s)"),
256 	       plongest (value));
257   return DW_VIRTUALITY_none;
258 }
259 
260 /* See attribute.h.  */
261 
262 bool
263 attribute::as_boolean () const
264 {
265   if (form == DW_FORM_flag_present)
266     return true;
267   else if (form == DW_FORM_flag)
268     return u.unsnd != 0;
269   return constant_value (0) != 0;
270 }
271