dwarf_util.h
4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
dwarf_util.h
$Revision: 1.1.1.1 $ $Date: 2002/05/02 03:29:20 $
*/
#include <limits.h>
/*
Decodes unsigned leb128 encoded numbers that
are assumed to be less than 4 bytes long.
Make sure ptr is a pointer to a 1-byte type.
Returns UINT_MAX on error.
Limits.h is included to define UINT_MAX.
*/
#define DECODE_LEB128_UWORD(ptr, value) \
{ \
Dwarf_Small byte; \
\
value = (byte = *(ptr++)) & 0x7f; \
if ((byte & 0x80) != 0) { \
value |= ((byte = *(ptr++)) & 0x7f) << 7; \
if ((byte & 0x80) != 0) { \
value |= ((byte = *(ptr++)) & 0x7f) << 14; \
if ((byte & 0x80) != 0) { \
value |= ((byte = *(ptr++)) & 0x7f) << 21; \
if ((byte & 0x80) != 0) { \
value = UINT_MAX; \
} \
} \
} \
} \
}
/*
Decodes signed leb128 encoded numbers that
are assumed to be less than 4 bytes long.
Make sure ptr is a pointer to a 1-byte type.
Returns INT_MAX on error.
Make sure value is a 4-byte signed int.
*/
#define DECODE_LEB128_SWORD(ptr, value) \
{ \
Dwarf_Small byte; \
\
value = (byte = *(ptr++)) & 0x7f; \
if ((byte & 0x80) == 0) { \
if ((byte & 0x40) != 0) \
value |= 0xffffff80; \
} \
else { \
value |= ((byte = *(ptr++)) & 0x7f) << 7; \
if ((byte & 0x80) == 0) { \
if ((byte & 0x40) != 0) \
value |= 0xffffc000; \
} \
else { \
value |= ((byte = *(ptr++)) & 0x7f) << 14; \
if ((byte & 0x80) == 0) { \
if ((byte & 0x40) != 0) \
value |= 0xffe00000; \
} \
else { \
value |= ((byte = *(ptr++)) & 0x7f) << 21; \
if ((byte & 0x80) == 0) { \
if ((byte & 0x40) != 0) \
value |= 0xf0000000; \
} \
else \
value = INT_MAX; \
} \
} \
} \
}
/*
Skips leb128_encoded numbers that are guaranteed
to be no more than 4 bytes long. Same for both
signed and unsigned numbers.
*/
#define SKIP_LEB128_WORD(ptr) \
if ((*(ptr++) & 0x80) != 0) { \
if ((*(ptr++) & 0x80) != 0) { \
if ((*(ptr++) & 0x80) != 0) { \
if ((*(ptr++) & 0x80) != 0) { \
} \
} \
} \
}
#define CHECK_DIE(die, error_ret_value) \
if (die == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
return(error_ret_value); \
} \
if (die->di_cu_context == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
return(error_ret_value); \
} \
if (die->di_cu_context->cc_dbg == NULL) { \
_dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
return(error_ret_value); \
}
/*
This macro copies length number of bytes from source to dest.
The actual destination address is adjusted to account for the
difference in the number of bytes in dest, and length.
*/
#define READ_UNALIGNED(dest, source, length) \
dest = 0; \
if (length > sizeof(dest)) \
memcpy(&dest, (char *)source + length - sizeof(dest), sizeof(dest)); \
else \
memcpy((char *)&dest + sizeof(dest) - length, source, length)
/*
This macro sign-extends a variable depending on the length.
It fills the bytes between the size of the destination and
the length with appropriate padding.
*/
#define SIGN_EXTEND(dest, length) \
if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) \
memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \
sizeof(dest) - length)
Dwarf_Unsigned
_dwarf_decode_u_leb128 (
Dwarf_Small *leb128,
Dwarf_Word *leb128_length
);
Dwarf_Signed
_dwarf_decode_s_leb128 (
Dwarf_Small *leb128,
Dwarf_Word *leb128_length
);
Dwarf_Unsigned
_dwarf_get_size_of_val (
Dwarf_Debug dbg,
Dwarf_Unsigned form,
Dwarf_Small *val_ptr
);
/*
This struct is used to build a hash table for the
abbreviation codes for a compile-unit.
*/
struct Dwarf_Hash_Table_s {
Dwarf_Abbrev_List at_head;
Dwarf_Abbrev_List at_tail;
};
Dwarf_Abbrev_List
_dwarf_get_abbrev_for_code (
Dwarf_CU_Context cu_context,
Dwarf_Word code
);
/* return 1 if string ends before 'endptr' else
** return 0 meaning string is not properly terminated.
** Presumption is the 'endptr' pts to end of some dwarf section data.
*/
int _dwarf_string_valid(void *startptr, void *endptr);