107dc1947SRichard Lowe #ifndef DWARF_UTIL_H
207dc1947SRichard Lowe #define DWARF_UTIL_H
349d3bc91SRichard Lowe /*
449d3bc91SRichard Lowe 
549d3bc91SRichard Lowe   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
8*4d9fdb46SRobert 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.
13*4d9fdb46SRobert 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.
18*4d9fdb46SRobert 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.
26*4d9fdb46SRobert 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.
3149d3bc91SRichard Lowe 
3207dc1947SRichard Lowe */
3307dc1947SRichard Lowe 
3449d3bc91SRichard Lowe /*
3507dc1947SRichard Lowe     Decodes unsigned leb128 encoded numbers.
36*4d9fdb46SRobert Mustacchi     Make sure ptr is a pointer to a 1-byte type.
3707dc1947SRichard Lowe     In 2003 and earlier this was a hand-inlined
3807dc1947SRichard Lowe     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.
4449d3bc91SRichard Lowe */
45*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \
46*4d9fdb46SRobert 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;                          \
7207dc1947SRichard Lowe     } while (0)
7349d3bc91SRichard Lowe 
7449d3bc91SRichard Lowe /*
7549d3bc91SRichard Lowe     Decodes signed leb128 encoded numbers.
7649d3bc91SRichard Lowe     Make sure ptr is a pointer to a 1-byte type.
7707dc1947SRichard Lowe     In 2003 and earlier this was a hand-inlined
7807dc1947SRichard Lowe     version of _dwarf_decode_s_leb128() which did
79*4d9fdb46SRobert Mustacchi     not work correctly if Dwarf_Unsigned was 64 bits.
8049d3bc91SRichard Lowe 
8149d3bc91SRichard Lowe */
82*4d9fdb46SRobert Mustacchi #define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \
83*4d9fdb46SRobert 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;                             \
109*4d9fdb46SRobert Mustacchi     } while (0)
11049d3bc91SRichard Lowe 
11149d3bc91SRichard Lowe 
11249d3bc91SRichard Lowe /*
113*4d9fdb46SRobert Mustacchi     Skips leb128_encoded numbers that are guaranteed
11449d3bc91SRichard Lowe     to be no more than 4 bytes long.  Same for both
11549d3bc91SRichard Lowe     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.
12249d3bc91SRichard Lowe */
123*4d9fdb46SRobert Mustacchi #define SKIP_LEB128_WORD_CK(ptr,dbg,errptr,endptr)                     \
124*4d9fdb46SRobert Mustacchi     do {                                          \
125*4d9fdb46SRobert 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             }                                     \
130*4d9fdb46SRobert 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                 }                                 \
135*4d9fdb46SRobert 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;      \
144*4d9fdb46SRobert Mustacchi                     }                             \
145*4d9fdb46SRobert Mustacchi                 }                                 \
146*4d9fdb46SRobert Mustacchi             }                                     \
147*4d9fdb46SRobert Mustacchi         }                                         \
148*4d9fdb46SRobert Mustacchi     } while (0)
149*4d9fdb46SRobert Mustacchi 
150*4d9fdb46SRobert 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 */
153*4d9fdb46SRobert Mustacchi #define CHECK_DIE(die, error_ret_value)                          \
154*4d9fdb46SRobert Mustacchi     do {                                                         \
155*4d9fdb46SRobert Mustacchi         if (die == NULL) {                                       \
156*4d9fdb46SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DIE_NULL);          \
157*4d9fdb46SRobert Mustacchi             return(error_ret_value);                             \
158*4d9fdb46SRobert Mustacchi         }                                                        \
159*4d9fdb46SRobert Mustacchi         if (die->di_cu_context == NULL) {                        \
160*4d9fdb46SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
161*4d9fdb46SRobert Mustacchi             return(error_ret_value);                             \
162*4d9fdb46SRobert Mustacchi         }                                                        \
163*4d9fdb46SRobert Mustacchi         if (die->di_cu_context->cc_dbg == NULL) {                \
164*4d9fdb46SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_DBG_NULL);          \
165*4d9fdb46SRobert Mustacchi             return(error_ret_value);                             \
166*4d9fdb46SRobert Mustacchi         }                                                        \
167*4d9fdb46SRobert Mustacchi     } while (0)
168*4d9fdb46SRobert Mustacchi 
169*4d9fdb46SRobert Mustacchi 
170*4d9fdb46SRobert Mustacchi /*
17149d3bc91SRichard Lowe    Reads 'source' for 'length' bytes from unaligned addr.
17249d3bc91SRichard Lowe 
17349d3bc91SRichard Lowe    Avoids any constant-in-conditional warnings and
17449d3bc91SRichard Lowe    avoids a test in the generated code (for non-const cases,
175*4d9fdb46SRobert Mustacchi    which are in the majority.)
17649d3bc91SRichard Lowe    Uses a temp to avoid the test.
17749d3bc91SRichard Lowe    The decl here should avoid any problem of size in the temp.
17849d3bc91SRichard Lowe    This code is ENDIAN DEPENDENT
17949d3bc91SRichard Lowe    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.
18449d3bc91SRichard Lowe */
18549d3bc91SRichard Lowe typedef Dwarf_Unsigned BIGGEST_UINT;
18649d3bc91SRichard Lowe 
18749d3bc91SRichard Lowe #ifdef WORDS_BIGENDIAN
188*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
189*4d9fdb46SRobert Mustacchi     do {                                                         \
190*4d9fdb46SRobert 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) ;            \
202*4d9fdb46SRobert Mustacchi         dest = (desttype)_ltmp;                                  \
20307dc1947SRichard Lowe     } while (0)
20449d3bc91SRichard Lowe 
20549d3bc91SRichard Lowe 
20649d3bc91SRichard Lowe /*
20749d3bc91SRichard Lowe     This macro sign-extends a variable depending on the length.
20849d3bc91SRichard Lowe     It fills the bytes between the size of the destination and
20949d3bc91SRichard Lowe     the length with appropriate padding.
21049d3bc91SRichard Lowe     This code is ENDIAN DEPENDENT but dependent only
21149d3bc91SRichard Lowe     on host endianness, not object file endianness.
21249d3bc91SRichard Lowe     The memcpy args are the issue.
21349d3bc91SRichard Lowe */
214*4d9fdb46SRobert 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) {                         \
218*4d9fdb46SRobert Mustacchi             memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\
219*4d9fdb46SRobert Mustacchi                 sizeof(dest) - length);                           \
220*4d9fdb46SRobert Mustacchi         }                                                         \
221*4d9fdb46SRobert Mustacchi     } while (0)
22249d3bc91SRichard Lowe #else /* LITTLE ENDIAN */
223*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \
224*4d9fdb46SRobert Mustacchi     do  {                                       \
225*4d9fdb46SRobert 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         }                                       \
237*4d9fdb46SRobert Mustacchi         dbg->de_copy_word( (char *)(&_ltmp) ,   \
238*4d9fdb46SRobert Mustacchi             source, length) ;                   \
239*4d9fdb46SRobert Mustacchi         dest = (desttype)_ltmp;                 \
240*4d9fdb46SRobert Mustacchi     } while (0)
24149d3bc91SRichard Lowe 
24249d3bc91SRichard Lowe 
24349d3bc91SRichard Lowe /*
24449d3bc91SRichard Lowe     This macro sign-extends a variable depending on the length.
24549d3bc91SRichard Lowe     It fills the bytes between the size of the destination and
24649d3bc91SRichard Lowe     the length with appropriate padding.
24749d3bc91SRichard Lowe     This code is ENDIAN DEPENDENT but dependent only
24849d3bc91SRichard Lowe     on host endianness, not object file endianness.
24949d3bc91SRichard Lowe     The memcpy args are the issue.
25049d3bc91SRichard Lowe */
251*4d9fdb46SRobert Mustacchi #define SIGN_EXTEND(dest, length)                               \
252*4d9fdb46SRobert Mustacchi     do {                                                        \
253*4d9fdb46SRobert Mustacchi         if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \
254*4d9fdb46SRobert Mustacchi             memcpy((char *)&dest+length,                        \
255*4d9fdb46SRobert Mustacchi                 "\xff\xff\xff\xff\xff\xff\xff\xff",             \
256*4d9fdb46SRobert Mustacchi                 sizeof(dest) - length);                         \
257*4d9fdb46SRobert Mustacchi         }                                                       \
25807dc1947SRichard Lowe     } while (0)
25949d3bc91SRichard Lowe 
26049d3bc91SRichard Lowe #endif /* ! LITTLE_ENDIAN */
26149d3bc91SRichard Lowe 
26249d3bc91SRichard Lowe 
26349d3bc91SRichard Lowe 
26449d3bc91SRichard Lowe /*
265*4d9fdb46SRobert Mustacchi     READ_AREA LENGTH reads the length (the older way
266*4d9fdb46SRobert Mustacchi     of pure 32 or 64 bit
267*4d9fdb46SRobert Mustacchi     or the dwarf v3 64bit-extension way)
268*4d9fdb46SRobert Mustacchi 
269*4d9fdb46SRobert Mustacchi     It reads the bits from where rw_src_data_p  points to
270*4d9fdb46SRobert Mustacchi     and updates the rw_src_data_p to point past what was just read.
27149d3bc91SRichard Lowe 
272*4d9fdb46SRobert 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
275*4d9fdb46SRobert Mustacchi     extension, in which case w_exten_size is set to 4).
27649d3bc91SRichard Lowe 
277*4d9fdb46SRobert Mustacchi     r_dbg is just the current dbg pointer.
278*4d9fdb46SRobert Mustacchi     w_target is the output length field.
279*4d9fdb46SRobert Mustacchi     r_targtype is the output type. Always Dwarf_Unsigned so far.
28049d3bc91SRichard Lowe 
28149d3bc91SRichard Lowe */
282*4d9fdb46SRobert Mustacchi /*  This one handles the v3 64bit extension
283*4d9fdb46SRobert Mustacchi     and 32bit (and   SGI/MIPS fixed 64  bit via the
284*4d9fdb46SRobert Mustacchi         dwarf_init-set r_dbg->de_length_size)..
285*4d9fdb46SRobert Mustacchi     It does not recognize any but the one distingushed value
286*4d9fdb46SRobert Mustacchi     (the only one with defined meaning).
287*4d9fdb46SRobert Mustacchi     It assumes that no CU will have a length
288*4d9fdb46SRobert Mustacchi         0xffffffxx  (32bit length)
289*4d9fdb46SRobert Mustacchi         or
290*4d9fdb46SRobert Mustacchi         0xffffffxx xxxxxxxx (64bit length)
291*4d9fdb46SRobert Mustacchi     which makes possible auto-detection of the extension.
292*4d9fdb46SRobert Mustacchi 
293*4d9fdb46SRobert Mustacchi     This depends on knowing that only a non-zero length
294*4d9fdb46SRobert Mustacchi     is legitimate (AFAICT), and for IRIX non-standard -64
295*4d9fdb46SRobert Mustacchi     dwarf that the first 32 bits of the 64bit offset will be
296*4d9fdb46SRobert Mustacchi     zero (because the compiler could not handle a truly large
297*4d9fdb46SRobert Mustacchi     value as of Jan 2003 and because no app has that much debug
298*4d9fdb46SRobert Mustacchi     info anyway, at least not in the IRIX case).
299*4d9fdb46SRobert Mustacchi 
300*4d9fdb46SRobert Mustacchi     At present not testing for '64bit elf' here as that
301*4d9fdb46SRobert Mustacchi     does not seem necessary (none of the 64bit length seems
302*4d9fdb46SRobert Mustacchi     appropriate unless it's  ident[EI_CLASS] == ELFCLASS64).
30349d3bc91SRichard Lowe */
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);                                 \
314*4d9fdb46SRobert Mustacchi         if (w_target == DISTINGUISHED_VALUE) {                 \
315*4d9fdb46SRobert Mustacchi             /* dwarf3 64bit extension */                       \
316*4d9fdb46SRobert Mustacchi             w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;  \
317*4d9fdb46SRobert Mustacchi             rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE;       \
318*4d9fdb46SRobert 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             }                                                  \
327*4d9fdb46SRobert Mustacchi             rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;  \
328*4d9fdb46SRobert Mustacchi         } else {                                               \
329*4d9fdb46SRobert 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) {              \
334*4d9fdb46SRobert Mustacchi                     /* IRIX 64 bit, big endian.  This test */  \
335*4d9fdb46SRobert Mustacchi                     /* is not a truly precise test, a precise test*/ \
336*4d9fdb46SRobert 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                     }                                          \
346*4d9fdb46SRobert Mustacchi                     w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;\
347*4d9fdb46SRobert Mustacchi                     rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;\
348*4d9fdb46SRobert Mustacchi                     w_exten_size = 0;                          \
349*4d9fdb46SRobert 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 */            \
362*4d9fdb46SRobert Mustacchi                 w_exten_size   = 0;                            \
363*4d9fdb46SRobert Mustacchi                 w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;   \
364*4d9fdb46SRobert Mustacchi                 rw_src_data_p += w_length_size;                \
365*4d9fdb46SRobert Mustacchi             }                                                  \
366*4d9fdb46SRobert Mustacchi         }                                                      \
367*4d9fdb46SRobert Mustacchi     } while (0)
368*4d9fdb46SRobert Mustacchi 
369*4d9fdb46SRobert 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);
375*4d9fdb46SRobert 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
38649d3bc91SRichard Lowe _dwarf_get_size_of_val(Dwarf_Debug dbg,
38707dc1947SRichard Lowe     Dwarf_Unsigned form,
388*4d9fdb46SRobert Mustacchi     Dwarf_Half cu_version,
38907dc1947SRichard Lowe     Dwarf_Half address_size,
390*4d9fdb46SRobert 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);
39507dc1947SRichard Lowe 
39607dc1947SRichard Lowe struct Dwarf_Hash_Table_Entry_s;
39707dc1947SRichard Lowe /* This single struct is the base for the hash table.
39807dc1947SRichard Lowe    The intent is that once the total_abbrev_count across
39907dc1947SRichard Lowe    all the entries is greater than  10*current_table_entry_count
40007dc1947SRichard Lowe    one should build a new Dwarf_Hash_Table_Base_s, rehash
401*4d9fdb46SRobert Mustacchi    all the existing entries, and delete the old table and entries.
40207dc1947SRichard Lowe    (10 is a heuristic, nothing magic about it, but once the
40307dc1947SRichard Lowe    count gets to 30 or 40 times current_table_entry_count
40407dc1947SRichard Lowe    things really slow down a lot. One (500MB) application had
40507dc1947SRichard Lowe    127000 abbreviations in one compilation unit)
40607dc1947SRichard Lowe    The incoming 'code' is an abbrev number and those simply
40707dc1947SRichard Lowe    increase linearly so the hashing is perfect always.
40807dc1947SRichard Lowe */
40907dc1947SRichard Lowe struct Dwarf_Hash_Table_s {
410*4d9fdb46SRobert Mustacchi     unsigned long       tb_table_entry_count;
411*4d9fdb46SRobert Mustacchi     unsigned long       tb_total_abbrev_count;
412*4d9fdb46SRobert Mustacchi     /* Each table entry is a list of abbreviations. */
413*4d9fdb46SRobert Mustacchi     struct  Dwarf_Hash_Table_Entry_s *tb_entries;
41407dc1947SRichard Lowe };
41549d3bc91SRichard Lowe 
41649d3bc91SRichard Lowe /*
41749d3bc91SRichard Lowe     This struct is used to build a hash table for the
418*4d9fdb46SRobert Mustacchi     abbreviation codes for a compile-unit.
41949d3bc91SRichard Lowe */
42007dc1947SRichard Lowe struct Dwarf_Hash_Table_Entry_s {
42149d3bc91SRichard Lowe     Dwarf_Abbrev_List at_head;
42249d3bc91SRichard Lowe };
42349d3bc91SRichard Lowe 
42407dc1947SRichard Lowe 
42507dc1947SRichard Lowe 
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);
42949d3bc91SRichard Lowe 
43049d3bc91SRichard Lowe 
43149d3bc91SRichard Lowe /* return 1 if string ends before 'endptr' else
43249d3bc91SRichard Lowe ** return 0 meaning string is not properly terminated.
43349d3bc91SRichard Lowe ** Presumption is the 'endptr' pts to end of some dwarf section data.
43449d3bc91SRichard Lowe */
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);
438*4d9fdb46SRobert 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);
44349d3bc91SRichard Lowe 
444*4d9fdb46SRobert Mustacchi Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug,Dwarf_Bool dinfo);
44549d3bc91SRichard Lowe 
44607dc1947SRichard Lowe 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);
44807dc1947SRichard Lowe void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,
44907dc1947SRichard Lowe     struct Dwarf_Hash_Table_s* hash_table);
45007dc1947SRichard Lowe 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 
50107dc1947SRichard Lowe 
50207dc1947SRichard Lowe #endif /* DWARF_UTIL_H */
503