xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_util.h (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi #ifndef DWARF_UTIL_H
2bc1f688bSRobert Mustacchi #define DWARF_UTIL_H
3bc1f688bSRobert Mustacchi /*
4bc1f688bSRobert Mustacchi 
5bc1f688bSRobert Mustacchi   Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
6*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved.
7*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved
8bc1f688bSRobert Mustacchi 
9*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it
10*4d9fdb46SRobert Mustacchi   and/or modify it under the terms of version 2.1 of the
11*4d9fdb46SRobert Mustacchi   GNU Lesser General Public License as published by the Free
12*4d9fdb46SRobert Mustacchi   Software Foundation.
13bc1f688bSRobert Mustacchi 
14*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be
15*4d9fdb46SRobert Mustacchi   useful, but WITHOUT ANY WARRANTY; without even the implied
16*4d9fdb46SRobert Mustacchi   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17*4d9fdb46SRobert Mustacchi   PURPOSE.
18bc1f688bSRobert Mustacchi 
19*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty
20*4d9fdb46SRobert Mustacchi   that it is free of the rightful claim of any third person
21*4d9fdb46SRobert Mustacchi   regarding infringement or the like.  Any license provided
22*4d9fdb46SRobert Mustacchi   herein, whether implied or otherwise, applies only to this
23*4d9fdb46SRobert Mustacchi   software file.  Patent licenses, if any, provided herein
24*4d9fdb46SRobert Mustacchi   do not apply to combinations of this program with other
25*4d9fdb46SRobert Mustacchi   software, or any other product whatsoever.
26bc1f688bSRobert Mustacchi 
27*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General
28*4d9fdb46SRobert Mustacchi   Public License along with this program; if not, write the
29*4d9fdb46SRobert Mustacchi   Free Software Foundation, Inc., 51 Franklin Street - Fifth
30*4d9fdb46SRobert Mustacchi   Floor, Boston MA 02110-1301, USA.
31bc1f688bSRobert Mustacchi 
32bc1f688bSRobert Mustacchi */
33bc1f688bSRobert Mustacchi 
34bc1f688bSRobert Mustacchi /*
35bc1f688bSRobert Mustacchi     Decodes unsigned leb128 encoded numbers.
36bc1f688bSRobert Mustacchi     Make sure ptr is a pointer to a 1-byte type.
37bc1f688bSRobert Mustacchi     In 2003 and earlier this was a hand-inlined
38bc1f688bSRobert Mustacchi     version of _dwarf_decode_u_leb128() which did
39*4d9fdb46SRobert Mustacchi     not work correctly if Dwarf_Unsigned was 64 bits.
40*4d9fdb46SRobert Mustacchi 
41*4d9fdb46SRobert Mustacchi     April 2016: now uses a reader that is careful.
42*4d9fdb46SRobert Mustacchi     'return' only in case of error
43*4d9fdb46SRobert Mustacchi     else falls through.
44bc1f688bSRobert Mustacchi */
45*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \
46bc1f688bSRobert Mustacchi     do {                                              \
47*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lu_leblen = 0;                     \
48*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lu_local = 0;                  \
49*4d9fdb46SRobert Mustacchi         int lu_res = 0;                               \
50*4d9fdb46SRobert Mustacchi         lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \
51*4d9fdb46SRobert Mustacchi         if (lu_res == DW_DLV_ERROR) {                 \
52*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);  \
53*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                      \
54*4d9fdb46SRobert Mustacchi         }                                             \
55*4d9fdb46SRobert Mustacchi         value = lu_local;                             \
56*4d9fdb46SRobert Mustacchi         ptr += lu_leblen;                             \
57*4d9fdb46SRobert Mustacchi     } while (0)
58*4d9fdb46SRobert Mustacchi 
59*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \
60*4d9fdb46SRobert Mustacchi     do {                                              \
61*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lu_leblen = 0;                     \
62*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lu_local = 0;                  \
63*4d9fdb46SRobert Mustacchi         int lu_res = 0;                               \
64*4d9fdb46SRobert Mustacchi         lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \
65*4d9fdb46SRobert Mustacchi         if (lu_res == DW_DLV_ERROR) {                 \
66*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);  \
67*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                      \
68*4d9fdb46SRobert Mustacchi         }                                             \
69*4d9fdb46SRobert Mustacchi         value = lu_local;                             \
70*4d9fdb46SRobert Mustacchi         ptr += lu_leblen;                             \
71*4d9fdb46SRobert Mustacchi         leblen = lu_leblen;                          \
72bc1f688bSRobert Mustacchi     } while (0)
73bc1f688bSRobert Mustacchi 
74bc1f688bSRobert Mustacchi /*
75bc1f688bSRobert Mustacchi     Decodes signed leb128 encoded numbers.
76bc1f688bSRobert Mustacchi     Make sure ptr is a pointer to a 1-byte type.
77bc1f688bSRobert Mustacchi     In 2003 and earlier this was a hand-inlined
78bc1f688bSRobert Mustacchi     version of _dwarf_decode_s_leb128() which did
79*4d9fdb46SRobert Mustacchi     not work correctly if Dwarf_Unsigned was 64 bits.
80bc1f688bSRobert Mustacchi 
81bc1f688bSRobert Mustacchi */
82*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \
83bc1f688bSRobert Mustacchi     do {                                              \
84*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned uleblen = 0;                       \
85*4d9fdb46SRobert Mustacchi         Dwarf_Signed local = 0;                       \
86*4d9fdb46SRobert Mustacchi         int lu_res = 0;                               \
87*4d9fdb46SRobert Mustacchi         lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen,&local,endptr); \
88*4d9fdb46SRobert Mustacchi         if (lu_res == DW_DLV_ERROR) {                 \
89*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);  \
90*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                      \
91*4d9fdb46SRobert Mustacchi         }                                             \
92*4d9fdb46SRobert Mustacchi         value = local;                                \
93*4d9fdb46SRobert Mustacchi         ptr += uleblen;                               \
94*4d9fdb46SRobert Mustacchi     } while (0)
95*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \
96*4d9fdb46SRobert Mustacchi     do {                                              \
97*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned lu_leblen = 0;                     \
98*4d9fdb46SRobert Mustacchi         Dwarf_Signed lu_local = 0;                    \
99*4d9fdb46SRobert Mustacchi         int lu_res = 0;                               \
100*4d9fdb46SRobert Mustacchi         lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\
101*4d9fdb46SRobert Mustacchi             &lu_local,endptr); \
102*4d9fdb46SRobert Mustacchi         if (lu_res == DW_DLV_ERROR) {                 \
103*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER);  \
104*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                      \
105*4d9fdb46SRobert Mustacchi         }                                             \
106*4d9fdb46SRobert Mustacchi         leblen = lu_leblen;                           \
107*4d9fdb46SRobert Mustacchi         value = lu_local;                             \
108*4d9fdb46SRobert Mustacchi         ptr += lu_leblen;                             \
109bc1f688bSRobert Mustacchi     } while (0)
110bc1f688bSRobert Mustacchi 
111bc1f688bSRobert Mustacchi 
112bc1f688bSRobert Mustacchi /*
113bc1f688bSRobert Mustacchi     Skips leb128_encoded numbers that are guaranteed
114bc1f688bSRobert Mustacchi     to be no more than 4 bytes long.  Same for both
115bc1f688bSRobert Mustacchi     signed and unsigned numbers.
116*4d9fdb46SRobert Mustacchi 
117*4d9fdb46SRobert Mustacchi     These seem bogus as they assume 4 bytes get a 4 byte
118*4d9fdb46SRobert Mustacchi     word. Wrong. FIXME
119*4d9fdb46SRobert Mustacchi 
120*4d9fdb46SRobert Mustacchi     'return' only in case of error
121*4d9fdb46SRobert Mustacchi     else falls through.
122bc1f688bSRobert Mustacchi */
123*4d9fdb46SRobert Mustacchi #define SKIP_LEB128_WORD_CK(ptr,dbg,errptr,endptr)                     \
124*4d9fdb46SRobert Mustacchi     do {                                          \
125bc1f688bSRobert Mustacchi         if ((*(ptr++) & 0x80) != 0) {             \
126*4d9fdb46SRobert Mustacchi             if (ptr >= endptr) {                  \
127*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
128*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;              \
129*4d9fdb46SRobert Mustacchi             }                                     \
130bc1f688bSRobert Mustacchi             if ((*(ptr++) & 0x80) != 0) {         \
131*4d9fdb46SRobert Mustacchi                 if (ptr >= endptr) {              \
132*4d9fdb46SRobert Mustacchi                     _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
133*4d9fdb46SRobert Mustacchi                     return DW_DLV_ERROR;          \
134*4d9fdb46SRobert Mustacchi                 }                                 \
135bc1f688bSRobert Mustacchi                 if ((*(ptr++) & 0x80) != 0) {     \
136*4d9fdb46SRobert Mustacchi                     if (ptr >= endptr) {          \
137*4d9fdb46SRobert Mustacchi                         _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
138*4d9fdb46SRobert Mustacchi                         return DW_DLV_ERROR;      \
139*4d9fdb46SRobert Mustacchi                     }                             \
140*4d9fdb46SRobert Mustacchi                     ptr++;                        \
141*4d9fdb46SRobert Mustacchi                     if (ptr >= endptr) {          \
142*4d9fdb46SRobert Mustacchi                         _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \
143*4d9fdb46SRobert Mustacchi                         return DW_DLV_ERROR;      \
144bc1f688bSRobert Mustacchi                     }                             \
145bc1f688bSRobert Mustacchi                 }                                 \
146bc1f688bSRobert Mustacchi             }                                     \
147*4d9fdb46SRobert Mustacchi         }                                         \
148*4d9fdb46SRobert Mustacchi     } while (0)
149bc1f688bSRobert Mustacchi 
150bc1f688bSRobert Mustacchi 
151*4d9fdb46SRobert Mustacchi /*  Any error  found here represents a bug that cannot
152*4d9fdb46SRobert Mustacchi     be dealloc-d as the caller will not know there was no dbg */
153bc1f688bSRobert Mustacchi #define CHECK_DIE(die, error_ret_value)                          \
154*4d9fdb46SRobert Mustacchi     do {                                                         \
155*4d9fdb46SRobert Mustacchi         if (die == NULL) {                                       \
156bc1f688bSRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DIE_NULL);          \
157bc1f688bSRobert Mustacchi             return(error_ret_value);                             \
158bc1f688bSRobert Mustacchi         }                                                        \
159bc1f688bSRobert Mustacchi         if (die->di_cu_context == NULL) {                        \
160bc1f688bSRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
161bc1f688bSRobert Mustacchi             return(error_ret_value);                             \
162bc1f688bSRobert Mustacchi         }                                                        \
163bc1f688bSRobert Mustacchi         if (die->di_cu_context->cc_dbg == NULL) {                \
164bc1f688bSRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DBG_NULL);          \
165bc1f688bSRobert Mustacchi             return(error_ret_value);                             \
166bc1f688bSRobert Mustacchi         }                                                        \
167bc1f688bSRobert Mustacchi     } while (0)
168bc1f688bSRobert Mustacchi 
169bc1f688bSRobert Mustacchi 
170bc1f688bSRobert Mustacchi /*
171bc1f688bSRobert Mustacchi    Reads 'source' for 'length' bytes from unaligned addr.
172bc1f688bSRobert Mustacchi 
173bc1f688bSRobert Mustacchi    Avoids any constant-in-conditional warnings and
174bc1f688bSRobert Mustacchi    avoids a test in the generated code (for non-const cases,
175bc1f688bSRobert Mustacchi    which are in the majority.)
176bc1f688bSRobert Mustacchi    Uses a temp to avoid the test.
177bc1f688bSRobert Mustacchi    The decl here should avoid any problem of size in the temp.
178bc1f688bSRobert Mustacchi    This code is ENDIAN DEPENDENT
179bc1f688bSRobert Mustacchi    The memcpy args are the endian issue.
180*4d9fdb46SRobert Mustacchi 
181*4d9fdb46SRobert Mustacchi    Does not update the 'source' field.
182*4d9fdb46SRobert Mustacchi 
183*4d9fdb46SRobert Mustacchi    for READ_UNALIGNED_CK the error code refers to host endianness.
184bc1f688bSRobert Mustacchi */
185bc1f688bSRobert Mustacchi typedef Dwarf_Unsigned BIGGEST_UINT;
186bc1f688bSRobert Mustacchi 
187bc1f688bSRobert Mustacchi #ifdef WORDS_BIGENDIAN
188*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
189bc1f688bSRobert Mustacchi     do {                                                         \
190bc1f688bSRobert Mustacchi         BIGGEST_UINT _ltmp = 0;                                  \
191*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr readend = source+length;                  \
192*4d9fdb46SRobert Mustacchi         if (readend <  source) {                                 \
193*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \
194*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                                 \
195*4d9fdb46SRobert Mustacchi         }                                                        \
196*4d9fdb46SRobert Mustacchi         if (readend > endptr) {                                  \
197*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \
198*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                                 \
199*4d9fdb46SRobert Mustacchi         }                                                        \
200*4d9fdb46SRobert Mustacchi         dbg->de_copy_word( (((char *)(&_ltmp)) +                 \
201*4d9fdb46SRobert Mustacchi             sizeof(_ltmp) - length),source, length) ;            \
202bc1f688bSRobert Mustacchi         dest = (desttype)_ltmp;                                  \
203bc1f688bSRobert Mustacchi     } while (0)
204bc1f688bSRobert Mustacchi 
205bc1f688bSRobert Mustacchi 
206bc1f688bSRobert Mustacchi /*
207bc1f688bSRobert Mustacchi     This macro sign-extends a variable depending on the length.
208bc1f688bSRobert Mustacchi     It fills the bytes between the size of the destination and
209bc1f688bSRobert Mustacchi     the length with appropriate padding.
210bc1f688bSRobert Mustacchi     This code is ENDIAN DEPENDENT but dependent only
211bc1f688bSRobert Mustacchi     on host endianness, not object file endianness.
212bc1f688bSRobert Mustacchi     The memcpy args are the issue.
213bc1f688bSRobert Mustacchi */
214bc1f688bSRobert Mustacchi #define SIGN_EXTEND(dest, length)                                 \
215*4d9fdb46SRobert Mustacchi     do {                                                          \
216*4d9fdb46SRobert Mustacchi         if (*(Dwarf_Sbyte *)((char *)&dest +                      \
217*4d9fdb46SRobert Mustacchi             sizeof(dest) - length) < 0) {                         \
218bc1f688bSRobert Mustacchi             memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\
219bc1f688bSRobert Mustacchi                 sizeof(dest) - length);                           \
220bc1f688bSRobert Mustacchi         }                                                         \
221bc1f688bSRobert Mustacchi     } while (0)
222bc1f688bSRobert Mustacchi #else /* LITTLE ENDIAN */
223*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
224bc1f688bSRobert Mustacchi     do  {                                       \
225bc1f688bSRobert Mustacchi         BIGGEST_UINT _ltmp = 0;                 \
226*4d9fdb46SRobert Mustacchi         Dwarf_Byte_Ptr readend = source+length; \
227*4d9fdb46SRobert Mustacchi         if (readend < source) {                 \
228*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,            \
229*4d9fdb46SRobert Mustacchi                 DW_DLE_READ_LITTLEENDIAN_ERROR);\
230*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                \
231*4d9fdb46SRobert Mustacchi         }                                       \
232*4d9fdb46SRobert Mustacchi         if (readend > endptr) {                 \
233*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,            \
234*4d9fdb46SRobert Mustacchi                 DW_DLE_READ_LITTLEENDIAN_ERROR);\
235*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;                \
236*4d9fdb46SRobert Mustacchi         }                                       \
237bc1f688bSRobert Mustacchi         dbg->de_copy_word( (char *)(&_ltmp) ,   \
238bc1f688bSRobert Mustacchi             source, length) ;                   \
239bc1f688bSRobert Mustacchi         dest = (desttype)_ltmp;                 \
240bc1f688bSRobert Mustacchi     } while (0)
241bc1f688bSRobert Mustacchi 
242bc1f688bSRobert Mustacchi 
243bc1f688bSRobert Mustacchi /*
244bc1f688bSRobert Mustacchi     This macro sign-extends a variable depending on the length.
245bc1f688bSRobert Mustacchi     It fills the bytes between the size of the destination and
246bc1f688bSRobert Mustacchi     the length with appropriate padding.
247bc1f688bSRobert Mustacchi     This code is ENDIAN DEPENDENT but dependent only
248bc1f688bSRobert Mustacchi     on host endianness, not object file endianness.
249bc1f688bSRobert Mustacchi     The memcpy args are the issue.
250bc1f688bSRobert Mustacchi */
251bc1f688bSRobert Mustacchi #define SIGN_EXTEND(dest, length)                               \
252*4d9fdb46SRobert Mustacchi     do {                                                        \
253*4d9fdb46SRobert Mustacchi         if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \
254bc1f688bSRobert Mustacchi             memcpy((char *)&dest+length,                        \
255bc1f688bSRobert Mustacchi                 "\xff\xff\xff\xff\xff\xff\xff\xff",             \
256bc1f688bSRobert Mustacchi                 sizeof(dest) - length);                         \
257bc1f688bSRobert Mustacchi         }                                                       \
258bc1f688bSRobert Mustacchi     } while (0)
259bc1f688bSRobert Mustacchi 
260bc1f688bSRobert Mustacchi #endif /* ! LITTLE_ENDIAN */
261bc1f688bSRobert Mustacchi 
262bc1f688bSRobert Mustacchi 
263bc1f688bSRobert Mustacchi 
264bc1f688bSRobert Mustacchi /*
265bc1f688bSRobert Mustacchi     READ_AREA LENGTH reads the length (the older way
266bc1f688bSRobert Mustacchi     of pure 32 or 64 bit
267*4d9fdb46SRobert Mustacchi     or the dwarf v3 64bit-extension way)
268bc1f688bSRobert Mustacchi 
269bc1f688bSRobert Mustacchi     It reads the bits from where rw_src_data_p  points to
270bc1f688bSRobert Mustacchi     and updates the rw_src_data_p to point past what was just read.
271bc1f688bSRobert Mustacchi 
272bc1f688bSRobert Mustacchi     It updates w_length_size (to the size of an offset, either 4 or 8)
273*4d9fdb46SRobert Mustacchi     and w_exten_size (set 0 unless this frame has the DWARF3
274*4d9fdb46SRobert Mustacchi     and later  64bit
275bc1f688bSRobert Mustacchi     extension, in which case w_exten_size is set to 4).
276bc1f688bSRobert Mustacchi 
277bc1f688bSRobert Mustacchi     r_dbg is just the current dbg pointer.
278bc1f688bSRobert Mustacchi     w_target is the output length field.
279bc1f688bSRobert Mustacchi     r_targtype is the output type. Always Dwarf_Unsigned so far.
280bc1f688bSRobert Mustacchi 
281bc1f688bSRobert Mustacchi */
282*4d9fdb46SRobert Mustacchi /*  This one handles the v3 64bit extension
283*4d9fdb46SRobert Mustacchi     and 32bit (and   SGI/MIPS fixed 64  bit via the
284bc1f688bSRobert Mustacchi         dwarf_init-set r_dbg->de_length_size)..
285bc1f688bSRobert Mustacchi     It does not recognize any but the one distingushed value
286bc1f688bSRobert Mustacchi     (the only one with defined meaning).
287bc1f688bSRobert Mustacchi     It assumes that no CU will have a length
288bc1f688bSRobert Mustacchi         0xffffffxx  (32bit length)
289bc1f688bSRobert Mustacchi         or
290bc1f688bSRobert Mustacchi         0xffffffxx xxxxxxxx (64bit length)
291bc1f688bSRobert Mustacchi     which makes possible auto-detection of the extension.
292bc1f688bSRobert Mustacchi 
293bc1f688bSRobert Mustacchi     This depends on knowing that only a non-zero length
294bc1f688bSRobert Mustacchi     is legitimate (AFAICT), and for IRIX non-standard -64
295bc1f688bSRobert Mustacchi     dwarf that the first 32 bits of the 64bit offset will be
296bc1f688bSRobert Mustacchi     zero (because the compiler could not handle a truly large
297bc1f688bSRobert Mustacchi     value as of Jan 2003 and because no app has that much debug
298bc1f688bSRobert Mustacchi     info anyway, at least not in the IRIX case).
299bc1f688bSRobert Mustacchi 
300bc1f688bSRobert Mustacchi     At present not testing for '64bit elf' here as that
301bc1f688bSRobert Mustacchi     does not seem necessary (none of the 64bit length seems
302bc1f688bSRobert Mustacchi     appropriate unless it's  ident[EI_CLASS] == ELFCLASS64).
303bc1f688bSRobert Mustacchi */
304*4d9fdb46SRobert Mustacchi /*  The w_target > r_sectionlen compare is done without adding in case
305*4d9fdb46SRobert Mustacchi     the w_target value read is so large any addition would overflow.
306*4d9fdb46SRobert Mustacchi     A basic value sanity check. */
307*4d9fdb46SRobert Mustacchi #define READ_AREA_LENGTH_CK(r_dbg,w_target,r_targtype,         \
308*4d9fdb46SRobert Mustacchi     rw_src_data_p,w_length_size,w_exten_size,w_error,          \
309*4d9fdb46SRobert Mustacchi     r_sectionlen,r_endptr)                                     \
310*4d9fdb46SRobert Mustacchi     do {                                                       \
311*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,           \
312*4d9fdb46SRobert Mustacchi             rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE,         \
313*4d9fdb46SRobert Mustacchi             w_error,r_endptr);                                 \
314bc1f688bSRobert Mustacchi         if (w_target == DISTINGUISHED_VALUE) {                 \
315bc1f688bSRobert Mustacchi             /* dwarf3 64bit extension */                       \
316bc1f688bSRobert Mustacchi             w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;  \
317bc1f688bSRobert Mustacchi             rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE;       \
318bc1f688bSRobert Mustacchi             w_exten_size   = ORIGINAL_DWARF_OFFSET_SIZE;       \
319*4d9fdb46SRobert Mustacchi             READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,       \
320*4d9fdb46SRobert Mustacchi                 rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE,\
321*4d9fdb46SRobert Mustacchi                 w_error,r_endptr);                             \
322*4d9fdb46SRobert Mustacchi             if (w_target > r_sectionlen) {                     \
323*4d9fdb46SRobert Mustacchi                 _dwarf_error(r_dbg,w_error,                    \
324*4d9fdb46SRobert Mustacchi                     DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);    \
325*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;                           \
326*4d9fdb46SRobert Mustacchi             }                                                  \
327bc1f688bSRobert Mustacchi             rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;  \
328bc1f688bSRobert Mustacchi         } else {                                               \
329bc1f688bSRobert Mustacchi             if (w_target == 0 && r_dbg->de_big_endian_object) {\
330*4d9fdb46SRobert Mustacchi                 /* Might be IRIX: We have to distinguish between */\
331*4d9fdb46SRobert Mustacchi                 /* 32-bit DWARF format and IRIX 64-bit         \
332*4d9fdb46SRobert Mustacchi                     DWARF format. */                           \
333*4d9fdb46SRobert Mustacchi                 if (r_dbg->de_length_size == 8) {              \
334bc1f688bSRobert Mustacchi                     /* IRIX 64 bit, big endian.  This test */  \
335bc1f688bSRobert Mustacchi                     /* is not a truly precise test, a precise test*/ \
336bc1f688bSRobert Mustacchi                     /* would check if the target was IRIX.  */  \
337*4d9fdb46SRobert Mustacchi                     READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,\
338*4d9fdb46SRobert Mustacchi                         rw_src_data_p,                          \
339*4d9fdb46SRobert Mustacchi                         DISTINGUISHED_VALUE_OFFSET_SIZE,      \
340*4d9fdb46SRobert Mustacchi                         w_error,r_endptr);                     \
341*4d9fdb46SRobert Mustacchi                     if (w_target > r_sectionlen) {             \
342*4d9fdb46SRobert Mustacchi                         _dwarf_error(r_dbg,w_error,            \
343*4d9fdb46SRobert Mustacchi                             DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\
344*4d9fdb46SRobert Mustacchi                         return DW_DLV_ERROR;                   \
345*4d9fdb46SRobert Mustacchi                     }                                          \
346bc1f688bSRobert Mustacchi                     w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;\
347bc1f688bSRobert Mustacchi                     rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;\
348bc1f688bSRobert Mustacchi                     w_exten_size = 0;                          \
349bc1f688bSRobert Mustacchi                 } else {                                       \
350*4d9fdb46SRobert Mustacchi                     /* 32 bit, big endian */                   \
351*4d9fdb46SRobert Mustacchi                     w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;\
352*4d9fdb46SRobert Mustacchi                     rw_src_data_p += w_length_size;            \
353*4d9fdb46SRobert Mustacchi                     w_exten_size = 0;                          \
354*4d9fdb46SRobert Mustacchi                 }                                              \
355*4d9fdb46SRobert Mustacchi             } else {                                           \
356*4d9fdb46SRobert Mustacchi                 if (w_target > r_sectionlen) {                 \
357*4d9fdb46SRobert Mustacchi                     _dwarf_error(r_dbg,w_error,                \
358*4d9fdb46SRobert Mustacchi                         DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\
359*4d9fdb46SRobert Mustacchi                     return DW_DLV_ERROR;                       \
360*4d9fdb46SRobert Mustacchi                 }                                              \
361*4d9fdb46SRobert Mustacchi                 /* Standard 32 bit dwarf2/dwarf3 */            \
362bc1f688bSRobert Mustacchi                 w_exten_size   = 0;                            \
363bc1f688bSRobert Mustacchi                 w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;   \
364bc1f688bSRobert Mustacchi                 rw_src_data_p += w_length_size;                \
365bc1f688bSRobert Mustacchi             }                                                  \
366*4d9fdb46SRobert Mustacchi         }                                                      \
367*4d9fdb46SRobert Mustacchi     } while (0)
368bc1f688bSRobert Mustacchi 
369bc1f688bSRobert Mustacchi 
370*4d9fdb46SRobert Mustacchi /* Fuller checking. Returns DW_DLV_ERROR or DW_DLV_OK
371*4d9fdb46SRobert Mustacchi    Caller must set Dwarf_Error */
372*4d9fdb46SRobert Mustacchi int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128,
373*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * leb128_length,
374*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr);
375bc1f688bSRobert Mustacchi 
376*4d9fdb46SRobert Mustacchi int _dwarf_format_TAG_err_msg(Dwarf_Debug dbg,
377*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned tag,const char *m,
378*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
379*4d9fdb46SRobert Mustacchi 
380*4d9fdb46SRobert Mustacchi 
381*4d9fdb46SRobert Mustacchi int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128,
382*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * leb128_length,
383*4d9fdb46SRobert Mustacchi     Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr);
384*4d9fdb46SRobert Mustacchi 
385*4d9fdb46SRobert Mustacchi int
386bc1f688bSRobert Mustacchi _dwarf_get_size_of_val(Dwarf_Debug dbg,
387bc1f688bSRobert Mustacchi     Dwarf_Unsigned form,
388*4d9fdb46SRobert Mustacchi     Dwarf_Half cu_version,
389bc1f688bSRobert Mustacchi     Dwarf_Half address_size,
390bc1f688bSRobert Mustacchi     Dwarf_Small * val_ptr,
391*4d9fdb46SRobert Mustacchi     int v_length_size,
392*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *size_out,
393*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end_ptr,
394*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
395bc1f688bSRobert Mustacchi 
396bc1f688bSRobert Mustacchi struct Dwarf_Hash_Table_Entry_s;
397bc1f688bSRobert Mustacchi /* This single struct is the base for the hash table.
398bc1f688bSRobert Mustacchi    The intent is that once the total_abbrev_count across
399bc1f688bSRobert Mustacchi    all the entries is greater than  10*current_table_entry_count
400bc1f688bSRobert Mustacchi    one should build a new Dwarf_Hash_Table_Base_s, rehash
401bc1f688bSRobert Mustacchi    all the existing entries, and delete the old table and entries.
402bc1f688bSRobert Mustacchi    (10 is a heuristic, nothing magic about it, but once the
403bc1f688bSRobert Mustacchi    count gets to 30 or 40 times current_table_entry_count
404bc1f688bSRobert Mustacchi    things really slow down a lot. One (500MB) application had
405bc1f688bSRobert Mustacchi    127000 abbreviations in one compilation unit)
406bc1f688bSRobert Mustacchi    The incoming 'code' is an abbrev number and those simply
407bc1f688bSRobert Mustacchi    increase linearly so the hashing is perfect always.
408bc1f688bSRobert Mustacchi */
409bc1f688bSRobert Mustacchi struct Dwarf_Hash_Table_s {
410bc1f688bSRobert Mustacchi     unsigned long       tb_table_entry_count;
411bc1f688bSRobert Mustacchi     unsigned long       tb_total_abbrev_count;
412bc1f688bSRobert Mustacchi     /* Each table entry is a list of abbreviations. */
413bc1f688bSRobert Mustacchi     struct  Dwarf_Hash_Table_Entry_s *tb_entries;
414bc1f688bSRobert Mustacchi };
415bc1f688bSRobert Mustacchi 
416bc1f688bSRobert Mustacchi /*
417bc1f688bSRobert Mustacchi     This struct is used to build a hash table for the
418bc1f688bSRobert Mustacchi     abbreviation codes for a compile-unit.
419bc1f688bSRobert Mustacchi */
420bc1f688bSRobert Mustacchi struct Dwarf_Hash_Table_Entry_s {
421bc1f688bSRobert Mustacchi     Dwarf_Abbrev_List at_head;
422bc1f688bSRobert Mustacchi };
423bc1f688bSRobert Mustacchi 
424bc1f688bSRobert Mustacchi 
425bc1f688bSRobert Mustacchi 
426*4d9fdb46SRobert Mustacchi int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
427*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned code,
428*4d9fdb46SRobert Mustacchi     Dwarf_Abbrev_List *list_out,Dwarf_Error *error);
429bc1f688bSRobert Mustacchi 
430bc1f688bSRobert Mustacchi 
431bc1f688bSRobert Mustacchi /* return 1 if string ends before 'endptr' else
432bc1f688bSRobert Mustacchi ** return 0 meaning string is not properly terminated.
433bc1f688bSRobert Mustacchi ** Presumption is the 'endptr' pts to end of some dwarf section data.
434bc1f688bSRobert Mustacchi */
435*4d9fdb46SRobert Mustacchi int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr,
436*4d9fdb46SRobert Mustacchi     void *startptr, void *endptr,
437*4d9fdb46SRobert Mustacchi     int suggested_error, Dwarf_Error *error);
438bc1f688bSRobert Mustacchi 
439*4d9fdb46SRobert Mustacchi int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset,
440*4d9fdb46SRobert Mustacchi     Dwarf_Bool is_info,
441*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *area_length_out,
442*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
443*4d9fdb46SRobert Mustacchi 
444*4d9fdb46SRobert Mustacchi Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug,Dwarf_Bool dinfo);
445bc1f688bSRobert Mustacchi 
446bc1f688bSRobert Mustacchi int  _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
447*4d9fdb46SRobert Mustacchi int  _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error *error);
448bc1f688bSRobert Mustacchi void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,
449bc1f688bSRobert Mustacchi     struct Dwarf_Hash_Table_s* hash_table);
450bc1f688bSRobert Mustacchi int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
451*4d9fdb46SRobert Mustacchi int _dwarf_reference_outside_section(Dwarf_Die die,
452*4d9fdb46SRobert Mustacchi     Dwarf_Small * startaddr,
453*4d9fdb46SRobert Mustacchi     Dwarf_Small * pastend);
454*4d9fdb46SRobert Mustacchi void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs,
455*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbgt,Dwarf_Error *errt);
456*4d9fdb46SRobert Mustacchi 
457*4d9fdb46SRobert Mustacchi int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out,
458*4d9fdb46SRobert Mustacchi     const char **comp_name_out,
459*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
460*4d9fdb46SRobert Mustacchi 
461*4d9fdb46SRobert Mustacchi int _dwarf_what_section_are_we(Dwarf_Debug dbg,
462*4d9fdb46SRobert Mustacchi     Dwarf_Small *our_pointer,
463*4d9fdb46SRobert Mustacchi     const char **      section_name_out,
464*4d9fdb46SRobert Mustacchi     Dwarf_Small    **sec_start_ptr_out,
465*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *sec_len_out,
466*4d9fdb46SRobert Mustacchi     Dwarf_Small    **sec_end_ptr_out,
467*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
468*4d9fdb46SRobert Mustacchi 
469*4d9fdb46SRobert Mustacchi /*  wrappers return either DW_DLV_OK or DW_DLV_ERROR.
470*4d9fdb46SRobert Mustacchi     Never DW_DLV_NO_ENTRY. */
471*4d9fdb46SRobert Mustacchi int
472*4d9fdb46SRobert Mustacchi _dwarf_read_unaligned_ck_wrapper(Dwarf_Debug dbg,
473*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *out_value,
474*4d9fdb46SRobert Mustacchi     Dwarf_Small *readfrom,
475*4d9fdb46SRobert Mustacchi     int          readlength,
476*4d9fdb46SRobert Mustacchi     Dwarf_Small *end_arange,
477*4d9fdb46SRobert Mustacchi     Dwarf_Error *err);
478*4d9fdb46SRobert Mustacchi int
479*4d9fdb46SRobert Mustacchi _dwarf_read_area_length_ck_wrapper(Dwarf_Debug dbg,
480*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *out_value,
481*4d9fdb46SRobert Mustacchi     Dwarf_Small **readfrom,
482*4d9fdb46SRobert Mustacchi     int    *  length_size_out,
483*4d9fdb46SRobert Mustacchi     int    *  exten_size_out,
484*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned sectionlength,
485*4d9fdb46SRobert Mustacchi     Dwarf_Small *endsection,
486*4d9fdb46SRobert Mustacchi     Dwarf_Error *err);
487*4d9fdb46SRobert Mustacchi int
488*4d9fdb46SRobert Mustacchi _dwarf_leb128_uword_wrapper(Dwarf_Debug dbg,
489*4d9fdb46SRobert Mustacchi     Dwarf_Small ** startptr,
490*4d9fdb46SRobert Mustacchi     Dwarf_Small * endptr,
491*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *out_value,
492*4d9fdb46SRobert Mustacchi     Dwarf_Error * error);
493*4d9fdb46SRobert Mustacchi int
494*4d9fdb46SRobert Mustacchi _dwarf_leb128_sword_wrapper(Dwarf_Debug dbg,
495*4d9fdb46SRobert Mustacchi     Dwarf_Small ** startptr,
496*4d9fdb46SRobert Mustacchi     Dwarf_Small * endptr,
497*4d9fdb46SRobert Mustacchi     Dwarf_Signed *out_value,
498*4d9fdb46SRobert Mustacchi     Dwarf_Error * error);
499*4d9fdb46SRobert Mustacchi 
500*4d9fdb46SRobert Mustacchi 
501bc1f688bSRobert Mustacchi 
502bc1f688bSRobert Mustacchi #endif /* DWARF_UTIL_H */
503