8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / tools / ctf / dwarf / common / dwarf_util.h
blob4046bb2478869f118493a429e1e114cb528b5fef
1 #ifndef DWARF_UTIL_H
2 #define DWARF_UTIL_H
3 /*
5 Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved.
6 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of version 2.1 of the GNU Lesser General Public License
10 as published by the Free Software Foundation.
12 This program is distributed in the hope that it would be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 Further, this software is distributed without any warranty that it is
17 free of the rightful claim of any third person regarding infringement
18 or the like. Any license provided herein, whether implied or
19 otherwise, applies only to this software file. Patent licenses, if
20 any, provided herein do not apply to combinations of this program with
21 other software, or any other product whatsoever.
23 You should have received a copy of the GNU Lesser General Public
24 License along with this program; if not, write the Free Software
25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26 USA.
28 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
29 Mountain View, CA 94043, or:
31 http://www.sgi.com
33 For further information regarding this notice, see:
35 http://oss.sgi.com/projects/GenInfo/NoticeExplan
38 /* The address of the Free Software Foundation is
39 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
40 Boston, MA 02110-1301, USA.
41 SGI has moved from the Crittenden Lane address.
48 Decodes unsigned leb128 encoded numbers.
49 Make sure ptr is a pointer to a 1-byte type.
50 In 2003 and earlier this was a hand-inlined
51 version of _dwarf_decode_u_leb128() which did
52 not work correctly if Dwarf_Word was 64 bits.
54 #define DECODE_LEB128_UWORD(ptr, value) \
55 do { \
56 Dwarf_Word uleblen; \
57 value = _dwarf_decode_u_leb128(ptr,&uleblen); \
58 ptr += uleblen; \
59 } while (0)
62 Decodes signed leb128 encoded numbers.
63 Make sure ptr is a pointer to a 1-byte type.
64 In 2003 and earlier this was a hand-inlined
65 version of _dwarf_decode_s_leb128() which did
66 not work correctly if Dwarf_Word was 64 bits.
69 #define DECODE_LEB128_SWORD(ptr, value) \
70 do { \
71 Dwarf_Word sleblen; \
72 value = _dwarf_decode_s_leb128(ptr,&sleblen); \
73 ptr += sleblen; \
74 } while(0)
78 Skips leb128_encoded numbers that are guaranteed
79 to be no more than 4 bytes long. Same for both
80 signed and unsigned numbers.
82 #define SKIP_LEB128_WORD(ptr) \
83 do{ if ((*(ptr++) & 0x80) != 0) { \
84 if ((*(ptr++) & 0x80) != 0) { \
85 if ((*(ptr++) & 0x80) != 0) { \
86 if ((*(ptr++) & 0x80) != 0) { \
87 } \
88 } \
89 } \
90 } } while (0)
93 #define CHECK_DIE(die, error_ret_value) \
94 do {if (die == NULL) { \
95 _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
96 return(error_ret_value); \
97 } \
98 if (die->di_cu_context == NULL) { \
99 _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
100 return(error_ret_value); \
102 if (die->di_cu_context->cc_dbg == NULL) { \
103 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
104 return(error_ret_value); \
106 } while (0)
110 Reads 'source' for 'length' bytes from unaligned addr.
112 Avoids any constant-in-conditional warnings and
113 avoids a test in the generated code (for non-const cases,
114 which are in the majority.)
115 Uses a temp to avoid the test.
116 The decl here should avoid any problem of size in the temp.
117 This code is ENDIAN DEPENDENT
118 The memcpy args are the endian issue.
120 typedef Dwarf_Unsigned BIGGEST_UINT;
122 #ifdef WORDS_BIGENDIAN
123 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
124 do { \
125 BIGGEST_UINT _ltmp = 0; \
126 dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
127 source, length) ; \
128 dest = (desttype)_ltmp; \
129 } while (0)
133 This macro sign-extends a variable depending on the length.
134 It fills the bytes between the size of the destination and
135 the length with appropriate padding.
136 This code is ENDIAN DEPENDENT but dependent only
137 on host endianness, not object file endianness.
138 The memcpy args are the issue.
140 #define SIGN_EXTEND(dest, length) \
141 do {if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) {\
142 memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \
143 sizeof(dest) - length); \
145 } while (0)
146 #else /* LITTLE ENDIAN */
148 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
149 do { \
150 BIGGEST_UINT _ltmp = 0; \
151 dbg->de_copy_word( (char *)(&_ltmp) , \
152 source, length) ; \
153 dest = (desttype)_ltmp; \
154 } while (0)
158 This macro sign-extends a variable depending on the length.
159 It fills the bytes between the size of the destination and
160 the length with appropriate padding.
161 This code is ENDIAN DEPENDENT but dependent only
162 on host endianness, not object file endianness.
163 The memcpy args are the issue.
165 #define SIGN_EXTEND(dest, length) \
166 do {if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) {\
167 memcpy((char *)&dest+length, \
168 "\xff\xff\xff\xff\xff\xff\xff\xff", \
169 sizeof(dest) - length); \
171 } while (0)
173 #endif /* ! LITTLE_ENDIAN */
178 READ_AREA LENGTH reads the length (the older way
179 of pure 32 or 64 bit
180 or the new proposed dwarfv2.1 64bit-extension way)
182 It reads the bits from where rw_src_data_p points to
183 and updates the rw_src_data_p to point past what was just read.
185 It updates w_length_size (to the size of an offset, either 4 or 8)
186 and w_exten_size (set 0 unless this frame has the DWARF3,4 64bit
187 extension, in which case w_exten_size is set to 4).
189 r_dbg is just the current dbg pointer.
190 w_target is the output length field.
191 r_targtype is the output type. Always Dwarf_Unsigned so far.
194 /* This one handles the v2.1 64bit extension
195 and 32bit (and MIPS fixed 64 bit via the
196 dwarf_init-set r_dbg->de_length_size)..
197 It does not recognize any but the one distingushed value
198 (the only one with defined meaning).
199 It assumes that no CU will have a length
200 0xffffffxx (32bit length)
202 0xffffffxx xxxxxxxx (64bit length)
203 which makes possible auto-detection of the extension.
205 This depends on knowing that only a non-zero length
206 is legitimate (AFAICT), and for IRIX non-standard -64
207 dwarf that the first 32 bits of the 64bit offset will be
208 zero (because the compiler could not handle a truly large
209 value as of Jan 2003 and because no app has that much debug
210 info anyway, at least not in the IRIX case).
212 At present not testing for '64bit elf' here as that
213 does not seem necessary (none of the 64bit length seems
214 appropriate unless it's ident[EI_CLASS] == ELFCLASS64).
216 # define READ_AREA_LENGTH(r_dbg,w_target,r_targtype, \
217 rw_src_data_p,w_length_size,w_exten_size) \
218 do { READ_UNALIGNED(r_dbg,w_target,r_targtype, \
219 rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE); \
220 if(w_target == DISTINGUISHED_VALUE) { \
221 /* dwarf3 64bit extension */ \
222 w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \
223 rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \
224 w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \
225 READ_UNALIGNED(r_dbg,w_target,r_targtype, \
226 rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);\
227 rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \
228 } else { \
229 if(w_target == 0 && r_dbg->de_big_endian_object) { \
230 /* IRIX 64 bit, big endian. This test */ \
231 /* is not a truly precise test, a precise test */ \
232 /* would check if the target was IRIX. */ \
233 READ_UNALIGNED(r_dbg,w_target,r_targtype, \
234 rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE); \
235 w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \
236 rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \
237 w_exten_size = 0; \
238 } else { \
239 /* standard 32 bit dwarf2/dwarf3 */ \
240 w_exten_size = 0; \
241 w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \
242 rw_src_data_p += w_length_size; \
244 } } while(0)
246 Dwarf_Unsigned
247 _dwarf_decode_u_leb128(Dwarf_Small * leb128,
248 Dwarf_Word * leb128_length);
250 Dwarf_Signed
251 _dwarf_decode_s_leb128(Dwarf_Small * leb128,
252 Dwarf_Word * leb128_length);
254 Dwarf_Unsigned
255 _dwarf_get_size_of_val(Dwarf_Debug dbg,
256 Dwarf_Unsigned form,
257 Dwarf_Half address_size,
258 Dwarf_Small * val_ptr,
259 int v_length_size);
261 struct Dwarf_Hash_Table_Entry_s;
262 /* This single struct is the base for the hash table.
263 The intent is that once the total_abbrev_count across
264 all the entries is greater than 10*current_table_entry_count
265 one should build a new Dwarf_Hash_Table_Base_s, rehash
266 all the existing entries, and delete the old table and entries.
267 (10 is a heuristic, nothing magic about it, but once the
268 count gets to 30 or 40 times current_table_entry_count
269 things really slow down a lot. One (500MB) application had
270 127000 abbreviations in one compilation unit)
271 The incoming 'code' is an abbrev number and those simply
272 increase linearly so the hashing is perfect always.
274 struct Dwarf_Hash_Table_s {
275 unsigned long tb_table_entry_count;
276 unsigned long tb_total_abbrev_count;
277 /* Each table entry is a list of abbreviations. */
278 struct Dwarf_Hash_Table_Entry_s *tb_entries;
282 This struct is used to build a hash table for the
283 abbreviation codes for a compile-unit.
285 struct Dwarf_Hash_Table_Entry_s {
286 Dwarf_Abbrev_List at_head;
291 Dwarf_Abbrev_List
292 _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
293 Dwarf_Unsigned code);
296 /* return 1 if string ends before 'endptr' else
297 ** return 0 meaning string is not properly terminated.
298 ** Presumption is the 'endptr' pts to end of some dwarf section data.
300 int _dwarf_string_valid(void *startptr, void *endptr);
302 Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug,
303 Dwarf_Unsigned offset);
304 Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug);
306 int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
307 void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,
308 struct Dwarf_Hash_Table_s* hash_table);
309 int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
311 #endif /* DWARF_UTIL_H */