atosl 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +14 -0
- data/atosl.gemspec +25 -0
- data/bin/atosl +48 -0
- data/ext/atosl/atosl.c +153 -0
- data/ext/atosl/atosl.h +4 -0
- data/ext/atosl/converter.c +411 -0
- data/ext/atosl/converter.h +9 -0
- data/ext/atosl/cputype.h +347 -0
- data/ext/atosl/debug.h +11 -0
- data/ext/atosl/dwarf2.h +844 -0
- data/ext/atosl/extconf.rb +9 -0
- data/ext/atosl/fat.h +25 -0
- data/ext/atosl/loader.h +1440 -0
- data/ext/atosl/macho.c +3333 -0
- data/ext/atosl/macho.h +602 -0
- data/ext/atosl/main.h +4 -0
- data/ext/atosl/nlist.h +312 -0
- data/lib/atosl.rb +8 -0
- data/lib/atosl/version.rb +3 -0
- data/test/test_atosl.rb +8 -0
- metadata +114 -0
data/ext/atosl/macho.c
ADDED
@@ -0,0 +1,3333 @@
|
|
1
|
+
/*
|
2
|
+
* =====================================================================================
|
3
|
+
*
|
4
|
+
* Filename: macho.c
|
5
|
+
*
|
6
|
+
* Description: Mach-O Reader
|
7
|
+
*
|
8
|
+
* Version: 1.0
|
9
|
+
* Created: 02/17/2013 22:51:27
|
10
|
+
* Revision: none
|
11
|
+
* Compiler: gcc
|
12
|
+
*
|
13
|
+
* Author: Reno Qiu
|
14
|
+
* Organization:
|
15
|
+
*
|
16
|
+
* =====================================================================================
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "macho.h"
|
20
|
+
|
21
|
+
char *project_name;
|
22
|
+
|
23
|
+
static struct die_info * read_die_and_children (char *info_ptr, struct dwarf2_cu *cu, char **new_info_ptr, struct die_info *parent);
|
24
|
+
static struct die_info * read_die_and_siblings (char *info_ptr, struct dwarf2_cu *cu, char **new_info_ptr, struct die_info *parent);
|
25
|
+
|
26
|
+
/* Free the line_header structure *LH, and any arrays and strings it
|
27
|
+
refers to. */
|
28
|
+
static void free_line_header (struct line_header *lh)
|
29
|
+
{
|
30
|
+
if (lh->standard_opcode_lengths)
|
31
|
+
free (lh->standard_opcode_lengths);
|
32
|
+
|
33
|
+
/* Remember that all the lh->file_names[i].name pointers are
|
34
|
+
pointers into debug_line_buffer, and don't need to be freed. */
|
35
|
+
if (lh->file_names)
|
36
|
+
free (lh->file_names);
|
37
|
+
|
38
|
+
/* Similarly for the include directory names. */
|
39
|
+
if (lh->include_dirs)
|
40
|
+
free (lh->include_dirs);
|
41
|
+
|
42
|
+
free (lh);
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
static CORE_ADDR read_signed_16(char *info_ptr){
|
47
|
+
signed int ret = 0;
|
48
|
+
ret = info_ptr[1];
|
49
|
+
ret = (ret << 8) + info_ptr[0];
|
50
|
+
return ret;
|
51
|
+
}
|
52
|
+
|
53
|
+
static signed int read_signed_32(char *info_ptr){
|
54
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
55
|
+
signed int ret = 0;
|
56
|
+
ret = temp_ptr[3];
|
57
|
+
ret = (ret << 8) + temp_ptr[2];
|
58
|
+
ret = (ret << 8) + temp_ptr[1];
|
59
|
+
ret = (ret << 8) + temp_ptr[0];
|
60
|
+
return ret;
|
61
|
+
}
|
62
|
+
|
63
|
+
static int64_t read_signed_64(char *info_ptr){
|
64
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
65
|
+
int64_t ret = 0;
|
66
|
+
ret = temp_ptr[7];
|
67
|
+
ret = (ret << 8) + temp_ptr[6];
|
68
|
+
ret = (ret << 8) + temp_ptr[5];
|
69
|
+
ret = (ret << 8) + temp_ptr[4];
|
70
|
+
ret = (ret << 8) + temp_ptr[3];
|
71
|
+
ret = (ret << 8) + temp_ptr[2];
|
72
|
+
ret = (ret << 8) + temp_ptr[1];
|
73
|
+
ret = (ret << 8) + temp_ptr[0];
|
74
|
+
return ret;
|
75
|
+
}
|
76
|
+
|
77
|
+
static unsigned int read_1_byte (char *info_ptr)
|
78
|
+
{
|
79
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
80
|
+
return *temp_ptr;
|
81
|
+
}
|
82
|
+
|
83
|
+
static int read_1_signed_byte (char *buf)
|
84
|
+
{
|
85
|
+
int ret = 0;
|
86
|
+
ret = (int)*buf;
|
87
|
+
return ret;
|
88
|
+
}
|
89
|
+
|
90
|
+
static unsigned int read_2_bytes (char *info_ptr)
|
91
|
+
{
|
92
|
+
//read bytes little endian?
|
93
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
94
|
+
unsigned short ret = 0;
|
95
|
+
ret = temp_ptr[1];
|
96
|
+
ret = (ret << 8) + temp_ptr[0];
|
97
|
+
return ret;
|
98
|
+
}
|
99
|
+
|
100
|
+
static unsigned int read_4_bytes(char *info_ptr)
|
101
|
+
{
|
102
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
103
|
+
unsigned int ret = 0;
|
104
|
+
ret = temp_ptr[3];
|
105
|
+
ret = (ret << 8) + temp_ptr[2];
|
106
|
+
ret = (ret << 8) + temp_ptr[1];
|
107
|
+
ret = (ret << 8) + temp_ptr[0];
|
108
|
+
return ret;
|
109
|
+
}
|
110
|
+
|
111
|
+
static unsigned long read_8_bytes (char *info_ptr)
|
112
|
+
{
|
113
|
+
//read bytes little endian?
|
114
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
115
|
+
unsigned long ret = 0;
|
116
|
+
ret = temp_ptr[7];
|
117
|
+
ret = (ret << 8) + temp_ptr[6];
|
118
|
+
ret = (ret << 8) + temp_ptr[5];
|
119
|
+
ret = (ret << 8) + temp_ptr[4];
|
120
|
+
ret = (ret << 8) + temp_ptr[3];
|
121
|
+
ret = (ret << 8) + temp_ptr[2];
|
122
|
+
ret = (ret << 8) + temp_ptr[1];
|
123
|
+
ret = (ret << 8) + temp_ptr[0];
|
124
|
+
return ret;
|
125
|
+
}
|
126
|
+
|
127
|
+
static unsigned int read_unsigned_int(char *info_ptr){
|
128
|
+
//read bytes little endian?
|
129
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
130
|
+
unsigned int ret = 0;
|
131
|
+
ret = temp_ptr[3];
|
132
|
+
ret = (ret << 8) + temp_ptr[2];
|
133
|
+
ret = (ret << 8) + temp_ptr[1];
|
134
|
+
ret = (ret << 8) + temp_ptr[0];
|
135
|
+
return ret;
|
136
|
+
}
|
137
|
+
|
138
|
+
static unsigned short read_unsigned_short(char *info_ptr){
|
139
|
+
//read bytes little endian?
|
140
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
141
|
+
unsigned short ret = 0;
|
142
|
+
ret = temp_ptr[1];
|
143
|
+
ret = (ret << 8) + temp_ptr[0];
|
144
|
+
return ret;
|
145
|
+
}
|
146
|
+
|
147
|
+
static unsigned char read_unsigned_char(char *info_ptr){
|
148
|
+
unsigned char * temp_ptr = (unsigned char *)info_ptr;
|
149
|
+
unsigned char ret = 0;
|
150
|
+
ret = temp_ptr[0];
|
151
|
+
return ret;
|
152
|
+
}
|
153
|
+
|
154
|
+
static long long read_signed_leb128(char* leb128_str, unsigned int* leb128_length)
|
155
|
+
{
|
156
|
+
unsigned char * leb128 = (unsigned char * )leb128_str;
|
157
|
+
signed long long number = 0;
|
158
|
+
int sign = 0;
|
159
|
+
signed long shift = 0;
|
160
|
+
unsigned char byte = *leb128;
|
161
|
+
signed long byte_length = 1;
|
162
|
+
|
163
|
+
/* byte_length being the number of bytes of data absorbed so far in
|
164
|
+
* turning the leb into a Dwarf_Signed. */
|
165
|
+
|
166
|
+
for (;;) {
|
167
|
+
sign = byte & 0x40;
|
168
|
+
number |= ((signed long long) ((byte & 0x7f))) << shift;
|
169
|
+
shift += 7;
|
170
|
+
|
171
|
+
if ((byte & 0x80) == 0) {
|
172
|
+
break;
|
173
|
+
}
|
174
|
+
++leb128;
|
175
|
+
byte = *leb128;
|
176
|
+
byte_length++;
|
177
|
+
}
|
178
|
+
|
179
|
+
if (((unsigned long long)shift < sizeof(signed long long) * 8) && sign) {
|
180
|
+
number |= -((signed long long) 1 << shift);
|
181
|
+
}
|
182
|
+
|
183
|
+
if (leb128_length != NULL)
|
184
|
+
*leb128_length = byte_length;
|
185
|
+
return (number);
|
186
|
+
}
|
187
|
+
|
188
|
+
|
189
|
+
static unsigned long long read_unsigned_leb128(char* leb128_str, unsigned int* leb128_length)
|
190
|
+
{
|
191
|
+
unsigned char byte;
|
192
|
+
unsigned long word_number;
|
193
|
+
unsigned long long number;
|
194
|
+
signed long shift;
|
195
|
+
signed long byte_length;
|
196
|
+
unsigned char * leb128 = (unsigned char * )leb128_str;
|
197
|
+
|
198
|
+
/* The following unrolls-the-loop for the first few bytes and
|
199
|
+
* unpacks into 32 bits to make this as fast as possible.
|
200
|
+
* word_number is assumed big enough that the shift has a defined
|
201
|
+
* result. */
|
202
|
+
if ((*leb128 & 0x80) == 0) {
|
203
|
+
if (leb128_length != NULL)
|
204
|
+
*leb128_length = 1;
|
205
|
+
return (*leb128);
|
206
|
+
} else if ((*(leb128 + 1) & 0x80) == 0) {
|
207
|
+
if (leb128_length != NULL)
|
208
|
+
*leb128_length = 2;
|
209
|
+
|
210
|
+
word_number = *leb128 & 0x7f;
|
211
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
212
|
+
return (word_number);
|
213
|
+
} else if ((*(leb128 + 2) & 0x80) == 0) {
|
214
|
+
if (leb128_length != NULL)
|
215
|
+
*leb128_length = 3;
|
216
|
+
|
217
|
+
word_number = *leb128 & 0x7f;
|
218
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
219
|
+
word_number |= (*(leb128 + 2) & 0x7f) << 14;
|
220
|
+
return (word_number);
|
221
|
+
} else if ((*(leb128 + 3) & 0x80) == 0) {
|
222
|
+
if (leb128_length != NULL)
|
223
|
+
*leb128_length = 4;
|
224
|
+
|
225
|
+
word_number = *leb128 & 0x7f;
|
226
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
227
|
+
word_number |= (*(leb128 + 2) & 0x7f) << 14;
|
228
|
+
word_number |= (*(leb128 + 3) & 0x7f) << 21;
|
229
|
+
return (word_number);
|
230
|
+
}
|
231
|
+
|
232
|
+
/* The rest handles long numbers Because the 'number' may be larger
|
233
|
+
* than the default int/unsigned, we must cast the 'byte' before
|
234
|
+
* the shift for the shift to have a defined result. */
|
235
|
+
number = 0;
|
236
|
+
shift = 0;
|
237
|
+
byte_length = 1;
|
238
|
+
byte = *(leb128);
|
239
|
+
for (;;) {
|
240
|
+
number |= ((unsigned int) (byte & 0x7f)) << shift;
|
241
|
+
|
242
|
+
if ((byte & 0x80) == 0) {
|
243
|
+
if (leb128_length != NULL)
|
244
|
+
*leb128_length = byte_length;
|
245
|
+
return (number);
|
246
|
+
}
|
247
|
+
shift += 7;
|
248
|
+
|
249
|
+
byte_length++;
|
250
|
+
++leb128;
|
251
|
+
byte = *leb128;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
|
256
|
+
static char * read_string (char *buf, unsigned int *bytes_read_ptr)
|
257
|
+
{
|
258
|
+
if (*buf == '\0')
|
259
|
+
{
|
260
|
+
*bytes_read_ptr = 1;
|
261
|
+
return NULL;
|
262
|
+
}
|
263
|
+
*bytes_read_ptr = strlen (buf) + 1;
|
264
|
+
return buf;
|
265
|
+
}
|
266
|
+
|
267
|
+
/* Read an offset from the data stream. The size of the offset is
|
268
|
+
given by cu_header->offset_size. */
|
269
|
+
|
270
|
+
static long read_offset (char *buf, const struct comp_unit_head *cu_header, int *bytes_read)
|
271
|
+
{
|
272
|
+
long retval = 0;
|
273
|
+
|
274
|
+
switch (cu_header->offset_size)
|
275
|
+
{
|
276
|
+
case 4:
|
277
|
+
retval = read_4_bytes(buf);
|
278
|
+
*bytes_read = 4;
|
279
|
+
break;
|
280
|
+
case 8:
|
281
|
+
retval = read_8_bytes(buf);
|
282
|
+
*bytes_read = 8;
|
283
|
+
break;
|
284
|
+
default:
|
285
|
+
printf("read_offset: bad switch\n");
|
286
|
+
}
|
287
|
+
|
288
|
+
return retval;
|
289
|
+
}
|
290
|
+
|
291
|
+
|
292
|
+
static CORE_ADDR read_address_of_cu (char *buf, struct dwarf2_cu *cu, int *bytes_read)
|
293
|
+
{
|
294
|
+
struct comp_unit_head *cu_header = &cu->header;
|
295
|
+
CORE_ADDR retval = 0;
|
296
|
+
|
297
|
+
switch (cu_header->addr_size)
|
298
|
+
{
|
299
|
+
case 2:
|
300
|
+
//unsigned
|
301
|
+
retval = read_signed_16(buf);
|
302
|
+
break;
|
303
|
+
case 4:
|
304
|
+
retval = read_signed_32(buf);
|
305
|
+
break;
|
306
|
+
case 8:
|
307
|
+
retval = read_signed_64(buf);
|
308
|
+
break;
|
309
|
+
default:
|
310
|
+
printf("read address: bad switch, signed\n");
|
311
|
+
}
|
312
|
+
|
313
|
+
*bytes_read = cu_header->addr_size;
|
314
|
+
return retval;
|
315
|
+
}
|
316
|
+
|
317
|
+
/* Read the initial length from a section. The (draft) DWARF 3
|
318
|
+
specification allows the initial length to take up either 4 bytes
|
319
|
+
or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8
|
320
|
+
bytes describe the length and all offsets will be 8 bytes in length
|
321
|
+
instead of 4.
|
322
|
+
|
323
|
+
An older, non-standard 64-bit format is also handled by this
|
324
|
+
function. The older format in question stores the initial length
|
325
|
+
as an 8-byte quantity without an escape value. Lengths greater
|
326
|
+
than 2^32 aren't very common which means that the initial 4 bytes
|
327
|
+
is almost always zero. Since a length value of zero doesn't make
|
328
|
+
sense for the 32-bit format, this initial zero can be considered to
|
329
|
+
be an escape value which indicates the presence of the older 64-bit
|
330
|
+
format. As written, the code can't detect (old format) lengths
|
331
|
+
greater than 4GB. If it becomes necessary to handle lengths
|
332
|
+
somewhat larger than 4GB, we could allow other small values (such
|
333
|
+
as the non-sensical values of 1, 2, and 3) to also be used as
|
334
|
+
escape values indicating the presence of the old format.
|
335
|
+
|
336
|
+
The value returned via bytes_read should be used to increment the
|
337
|
+
relevant pointer after calling read_initial_length_of_comp_unit().
|
338
|
+
|
339
|
+
As a side effect, this function sets the fields initial_length_size
|
340
|
+
and offset_size in cu_header to the values appropriate for the
|
341
|
+
length field. (The format of the initial length field determines
|
342
|
+
the width of file offsets to be fetched later with read_offset().)
|
343
|
+
|
344
|
+
[ Note: read_initial_length_of_comp_unit() and read_offset() are based on the
|
345
|
+
document entitled "DWARF Debugging Information Format", revision
|
346
|
+
3, draft 8, dated November 19, 2001. This document was obtained
|
347
|
+
from:
|
348
|
+
|
349
|
+
http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf
|
350
|
+
|
351
|
+
This document is only a draft and is subject to change. (So beware.)
|
352
|
+
|
353
|
+
Details regarding the older, non-standard 64-bit format were
|
354
|
+
determined empirically by examining 64-bit ELF files produced by
|
355
|
+
the SGI toolchain on an IRIX 6.5 machine.
|
356
|
+
|
357
|
+
- Kevin, July 16, 2002
|
358
|
+
] */
|
359
|
+
static long read_initial_length_of_aranges(char *buf, struct aranges_header *aranges_header, int *bytes_read){
|
360
|
+
long length = read_4_bytes(buf);
|
361
|
+
return length;
|
362
|
+
}
|
363
|
+
|
364
|
+
static long read_initial_length_of_comp_unit (char *buf, struct comp_unit_head *cu_header,
|
365
|
+
int *bytes_read)
|
366
|
+
{
|
367
|
+
long length = read_4_bytes(buf);
|
368
|
+
|
369
|
+
if (length == 0xffffffff)
|
370
|
+
{
|
371
|
+
length = read_8_bytes(buf + 4);
|
372
|
+
*bytes_read = 12;
|
373
|
+
}
|
374
|
+
else if (length == 0)
|
375
|
+
{
|
376
|
+
/* Handle the (non-standard) 63-bit DWARF2 format used by IRIX. */
|
377
|
+
length = read_8_bytes(buf + 4);
|
378
|
+
*bytes_read = 8;
|
379
|
+
}
|
380
|
+
else
|
381
|
+
{
|
382
|
+
*bytes_read = 4;
|
383
|
+
}
|
384
|
+
|
385
|
+
if (cu_header)
|
386
|
+
{
|
387
|
+
assert (cu_header->initial_length_size == 0
|
388
|
+
|| cu_header->initial_length_size == 4
|
389
|
+
|| cu_header->initial_length_size == 8
|
390
|
+
|| cu_header->initial_length_size == 12);
|
391
|
+
|
392
|
+
if(cu_header->initial_length_size != 0
|
393
|
+
&& cu_header->initial_length_size != 4
|
394
|
+
&& cu_header->initial_length_size != 8
|
395
|
+
&& cu_header->initial_length_size != 12){
|
396
|
+
PyErr_Format(ATOSError, "cu_header->initial_length_size invalid");
|
397
|
+
return -1;
|
398
|
+
}
|
399
|
+
|
400
|
+
if (cu_header->initial_length_size != 0 && cu_header->initial_length_size != *bytes_read){
|
401
|
+
PyErr_Format(ATOSError, "cu_header->initial_length_size is not equal to bytes_read");
|
402
|
+
fprintf(stderr, "cu_header->initial_length_size is not equal to bytes_read\n");
|
403
|
+
return -1;
|
404
|
+
}
|
405
|
+
|
406
|
+
cu_header->initial_length_size = *bytes_read;
|
407
|
+
cu_header->offset_size = (*bytes_read == 4) ? 4 : 8;
|
408
|
+
}
|
409
|
+
|
410
|
+
return length;
|
411
|
+
}
|
412
|
+
|
413
|
+
/* Add an entry to LH's include directory table. */
|
414
|
+
static void add_include_dir (struct line_header *lh, char *include_dir)
|
415
|
+
{
|
416
|
+
/* Grow the array if necessary. */
|
417
|
+
if (lh->include_dirs_size == 0)
|
418
|
+
{
|
419
|
+
lh->include_dirs_size = 1; /* for testing */
|
420
|
+
lh->include_dirs = malloc (lh->include_dirs_size * sizeof (*lh->include_dirs));
|
421
|
+
}
|
422
|
+
else if (lh->num_include_dirs >= lh->include_dirs_size)
|
423
|
+
{
|
424
|
+
lh->include_dirs_size *= 2;
|
425
|
+
lh->include_dirs = realloc (lh->include_dirs, (lh->include_dirs_size * sizeof (*lh->include_dirs)));
|
426
|
+
}
|
427
|
+
|
428
|
+
lh->include_dirs[lh->num_include_dirs++] = include_dir;
|
429
|
+
}
|
430
|
+
|
431
|
+
/* Add an entry to LH's file name table. */
|
432
|
+
static void add_file_name (struct line_header *lh,
|
433
|
+
char *name,
|
434
|
+
unsigned int dir_index,
|
435
|
+
unsigned int mod_time,
|
436
|
+
unsigned int length)
|
437
|
+
{
|
438
|
+
struct file_entry *fe;
|
439
|
+
|
440
|
+
/* Grow the array if necessary. */
|
441
|
+
if (lh->file_names_size == 0)
|
442
|
+
{
|
443
|
+
lh->file_names_size = 1; /* for testing */
|
444
|
+
lh->file_names = malloc (lh->file_names_size
|
445
|
+
* sizeof (*lh->file_names));
|
446
|
+
}
|
447
|
+
else if (lh->num_file_names >= lh->file_names_size)
|
448
|
+
{
|
449
|
+
lh->file_names_size *= 2;
|
450
|
+
lh->file_names = realloc (lh->file_names,
|
451
|
+
(lh->file_names_size
|
452
|
+
* sizeof (*lh->file_names)));
|
453
|
+
}
|
454
|
+
|
455
|
+
fe = &lh->file_names[lh->num_file_names++];
|
456
|
+
fe->name = name;
|
457
|
+
fe->dir_index = dir_index;
|
458
|
+
fe->mod_time = mod_time;
|
459
|
+
fe->length = length;
|
460
|
+
fe->included_p = 0;
|
461
|
+
}
|
462
|
+
|
463
|
+
/* Read the statement program header starting at OFFSET in
|
464
|
+
.debug_line, according to the endianness of ABFD. Return a pointer
|
465
|
+
to a struct line_header, allocated using xmalloc.
|
466
|
+
|
467
|
+
NOTE: the strings in the include directory and file name tables of
|
468
|
+
the returned object point into debug_line_buffer, and must not be
|
469
|
+
freed. */
|
470
|
+
static struct line_header * dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
|
471
|
+
{
|
472
|
+
struct dwarf2_per_objfile *dwarf2_per_objfile = cu->dwarf2_per_objfile;
|
473
|
+
// struct cleanup *back_to;
|
474
|
+
struct line_header *lh;
|
475
|
+
char *line_ptr;
|
476
|
+
/* APPLE LOCAL avoid type warnings by making BYTES_READ unsigned. */
|
477
|
+
unsigned bytes_read;
|
478
|
+
int i;
|
479
|
+
char *cur_dir, *cur_file;
|
480
|
+
|
481
|
+
if (dwarf2_per_objfile->line_buffer == NULL)
|
482
|
+
{
|
483
|
+
printf("missing .debug_line section\n");
|
484
|
+
PyErr_Format(ATOSError, "missing .debug_line section");
|
485
|
+
return NULL;
|
486
|
+
}
|
487
|
+
|
488
|
+
/* Make sure that at least there's room for the total_length field.
|
489
|
+
That could be 12 bytes long, but we're just going to fudge that. */
|
490
|
+
if (offset + 4 >= dwarf2_per_objfile->line_size)
|
491
|
+
{
|
492
|
+
//dwarf2_statement_list_fits_in_line_number_section_complaint ();
|
493
|
+
printf(".debug_line incomplete.\n");
|
494
|
+
PyErr_Format(ATOSError, ".debug_line incomplete");
|
495
|
+
return NULL;
|
496
|
+
}
|
497
|
+
|
498
|
+
lh = malloc (sizeof (*lh));
|
499
|
+
memset (lh, 0, sizeof (*lh));
|
500
|
+
//back_to = make_cleanup ((make_cleanup_ftype *) free_line_header, (void *) lh);
|
501
|
+
|
502
|
+
line_ptr = dwarf2_per_objfile->line_buffer + offset;
|
503
|
+
|
504
|
+
/* Read in the header. */
|
505
|
+
/* APPLE LOCAL Add cast to avoid type mismatch in arg4 warning. */
|
506
|
+
lh->total_length = read_initial_length_of_comp_unit (line_ptr, &cu->header, (int *) &bytes_read);
|
507
|
+
if(lh->total_length == -1){
|
508
|
+
return NULL;
|
509
|
+
}
|
510
|
+
line_ptr += bytes_read;
|
511
|
+
if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer
|
512
|
+
+ dwarf2_per_objfile->line_size))
|
513
|
+
{
|
514
|
+
printf(".debug_line incomplete.\n");
|
515
|
+
PyErr_Format(ATOSError, ".debug_line incomplete");
|
516
|
+
return NULL;
|
517
|
+
}
|
518
|
+
lh->statement_program_end = line_ptr + lh->total_length;
|
519
|
+
lh->version = read_2_bytes (line_ptr);
|
520
|
+
line_ptr += 2;
|
521
|
+
/* APPLE LOCAL Add cast to avoid type mismatch in arg4 warning. */
|
522
|
+
lh->header_length = read_offset (line_ptr, &cu->header, (int *) &bytes_read);
|
523
|
+
line_ptr += bytes_read;
|
524
|
+
lh->minimum_instruction_length = read_1_byte (line_ptr);
|
525
|
+
line_ptr += 1;
|
526
|
+
lh->default_is_stmt = read_1_byte (line_ptr);
|
527
|
+
line_ptr += 1;
|
528
|
+
lh->line_base = read_1_signed_byte (line_ptr);
|
529
|
+
line_ptr += 1;
|
530
|
+
lh->line_range = read_1_byte (line_ptr);
|
531
|
+
line_ptr += 1;
|
532
|
+
lh->opcode_base = read_1_byte (line_ptr);
|
533
|
+
line_ptr += 1;
|
534
|
+
lh->standard_opcode_lengths = (unsigned char *) malloc (lh->opcode_base * sizeof (unsigned char));
|
535
|
+
|
536
|
+
lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
|
537
|
+
for (i = 1; i < lh->opcode_base; ++i)
|
538
|
+
{
|
539
|
+
lh->standard_opcode_lengths[i] = read_1_byte (line_ptr);
|
540
|
+
line_ptr += 1;
|
541
|
+
}
|
542
|
+
|
543
|
+
/* Read directory table. */
|
544
|
+
while ((cur_dir = read_string (line_ptr, &bytes_read)) != NULL)
|
545
|
+
{
|
546
|
+
line_ptr += bytes_read;
|
547
|
+
add_include_dir (lh, cur_dir);
|
548
|
+
}
|
549
|
+
line_ptr += bytes_read;
|
550
|
+
|
551
|
+
/* Read file name table. */
|
552
|
+
while ((cur_file = read_string (line_ptr, &bytes_read)) != NULL)
|
553
|
+
{
|
554
|
+
unsigned int dir_index, mod_time, length;
|
555
|
+
|
556
|
+
line_ptr += bytes_read;
|
557
|
+
dir_index = read_unsigned_leb128 (line_ptr, &bytes_read);
|
558
|
+
line_ptr += bytes_read;
|
559
|
+
mod_time = read_unsigned_leb128 (line_ptr, &bytes_read);
|
560
|
+
line_ptr += bytes_read;
|
561
|
+
length = read_unsigned_leb128 (line_ptr, &bytes_read);
|
562
|
+
line_ptr += bytes_read;
|
563
|
+
|
564
|
+
add_file_name (lh, cur_file, dir_index, mod_time, length);
|
565
|
+
}
|
566
|
+
line_ptr += bytes_read;
|
567
|
+
lh->statement_program_start = line_ptr;
|
568
|
+
|
569
|
+
if (line_ptr > (dwarf2_per_objfile->line_buffer + dwarf2_per_objfile->line_size)){
|
570
|
+
printf("line number info header doesn't fit in `.debug_line' section\n");
|
571
|
+
PyErr_Format(ATOSError, "line number info header doesn't fit in `.debug_line' section");
|
572
|
+
return NULL;
|
573
|
+
}
|
574
|
+
|
575
|
+
// discard_cleanups (back_to);
|
576
|
+
return lh;
|
577
|
+
}
|
578
|
+
|
579
|
+
/* Add a linetable entry for line number LINE and address PC to the
|
580
|
+
line vector for SUBFILE. */
|
581
|
+
|
582
|
+
static void record_line (struct subfile *subfile, int line, CORE_ADDR pc)
|
583
|
+
{
|
584
|
+
struct linetable_entry *e;
|
585
|
+
/* Ignore the dummy line number in libg.o */
|
586
|
+
|
587
|
+
if (line == 0xffff)
|
588
|
+
{
|
589
|
+
return;
|
590
|
+
}
|
591
|
+
|
592
|
+
/* Make sure line vector exists and is big enough. */
|
593
|
+
if (!subfile->line_vector)
|
594
|
+
{
|
595
|
+
subfile->line_vector_length = INITIAL_LINE_VECTOR_LENGTH;
|
596
|
+
subfile->line_vector = (struct linetable *) malloc (sizeof (struct linetable) + subfile->line_vector_length * sizeof (struct linetable_entry));
|
597
|
+
subfile->line_vector->nitems = 0;
|
598
|
+
/* APPLE LOCAL codewarrior support */
|
599
|
+
subfile->line_vector->lines_are_chars = 0;
|
600
|
+
//have_line_numbers = 1;
|
601
|
+
}
|
602
|
+
|
603
|
+
if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
|
604
|
+
{
|
605
|
+
subfile->line_vector_length *= 2;
|
606
|
+
subfile->line_vector = (struct linetable *) realloc ((char *) subfile->line_vector,
|
607
|
+
(sizeof (struct linetable)
|
608
|
+
+ (subfile->line_vector_length
|
609
|
+
* sizeof (struct linetable_entry))));
|
610
|
+
}
|
611
|
+
|
612
|
+
e = subfile->line_vector->item + subfile->line_vector->nitems++;
|
613
|
+
e->line = line;
|
614
|
+
e->pc = pc;
|
615
|
+
// e->pc = ADDR_BITS_REMOVE(pc);
|
616
|
+
}
|
617
|
+
|
618
|
+
/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
|
619
|
+
|
620
|
+
/* APPLE LOCAL make compare_line_numbers extern */
|
621
|
+
//static int compare_line_numbers (const void *ln1p, const void *ln2p)
|
622
|
+
//{
|
623
|
+
// struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
|
624
|
+
// struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
|
625
|
+
//
|
626
|
+
// /* Note: this code does not assume that CORE_ADDRs can fit in ints.
|
627
|
+
// Please keep it that way. */
|
628
|
+
// if (ln1->pc < ln2->pc)
|
629
|
+
// return -1;
|
630
|
+
//
|
631
|
+
// if (ln1->pc > ln2->pc)
|
632
|
+
// return 1;
|
633
|
+
//
|
634
|
+
// /* If pc equal, sort by line. I'm not sure whether this is optimum
|
635
|
+
// behavior (see comment at struct linetable in symtab.h). */
|
636
|
+
// return ln1->line - ln2->line;
|
637
|
+
//}
|
638
|
+
|
639
|
+
|
640
|
+
/* Decode the Line Number Program (LNP) for the given line_header
|
641
|
+
structure and CU. The actual information extracted and the type
|
642
|
+
of structures created from the LNP depends on the value of PST.
|
643
|
+
|
644
|
+
1. If PST is NULL, then this procedure uses the data from the program
|
645
|
+
to create all necessary symbol tables, and their linetables.
|
646
|
+
The compilation directory of the file is passed in COMP_DIR,
|
647
|
+
and must not be NULL.
|
648
|
+
|
649
|
+
2. If PST is not NULL, this procedure reads the program to determine
|
650
|
+
the list of files included by the unit represented by PST, and
|
651
|
+
builds all the associated partial symbol tables. In this case,
|
652
|
+
the value of COMP_DIR is ignored, and can thus be NULL (the COMP_DIR
|
653
|
+
is not used to compute the full name of the symtab, and therefore
|
654
|
+
omitting it when building the partial symtab does not introduce
|
655
|
+
the potential for inconsistency - a partial symtab and its associated
|
656
|
+
symbtab having a different fullname -). */
|
657
|
+
|
658
|
+
static struct subfile * dwarf_decode_lines (struct line_header *lh, char *comp_dir, struct dwarf2_cu *cu)
|
659
|
+
{
|
660
|
+
char *line_ptr;
|
661
|
+
char *line_end;
|
662
|
+
unsigned int bytes_read;
|
663
|
+
unsigned char op_code, extended_op, adj_opcode;
|
664
|
+
CORE_ADDR baseaddr;
|
665
|
+
//struct objfile *objfile = cu->objfile;
|
666
|
+
// const int decode_for_pst_p = (pst != NULL);
|
667
|
+
const int decode_for_pst_p = 0;
|
668
|
+
|
669
|
+
/* APPLE LOCAL: We'll need to skip linetable entries in functions that
|
670
|
+
were coalesced out. */
|
671
|
+
int record_linetable_entry = 1;
|
672
|
+
struct subfile *current_subfile = malloc (sizeof (struct subfile));
|
673
|
+
memset(current_subfile, 0, sizeof(struct subfile));
|
674
|
+
/* APPLE LOCAL */
|
675
|
+
//if (debug_debugmap)
|
676
|
+
// fprintf_unfiltered (gdb_stdlog,
|
677
|
+
// "debugmap: reading line program for %s\n",
|
678
|
+
// cu->per_cu->psymtab->filename);
|
679
|
+
|
680
|
+
//baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
|
681
|
+
baseaddr = 0;
|
682
|
+
|
683
|
+
line_ptr = lh->statement_program_start;
|
684
|
+
line_end = lh->statement_program_end;
|
685
|
+
|
686
|
+
/* Read the statement sequences until there's nothing left. */
|
687
|
+
while (line_ptr < line_end)
|
688
|
+
{
|
689
|
+
/* state machine registers */
|
690
|
+
CORE_ADDR address = 0;
|
691
|
+
unsigned int file = 1;
|
692
|
+
unsigned int line = 1;
|
693
|
+
//unsigned int column = 0;
|
694
|
+
int is_stmt = lh->default_is_stmt;
|
695
|
+
//int basic_block = 0;
|
696
|
+
int end_sequence = 0;
|
697
|
+
|
698
|
+
//if (!decode_for_pst_p && lh->num_file_names >= file)
|
699
|
+
//{
|
700
|
+
// /* Start a subfile for the current file of the state machine. */
|
701
|
+
// /* lh->include_dirs and lh->file_names are 0-based, but the
|
702
|
+
// directory and file name numbers in the statement program
|
703
|
+
// are 1-based. */
|
704
|
+
// struct file_entry *fe = &lh->file_names[file - 1];
|
705
|
+
// char *dir;
|
706
|
+
|
707
|
+
// if (fe->dir_index)
|
708
|
+
// dir = lh->include_dirs[fe->dir_index - 1];
|
709
|
+
// else
|
710
|
+
// dir = comp_dir;
|
711
|
+
// /* APPLE LOCAL: Pass in the compilation directory of this CU. */
|
712
|
+
// dwarf2_start_subfile (fe->name, dir, cu->comp_dir);
|
713
|
+
//}
|
714
|
+
|
715
|
+
/* Decode the table. */
|
716
|
+
while (!end_sequence)
|
717
|
+
{
|
718
|
+
op_code = read_1_byte (line_ptr);
|
719
|
+
line_ptr += 1;
|
720
|
+
|
721
|
+
if (op_code >= lh->opcode_base)
|
722
|
+
{
|
723
|
+
/* Special operand. */
|
724
|
+
adj_opcode = op_code - lh->opcode_base;
|
725
|
+
address += (adj_opcode / lh->line_range)
|
726
|
+
* lh->minimum_instruction_length;
|
727
|
+
line += lh->line_base + (adj_opcode % lh->line_range);
|
728
|
+
lh->file_names[file - 1].included_p = 1;
|
729
|
+
/* APPLE LOCAL: Skip linetable entries coalesced out */
|
730
|
+
if (!decode_for_pst_p && record_linetable_entry)
|
731
|
+
{
|
732
|
+
/* Append row to matrix using current values. */
|
733
|
+
//FIXME check_cu_functions
|
734
|
+
//record_line (current_subfile, line, check_cu_functions (address, cu));
|
735
|
+
record_line (current_subfile, line, address);
|
736
|
+
}
|
737
|
+
//basic_block = 1;
|
738
|
+
}
|
739
|
+
else switch (op_code)
|
740
|
+
{
|
741
|
+
case DW_LNS_extended_op:
|
742
|
+
read_unsigned_leb128 (line_ptr, &bytes_read);
|
743
|
+
line_ptr += bytes_read;
|
744
|
+
extended_op = read_1_byte (line_ptr);
|
745
|
+
line_ptr += 1;
|
746
|
+
switch (extended_op)
|
747
|
+
{
|
748
|
+
case DW_LNE_end_sequence:
|
749
|
+
end_sequence = 1;
|
750
|
+
lh->file_names[file - 1].included_p = 1;
|
751
|
+
/* APPLE LOCAL: Skip linetable entries coalesced out */
|
752
|
+
if (!decode_for_pst_p && record_linetable_entry){
|
753
|
+
//record_line (current_subfile, 0, address);
|
754
|
+
record_line (current_subfile, line, address);
|
755
|
+
}
|
756
|
+
break;
|
757
|
+
case DW_LNE_set_address:
|
758
|
+
/* APPLE LOCAL Add cast to avoid type mismatch in arg4 warn.*/
|
759
|
+
address = read_address_of_cu (line_ptr, cu, (int *) &bytes_read);
|
760
|
+
/* APPLE LOCAL: debug map */
|
761
|
+
{
|
762
|
+
//CORE_ADDR addr;
|
763
|
+
//FIXME
|
764
|
+
//if (translate_debug_map_address (cu, address, &addr, 0))
|
765
|
+
//{
|
766
|
+
// address = addr;
|
767
|
+
// record_linetable_entry = 1;
|
768
|
+
//}
|
769
|
+
//else
|
770
|
+
record_linetable_entry = 1;
|
771
|
+
}
|
772
|
+
line_ptr += bytes_read;
|
773
|
+
address += baseaddr;
|
774
|
+
break;
|
775
|
+
case DW_LNE_define_file:
|
776
|
+
{
|
777
|
+
char *cur_file;
|
778
|
+
unsigned int dir_index, mod_time, length;
|
779
|
+
|
780
|
+
cur_file = read_string (line_ptr, &bytes_read);
|
781
|
+
line_ptr += bytes_read;
|
782
|
+
dir_index =
|
783
|
+
read_unsigned_leb128 (line_ptr, &bytes_read);
|
784
|
+
line_ptr += bytes_read;
|
785
|
+
mod_time =
|
786
|
+
read_unsigned_leb128 (line_ptr, &bytes_read);
|
787
|
+
line_ptr += bytes_read;
|
788
|
+
length =
|
789
|
+
read_unsigned_leb128 (line_ptr, &bytes_read);
|
790
|
+
line_ptr += bytes_read;
|
791
|
+
add_file_name (lh, cur_file, dir_index, mod_time, length);
|
792
|
+
}
|
793
|
+
break;
|
794
|
+
default:
|
795
|
+
printf("mangled .debug_line section\n");
|
796
|
+
return NULL;
|
797
|
+
}
|
798
|
+
break;
|
799
|
+
case DW_LNS_copy:
|
800
|
+
lh->file_names[file - 1].included_p = 1;
|
801
|
+
/* APPLE LOCAL: Skip linetable entries coalesced out */
|
802
|
+
if (!decode_for_pst_p && record_linetable_entry)
|
803
|
+
// record_line (current_subfile, line, check_cu_functions (address, cu));
|
804
|
+
record_line (current_subfile, line, address);
|
805
|
+
//basic_block = 0;
|
806
|
+
break;
|
807
|
+
case DW_LNS_advance_pc:
|
808
|
+
address += lh->minimum_instruction_length
|
809
|
+
* read_unsigned_leb128 (line_ptr, &bytes_read);
|
810
|
+
line_ptr += bytes_read;
|
811
|
+
break;
|
812
|
+
case DW_LNS_advance_line:
|
813
|
+
line += read_signed_leb128 (line_ptr, &bytes_read);
|
814
|
+
line_ptr += bytes_read;
|
815
|
+
break;
|
816
|
+
case DW_LNS_set_file:
|
817
|
+
{
|
818
|
+
/* The arrays lh->include_dirs and lh->file_names are
|
819
|
+
0-based, but the directory and file name numbers in
|
820
|
+
the statement program are 1-based. */
|
821
|
+
|
822
|
+
file = read_unsigned_leb128 (line_ptr, &bytes_read);
|
823
|
+
line_ptr += bytes_read;
|
824
|
+
|
825
|
+
//struct file_entry *fe;
|
826
|
+
//fe = &lh->file_names[file - 1];
|
827
|
+
//char *dir = NULL;
|
828
|
+
//if (fe->dir_index)
|
829
|
+
// dir = lh->include_dirs[fe->dir_index - 1];
|
830
|
+
//else
|
831
|
+
// dir = comp_dir;
|
832
|
+
/* APPLE LOCAL: Pass in the compilation dir of this CU. */
|
833
|
+
//FIXME
|
834
|
+
//if (!decode_for_pst_p)
|
835
|
+
// dwarf2_start_subfile (fe->name, dir, cu->comp_dir);
|
836
|
+
}
|
837
|
+
break;
|
838
|
+
case DW_LNS_set_column:
|
839
|
+
//column = read_unsigned_leb128 (line_ptr, &bytes_read);
|
840
|
+
read_unsigned_leb128 (line_ptr, &bytes_read);
|
841
|
+
line_ptr += bytes_read;
|
842
|
+
break;
|
843
|
+
case DW_LNS_negate_stmt:
|
844
|
+
is_stmt = (!is_stmt);
|
845
|
+
break;
|
846
|
+
case DW_LNS_set_basic_block:
|
847
|
+
//basic_block = 1;
|
848
|
+
break;
|
849
|
+
/* Add to the address register of the state machine the
|
850
|
+
address increment value corresponding to special opcode
|
851
|
+
255. I.e., this value is scaled by the minimum
|
852
|
+
instruction length since special opcode 255 would have
|
853
|
+
scaled the the increment. */
|
854
|
+
case DW_LNS_const_add_pc:
|
855
|
+
address += (lh->minimum_instruction_length
|
856
|
+
* ((255 - lh->opcode_base) / lh->line_range));
|
857
|
+
break;
|
858
|
+
case DW_LNS_fixed_advance_pc:
|
859
|
+
address += read_2_bytes (line_ptr);
|
860
|
+
line_ptr += 2;
|
861
|
+
break;
|
862
|
+
default:
|
863
|
+
{
|
864
|
+
/* Unknown standard opcode, ignore it. */
|
865
|
+
int i;
|
866
|
+
|
867
|
+
for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
|
868
|
+
{
|
869
|
+
(void) read_unsigned_leb128 (line_ptr, &bytes_read);
|
870
|
+
line_ptr += bytes_read;
|
871
|
+
}
|
872
|
+
}
|
873
|
+
}
|
874
|
+
}
|
875
|
+
}
|
876
|
+
|
877
|
+
return current_subfile;
|
878
|
+
}
|
879
|
+
|
880
|
+
//static void set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
|
881
|
+
//{
|
882
|
+
// switch (lang)
|
883
|
+
// {
|
884
|
+
// case DW_LANG_C89:
|
885
|
+
// case DW_LANG_C:
|
886
|
+
// cu->language = language_c;
|
887
|
+
// break;
|
888
|
+
// case DW_LANG_C_plus_plus:
|
889
|
+
// cu->language = language_cplus;
|
890
|
+
// break;
|
891
|
+
// case DW_LANG_Fortran77:
|
892
|
+
// case DW_LANG_Fortran90:
|
893
|
+
// case DW_LANG_Fortran95:
|
894
|
+
// cu->language = language_fortran;
|
895
|
+
// break;
|
896
|
+
// case DW_LANG_Mips_Assembler:
|
897
|
+
// cu->language = language_asm;
|
898
|
+
// break;
|
899
|
+
// case DW_LANG_Java:
|
900
|
+
// cu->language = language_java;
|
901
|
+
// break;
|
902
|
+
// case DW_LANG_Ada83:
|
903
|
+
// case DW_LANG_Ada95:
|
904
|
+
// cu->language = language_ada;
|
905
|
+
// break;
|
906
|
+
// /* APPLE LOCAL: No need to be Apple local but not merged in to FSF.. */
|
907
|
+
// case DW_LANG_ObjC:
|
908
|
+
// cu->language = language_objc;
|
909
|
+
// break;
|
910
|
+
// /* APPLE LOCAL: No need to be Apple local but not merged in to FSF.. */
|
911
|
+
// case DW_LANG_ObjC_plus_plus:
|
912
|
+
// cu->language = language_objcplus;
|
913
|
+
// break;
|
914
|
+
// case DW_LANG_Cobol74:
|
915
|
+
// case DW_LANG_Cobol85:
|
916
|
+
// case DW_LANG_Pascal83:
|
917
|
+
// case DW_LANG_Modula2:
|
918
|
+
// default:
|
919
|
+
// cu->language = language_minimal;
|
920
|
+
// break;
|
921
|
+
// }
|
922
|
+
// //cu->language_defn = language_def (cu->language);
|
923
|
+
//}
|
924
|
+
//
|
925
|
+
void free_dwarf2_per_objfile(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
926
|
+
if(dwarf2_per_objfile->info_buffer){
|
927
|
+
free(dwarf2_per_objfile->info_buffer);
|
928
|
+
}
|
929
|
+
if(dwarf2_per_objfile->abbrev_buffer){
|
930
|
+
free(dwarf2_per_objfile->abbrev_buffer);
|
931
|
+
}
|
932
|
+
if(dwarf2_per_objfile->line_buffer){
|
933
|
+
free(dwarf2_per_objfile->line_buffer);
|
934
|
+
}
|
935
|
+
if(dwarf2_per_objfile->pubnames_buffer){
|
936
|
+
free(dwarf2_per_objfile->pubnames_buffer);
|
937
|
+
}
|
938
|
+
if(dwarf2_per_objfile->aranges_buffer){
|
939
|
+
free(dwarf2_per_objfile->aranges_buffer);
|
940
|
+
}
|
941
|
+
if(dwarf2_per_objfile->loc_buffer){
|
942
|
+
free(dwarf2_per_objfile->loc_buffer);
|
943
|
+
}
|
944
|
+
if(dwarf2_per_objfile->macinfo_buffer){
|
945
|
+
free(dwarf2_per_objfile->macinfo_buffer);
|
946
|
+
}
|
947
|
+
if(dwarf2_per_objfile->str_buffer){
|
948
|
+
free(dwarf2_per_objfile->str_buffer);
|
949
|
+
}
|
950
|
+
if(dwarf2_per_objfile->ranges_buffer){
|
951
|
+
free(dwarf2_per_objfile->ranges_buffer);
|
952
|
+
}
|
953
|
+
if(dwarf2_per_objfile->inlined_buffer){
|
954
|
+
free(dwarf2_per_objfile->inlined_buffer);
|
955
|
+
}
|
956
|
+
if(dwarf2_per_objfile->pubtypes_buffer){
|
957
|
+
free(dwarf2_per_objfile->pubtypes_buffer);
|
958
|
+
}
|
959
|
+
if(dwarf2_per_objfile->frame_buffer){
|
960
|
+
free(dwarf2_per_objfile->frame_buffer);
|
961
|
+
}
|
962
|
+
if(dwarf2_per_objfile->eh_frame_buffer){
|
963
|
+
free(dwarf2_per_objfile->eh_frame_buffer);
|
964
|
+
}
|
965
|
+
|
966
|
+
free(dwarf2_per_objfile);
|
967
|
+
}
|
968
|
+
|
969
|
+
void get_uuid_of_thin(struct thin_macho*thin_macho, char*uuid){
|
970
|
+
int i = 0;
|
971
|
+
while(i < 16){
|
972
|
+
sprintf(uuid + (i * 2), "%02x", thin_macho->uuid[i]);
|
973
|
+
i++;
|
974
|
+
}
|
975
|
+
}
|
976
|
+
|
977
|
+
static struct dwarf2_per_objfile* parse_dwarf_segment(char *macho_str, long offset,struct segment_command *command){
|
978
|
+
uint32_t numofdwarfsections = command->nsects;
|
979
|
+
|
980
|
+
struct dwarf2_per_objfile *dwarf2_per_objfile = malloc(sizeof(struct dwarf2_per_objfile));
|
981
|
+
if (dwarf2_per_objfile == NULL){
|
982
|
+
printf("Malloc Error!\n");
|
983
|
+
PyErr_NoMemory();
|
984
|
+
return NULL;
|
985
|
+
}
|
986
|
+
memset(dwarf2_per_objfile, '\0', sizeof(struct dwarf2_per_objfile));
|
987
|
+
|
988
|
+
struct section * dwarf_section_headers = malloc(numofdwarfsections * sizeof(struct section));
|
989
|
+
if (dwarf_section_headers == NULL){
|
990
|
+
printf("Malloc Error!\n");
|
991
|
+
PyErr_NoMemory();
|
992
|
+
return NULL;
|
993
|
+
}
|
994
|
+
memset(dwarf_section_headers, '\0', numofdwarfsections * sizeof (struct section));
|
995
|
+
memcpy(dwarf_section_headers, macho_str + offset, numofdwarfsections * sizeof(struct section));
|
996
|
+
|
997
|
+
uint32_t i = 0;
|
998
|
+
while(i < numofdwarfsections){
|
999
|
+
char *temp = malloc(dwarf_section_headers[i].size);
|
1000
|
+
if (temp == NULL){
|
1001
|
+
printf("Malloc Error!\n");
|
1002
|
+
PyErr_NoMemory();
|
1003
|
+
return NULL;
|
1004
|
+
}
|
1005
|
+
memset(temp, '\0', dwarf_section_headers[i].size);
|
1006
|
+
memcpy(temp, macho_str + dwarf_section_headers[i].offset, dwarf_section_headers[i].size);
|
1007
|
+
|
1008
|
+
if(strcmp(dwarf_section_headers[i].sectname, "__debug_abbrev") == 0){
|
1009
|
+
dwarf2_per_objfile->abbrev_buffer = temp;
|
1010
|
+
dwarf2_per_objfile->abbrev_size = dwarf_section_headers[i].size;
|
1011
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_aranges") == 0){
|
1012
|
+
dwarf2_per_objfile->aranges_buffer = temp;
|
1013
|
+
dwarf2_per_objfile->aranges_size = dwarf_section_headers[i].size;
|
1014
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_info") == 0){
|
1015
|
+
dwarf2_per_objfile->info_buffer = temp;
|
1016
|
+
dwarf2_per_objfile->info_size = dwarf_section_headers[i].size;
|
1017
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_inlined") == 0){
|
1018
|
+
dwarf2_per_objfile->inlined_buffer = temp;
|
1019
|
+
dwarf2_per_objfile->inlined_size = dwarf_section_headers[i].size;
|
1020
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_line") == 0){
|
1021
|
+
dwarf2_per_objfile->line_buffer = temp;
|
1022
|
+
dwarf2_per_objfile->line_size = dwarf_section_headers[i].size;
|
1023
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_loc") == 0){
|
1024
|
+
dwarf2_per_objfile->loc_buffer = temp;
|
1025
|
+
dwarf2_per_objfile->loc_size = dwarf_section_headers[i].size;
|
1026
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__debug_pubnames") == 0) ||
|
1027
|
+
(strcmp(dwarf_section_headers[i].sectname, "__debug_pubnames__DWARF") == 0)
|
1028
|
+
){
|
1029
|
+
dwarf2_per_objfile->pubnames_buffer = temp;
|
1030
|
+
dwarf2_per_objfile->pubnames_size = dwarf_section_headers[i].size;
|
1031
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__debug_pubtypes") == 0) ||
|
1032
|
+
(strcmp(dwarf_section_headers[i].sectname, "__debug_pubtypes__DWARF") == 0)
|
1033
|
+
){
|
1034
|
+
dwarf2_per_objfile->pubtypes_buffer = temp;
|
1035
|
+
dwarf2_per_objfile->pubtypes_size = dwarf_section_headers[i].size;
|
1036
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_ranges") == 0){
|
1037
|
+
dwarf2_per_objfile->ranges_buffer = temp;
|
1038
|
+
dwarf2_per_objfile->ranges_size = dwarf_section_headers[i].size;
|
1039
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_str") == 0){
|
1040
|
+
dwarf2_per_objfile->str_buffer = temp;
|
1041
|
+
dwarf2_per_objfile->str_size = dwarf_section_headers[i].size;
|
1042
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_frame") == 0){
|
1043
|
+
//do nothing for now
|
1044
|
+
free(temp);
|
1045
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_names") == 0){
|
1046
|
+
//do nothing for now
|
1047
|
+
free(temp);
|
1048
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_types") == 0){
|
1049
|
+
//do nothing for now
|
1050
|
+
free(temp);
|
1051
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__apple_namespa") == 0) ||
|
1052
|
+
(strcmp(dwarf_section_headers[i].sectname, "__apple_namespac__DWARF") == 0)
|
1053
|
+
){
|
1054
|
+
//do nothing for now
|
1055
|
+
free(temp);
|
1056
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_objc") == 0){
|
1057
|
+
//do nothing for now
|
1058
|
+
free(temp);
|
1059
|
+
}else{
|
1060
|
+
printf("╮(╯▽╰)╭ Unknown Section, %s \n", dwarf_section_headers[i].sectname);
|
1061
|
+
free(temp);
|
1062
|
+
}
|
1063
|
+
i++;
|
1064
|
+
}
|
1065
|
+
free(dwarf_section_headers);
|
1066
|
+
return dwarf2_per_objfile;
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
|
1070
|
+
static struct dwarf2_per_objfile* parse_dwarf_segment_64(char *macho_str, long offset,struct segment_command_64 *command){
|
1071
|
+
uint32_t numofdwarfsections = command->nsects;
|
1072
|
+
|
1073
|
+
struct dwarf2_per_objfile *dwarf2_per_objfile = malloc(sizeof(struct dwarf2_per_objfile));
|
1074
|
+
if (dwarf2_per_objfile == NULL){
|
1075
|
+
printf("Malloc Error!\n");
|
1076
|
+
PyErr_NoMemory();
|
1077
|
+
return NULL;
|
1078
|
+
}
|
1079
|
+
memset(dwarf2_per_objfile, '\0', sizeof(struct dwarf2_per_objfile));
|
1080
|
+
|
1081
|
+
struct section_64 * dwarf_section_headers = malloc(numofdwarfsections * sizeof(struct section_64));
|
1082
|
+
if (dwarf_section_headers == NULL){
|
1083
|
+
printf("Malloc Error!\n");
|
1084
|
+
PyErr_NoMemory();
|
1085
|
+
return NULL;
|
1086
|
+
}
|
1087
|
+
memset(dwarf_section_headers, '\0', numofdwarfsections * sizeof (struct section));
|
1088
|
+
memcpy(dwarf_section_headers, macho_str + offset, numofdwarfsections * sizeof(struct section_64));
|
1089
|
+
|
1090
|
+
uint32_t i = 0;
|
1091
|
+
while(i < numofdwarfsections){
|
1092
|
+
//FIXME more the size more 4G
|
1093
|
+
char *temp = malloc((uint32_t)dwarf_section_headers[i].size);
|
1094
|
+
if (temp == NULL){
|
1095
|
+
printf("Malloc Error!\n");
|
1096
|
+
PyErr_NoMemory();
|
1097
|
+
return NULL;
|
1098
|
+
}
|
1099
|
+
memset(temp, '\0', (uint32_t)dwarf_section_headers[i].size);
|
1100
|
+
memcpy(temp, macho_str + dwarf_section_headers[i].offset, (uint32_t)dwarf_section_headers[i].size);
|
1101
|
+
|
1102
|
+
if(strcmp(dwarf_section_headers[i].sectname, "__debug_abbrev") == 0){
|
1103
|
+
dwarf2_per_objfile->abbrev_buffer = temp;
|
1104
|
+
dwarf2_per_objfile->abbrev_size = (uint32_t)dwarf_section_headers[i].size;
|
1105
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_aranges") == 0){
|
1106
|
+
dwarf2_per_objfile->aranges_buffer = temp;
|
1107
|
+
dwarf2_per_objfile->aranges_size = (uint32_t)dwarf_section_headers[i].size;
|
1108
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_info") == 0){
|
1109
|
+
dwarf2_per_objfile->info_buffer = temp;
|
1110
|
+
dwarf2_per_objfile->info_size = (uint32_t)dwarf_section_headers[i].size;
|
1111
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_inlined") == 0){
|
1112
|
+
dwarf2_per_objfile->inlined_buffer = temp;
|
1113
|
+
dwarf2_per_objfile->inlined_size = (uint32_t)dwarf_section_headers[i].size;
|
1114
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_line") == 0){
|
1115
|
+
dwarf2_per_objfile->line_buffer = temp;
|
1116
|
+
dwarf2_per_objfile->line_size = (uint32_t)dwarf_section_headers[i].size;
|
1117
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_loc") == 0){
|
1118
|
+
dwarf2_per_objfile->loc_buffer = temp;
|
1119
|
+
dwarf2_per_objfile->loc_size = (uint32_t)dwarf_section_headers[i].size;
|
1120
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__debug_pubnames") == 0) ||
|
1121
|
+
(strcmp(dwarf_section_headers[i].sectname, "__debug_pubnames__DWARF") == 0)
|
1122
|
+
){
|
1123
|
+
dwarf2_per_objfile->pubnames_buffer = temp;
|
1124
|
+
dwarf2_per_objfile->pubnames_size = (uint32_t)dwarf_section_headers[i].size;
|
1125
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__debug_pubtypes") == 0) ||
|
1126
|
+
(strcmp(dwarf_section_headers[i].sectname, "__debug_pubtypes__DWARF") == 0)
|
1127
|
+
){
|
1128
|
+
dwarf2_per_objfile->pubtypes_buffer = temp;
|
1129
|
+
dwarf2_per_objfile->pubtypes_size = (uint32_t)dwarf_section_headers[i].size;
|
1130
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_ranges") == 0){
|
1131
|
+
dwarf2_per_objfile->ranges_buffer = temp;
|
1132
|
+
dwarf2_per_objfile->ranges_size = (uint32_t)dwarf_section_headers[i].size;
|
1133
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_str") == 0){
|
1134
|
+
dwarf2_per_objfile->str_buffer = temp;
|
1135
|
+
dwarf2_per_objfile->str_size = (uint32_t)dwarf_section_headers[i].size;
|
1136
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__debug_frame") == 0){
|
1137
|
+
//do nothing for now
|
1138
|
+
free(temp);
|
1139
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_names") == 0){
|
1140
|
+
//do nothing for now
|
1141
|
+
free(temp);
|
1142
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_types") == 0){
|
1143
|
+
//do nothing for now
|
1144
|
+
free(temp);
|
1145
|
+
}else if((strcmp(dwarf_section_headers[i].sectname, "__apple_namespa") == 0) ||
|
1146
|
+
(strcmp(dwarf_section_headers[i].sectname, "__apple_namespac__DWARF") == 0)
|
1147
|
+
){
|
1148
|
+
//do nothing for now
|
1149
|
+
free(temp);
|
1150
|
+
}else if(strcmp(dwarf_section_headers[i].sectname, "__apple_objc") == 0){
|
1151
|
+
//do nothing for now
|
1152
|
+
free(temp);
|
1153
|
+
}else{
|
1154
|
+
printf("╮(╯▽╰)╭ Unknown Section, %s \n", dwarf_section_headers[i].sectname);
|
1155
|
+
free(temp);
|
1156
|
+
}
|
1157
|
+
i++;
|
1158
|
+
}
|
1159
|
+
free(dwarf_section_headers);
|
1160
|
+
return dwarf2_per_objfile;
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
void print_all_dwarf2_per_objfile(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
1164
|
+
int i = 0;
|
1165
|
+
printf("abbrev_buffer:\n");
|
1166
|
+
for (i =0; i< dwarf2_per_objfile->abbrev_size; i++){
|
1167
|
+
printf("%02x", dwarf2_per_objfile->abbrev_buffer[i]);
|
1168
|
+
}
|
1169
|
+
printf("\n");
|
1170
|
+
printf("\n");
|
1171
|
+
printf("\n");
|
1172
|
+
printf("\n");
|
1173
|
+
printf("aranges_buffer:\n");
|
1174
|
+
|
1175
|
+
for (i =0; i< dwarf2_per_objfile->aranges_size; i++){
|
1176
|
+
printf("%02x", dwarf2_per_objfile->aranges_buffer[i]);
|
1177
|
+
|
1178
|
+
}
|
1179
|
+
printf("\n");
|
1180
|
+
printf("\n");
|
1181
|
+
printf("\n");
|
1182
|
+
printf("\n");
|
1183
|
+
|
1184
|
+
printf("info_buffer:\n");
|
1185
|
+
for (i =0; i< dwarf2_per_objfile->info_size; i++){
|
1186
|
+
printf("%02x", dwarf2_per_objfile->info_buffer[i]);
|
1187
|
+
|
1188
|
+
}
|
1189
|
+
printf("\n");
|
1190
|
+
printf("\n");
|
1191
|
+
printf("\n");
|
1192
|
+
printf("\n");
|
1193
|
+
|
1194
|
+
printf("inlined_buffer:\n");
|
1195
|
+
for (i =0; i< dwarf2_per_objfile->inlined_size; i++){
|
1196
|
+
printf("%02x", dwarf2_per_objfile->inlined_buffer[i]);
|
1197
|
+
|
1198
|
+
}
|
1199
|
+
printf("\n");
|
1200
|
+
printf("\n");
|
1201
|
+
printf("\n");
|
1202
|
+
printf("\n");
|
1203
|
+
|
1204
|
+
printf("line_buffer:\n");
|
1205
|
+
for (i =0; i< dwarf2_per_objfile->line_size; i++){
|
1206
|
+
printf("%02x", dwarf2_per_objfile->line_buffer[i]);
|
1207
|
+
|
1208
|
+
}
|
1209
|
+
printf("\n");
|
1210
|
+
printf("\n");
|
1211
|
+
printf("\n");
|
1212
|
+
printf("\n");
|
1213
|
+
printf("loc_buffer:\n");
|
1214
|
+
|
1215
|
+
for (i =0; i< dwarf2_per_objfile->loc_size; i++){
|
1216
|
+
printf("%02x", dwarf2_per_objfile->loc_buffer[i]);
|
1217
|
+
|
1218
|
+
}
|
1219
|
+
printf("\n");
|
1220
|
+
printf("\n");
|
1221
|
+
printf("\n");
|
1222
|
+
printf("\n");
|
1223
|
+
|
1224
|
+
printf("pubnames_buffer:\n");
|
1225
|
+
for (i =0; i< dwarf2_per_objfile->pubnames_size; i++){
|
1226
|
+
printf("%02x", dwarf2_per_objfile->pubnames_buffer[i]);
|
1227
|
+
|
1228
|
+
}
|
1229
|
+
printf("\n");
|
1230
|
+
printf("\n");
|
1231
|
+
printf("\n");
|
1232
|
+
printf("\n");
|
1233
|
+
printf("pubtypes_buffer:\n");
|
1234
|
+
|
1235
|
+
for (i =0; i< dwarf2_per_objfile->pubtypes_size; i++){
|
1236
|
+
printf("%02x", dwarf2_per_objfile->pubtypes_buffer[i]);
|
1237
|
+
|
1238
|
+
}
|
1239
|
+
printf("\n");
|
1240
|
+
printf("\n");
|
1241
|
+
printf("\n");
|
1242
|
+
printf("\n");
|
1243
|
+
|
1244
|
+
printf("ranges_buffer:\n");
|
1245
|
+
for (i =0; i< dwarf2_per_objfile->ranges_size; i++){
|
1246
|
+
printf("%02x", dwarf2_per_objfile->ranges_buffer[i]);
|
1247
|
+
|
1248
|
+
}
|
1249
|
+
printf("\n");
|
1250
|
+
printf("\n");
|
1251
|
+
printf("\n");
|
1252
|
+
printf("\n");
|
1253
|
+
printf("str_size:\n");
|
1254
|
+
|
1255
|
+
for (i =0; i< dwarf2_per_objfile->str_size; i++){
|
1256
|
+
printf("%02x", dwarf2_per_objfile->str_buffer[i]);
|
1257
|
+
|
1258
|
+
}
|
1259
|
+
printf("\n");
|
1260
|
+
printf("\n");
|
1261
|
+
printf("\n");
|
1262
|
+
printf("\n");
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
|
1266
|
+
int parse_normal(FILE *fp, uint32_t magic_number, struct target_file *tf){
|
1267
|
+
tf->numofarchs = 1;
|
1268
|
+
tf->thin_machos = malloc(1 *sizeof(struct thin_macho*));
|
1269
|
+
if (tf->thin_machos == NULL){
|
1270
|
+
PyErr_NoMemory();
|
1271
|
+
return -1;
|
1272
|
+
}
|
1273
|
+
memset(tf->thin_machos, '\0', 1 * sizeof(struct thin_macho*));
|
1274
|
+
|
1275
|
+
fseek(fp, 0L, SEEK_END);
|
1276
|
+
long int size = ftell(fp);
|
1277
|
+
|
1278
|
+
fseek(fp, 0L, SEEK_SET);
|
1279
|
+
|
1280
|
+
int numofbytes = 0;
|
1281
|
+
tf->thin_machos[0] = malloc(sizeof(struct thin_macho));
|
1282
|
+
if(tf->thin_machos[0] == NULL){
|
1283
|
+
PyErr_NoMemory();
|
1284
|
+
return -1;
|
1285
|
+
}
|
1286
|
+
tf->thin_machos[0]->data = malloc(size);
|
1287
|
+
if(tf->thin_machos[0]->data == NULL){
|
1288
|
+
PyErr_NoMemory();
|
1289
|
+
return -1;
|
1290
|
+
}
|
1291
|
+
memset(tf->thin_machos[0]->data, '\0', size);
|
1292
|
+
|
1293
|
+
numofbytes = fread(tf->thin_machos[0]->data, sizeof(char), size, fp);
|
1294
|
+
assert(numofbytes == size);
|
1295
|
+
if(numofbytes == size){
|
1296
|
+
parse_macho(tf->thin_machos[0]);
|
1297
|
+
return 0;
|
1298
|
+
}else{
|
1299
|
+
return -1;
|
1300
|
+
}
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
void free_buffers(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
1304
|
+
free(dwarf2_per_objfile->info_buffer);
|
1305
|
+
free(dwarf2_per_objfile->abbrev_buffer);
|
1306
|
+
free(dwarf2_per_objfile->line_buffer);
|
1307
|
+
free(dwarf2_per_objfile->pubnames_buffer);
|
1308
|
+
free(dwarf2_per_objfile->aranges_buffer);
|
1309
|
+
free(dwarf2_per_objfile->loc_buffer);
|
1310
|
+
free(dwarf2_per_objfile->macinfo_buffer);
|
1311
|
+
free(dwarf2_per_objfile->str_buffer);
|
1312
|
+
free(dwarf2_per_objfile->ranges_buffer);
|
1313
|
+
free(dwarf2_per_objfile->inlined_buffer);
|
1314
|
+
free(dwarf2_per_objfile->pubtypes_buffer);
|
1315
|
+
free(dwarf2_per_objfile->frame_buffer);
|
1316
|
+
free(dwarf2_per_objfile->eh_frame_buffer);
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
void free_dwarf_abbrev_hash(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
1320
|
+
if(dwarf2_per_objfile->dwarf2_abbrevs == NULL){
|
1321
|
+
return;
|
1322
|
+
}
|
1323
|
+
int i = 0;
|
1324
|
+
while(i < ABBREV_HASH_SIZE){
|
1325
|
+
struct abbrev_info *dwarf2_abbrevs= dwarf2_per_objfile->dwarf2_abbrevs[i];
|
1326
|
+
struct abbrev_info *current = dwarf2_abbrevs;
|
1327
|
+
while(current != NULL){
|
1328
|
+
current = current->next;
|
1329
|
+
free(current);
|
1330
|
+
}
|
1331
|
+
i++;
|
1332
|
+
}
|
1333
|
+
free(dwarf2_per_objfile->dwarf2_abbrevs);
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
void free_dwarf_aranges(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
1337
|
+
struct arange **all_aranges = dwarf2_per_objfile->all_aranges;
|
1338
|
+
int i = 0;
|
1339
|
+
while(i < dwarf2_per_objfile->n_aranges){
|
1340
|
+
free(all_aranges[i]->address_range_descriptors);
|
1341
|
+
free(all_aranges[i]);
|
1342
|
+
i++;
|
1343
|
+
}
|
1344
|
+
}
|
1345
|
+
|
1346
|
+
/* Free a linked list of dies. */
|
1347
|
+
static void free_die_list (struct die_info *dies)
|
1348
|
+
{
|
1349
|
+
struct die_info *die, *next;
|
1350
|
+
int i = 0;
|
1351
|
+
die = dies;
|
1352
|
+
while (die)
|
1353
|
+
{
|
1354
|
+
if (die->child != NULL)
|
1355
|
+
free_die_list (die->child);
|
1356
|
+
next = die->sibling;
|
1357
|
+
|
1358
|
+
while(i < die->num_attrs){
|
1359
|
+
if ((die->attrs[i].form == DW_FORM_block2)
|
1360
|
+
|| (die->attrs[i].form == DW_FORM_block4)
|
1361
|
+
|| (die->attrs[i].form == DW_FORM_block)
|
1362
|
+
|| (die->attrs[i].form == DW_FORM_block1)){
|
1363
|
+
free((die->attrs[i]).u.blk);
|
1364
|
+
}
|
1365
|
+
i++;
|
1366
|
+
}
|
1367
|
+
free (die->attrs);
|
1368
|
+
free (die);
|
1369
|
+
die = next;
|
1370
|
+
}
|
1371
|
+
}
|
1372
|
+
|
1373
|
+
static void free_compilation_units(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
1374
|
+
struct dwarf2_per_cu_data **all_comp_units = dwarf2_per_objfile->all_comp_units;
|
1375
|
+
int i = 0;
|
1376
|
+
while(i < dwarf2_per_objfile->n_comp_units){
|
1377
|
+
struct dwarf2_cu* cu= all_comp_units[i]->cu;
|
1378
|
+
if (cu->dies){
|
1379
|
+
free_die_list (cu->dies);
|
1380
|
+
}
|
1381
|
+
free(cu);
|
1382
|
+
i++;
|
1383
|
+
}
|
1384
|
+
free(dwarf2_per_objfile->all_comp_units);
|
1385
|
+
}
|
1386
|
+
|
1387
|
+
void free_target_file(struct target_file *tf){
|
1388
|
+
uint32_t i = 0;
|
1389
|
+
while(i < tf->numofarchs){
|
1390
|
+
free(tf->thin_machos[i]->data);
|
1391
|
+
if(tf->thin_machos[i]->dwarf2_per_objfile){
|
1392
|
+
struct dwarf2_per_objfile *dwarf2_per_objfile = tf->thin_machos[i]->dwarf2_per_objfile;
|
1393
|
+
if (dwarf2_per_objfile != NULL){
|
1394
|
+
free_buffers(dwarf2_per_objfile);
|
1395
|
+
//free all compilation units
|
1396
|
+
free_compilation_units(dwarf2_per_objfile);
|
1397
|
+
//free aranges
|
1398
|
+
free_dwarf_aranges(dwarf2_per_objfile);
|
1399
|
+
//free dwarf abbrev hash
|
1400
|
+
free_dwarf_abbrev_hash(dwarf2_per_objfile);
|
1401
|
+
//free dwarf file
|
1402
|
+
free(dwarf2_per_objfile);
|
1403
|
+
}
|
1404
|
+
}
|
1405
|
+
free(tf->thin_machos[i]->all_symbols);
|
1406
|
+
free(tf->thin_machos[i]);
|
1407
|
+
i++;
|
1408
|
+
}
|
1409
|
+
free(tf->thin_machos);
|
1410
|
+
free(tf);
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
int select_thin_macho_by_arch(struct target_file *tf, const char *target_arch){
|
1414
|
+
int i = 0;
|
1415
|
+
char *arch = NULL;
|
1416
|
+
while(i < tf->numofarchs){
|
1417
|
+
struct thin_macho *thin_macho = tf->thin_machos[i];
|
1418
|
+
switch(thin_macho->cputype){
|
1419
|
+
case CPU_TYPE_ARM:
|
1420
|
+
{
|
1421
|
+
switch (thin_macho->cpusubtype){
|
1422
|
+
case CPU_SUBTYPE_ARM_V4T:
|
1423
|
+
//armv4t
|
1424
|
+
arch = "armv4t";
|
1425
|
+
break;
|
1426
|
+
case CPU_SUBTYPE_ARM_V5TEJ:
|
1427
|
+
//armv5
|
1428
|
+
arch = "armv5";
|
1429
|
+
break;
|
1430
|
+
case CPU_SUBTYPE_ARM_V6:
|
1431
|
+
//armv6
|
1432
|
+
arch = "armv6";
|
1433
|
+
break;
|
1434
|
+
case CPU_SUBTYPE_ARM_V7:
|
1435
|
+
//armv7
|
1436
|
+
arch = "armv7";
|
1437
|
+
break;
|
1438
|
+
case CPU_SUBTYPE_ARM_V7S:
|
1439
|
+
//armv7s
|
1440
|
+
arch = "armv7s";
|
1441
|
+
break;
|
1442
|
+
case CPU_SUBTYPE_ARM_V8:
|
1443
|
+
//armv8
|
1444
|
+
arch = "armv8";
|
1445
|
+
break;
|
1446
|
+
}
|
1447
|
+
break;
|
1448
|
+
}
|
1449
|
+
case CPU_TYPE_I386:
|
1450
|
+
//i386
|
1451
|
+
arch = "i386";
|
1452
|
+
break;
|
1453
|
+
case CPU_TYPE_X86_64:
|
1454
|
+
//x86_64
|
1455
|
+
arch = "x86_64";
|
1456
|
+
break;
|
1457
|
+
case CPU_TYPE_POWERPC:
|
1458
|
+
//ppc
|
1459
|
+
arch = "ppc";
|
1460
|
+
break;
|
1461
|
+
case CPU_TYPE_POWERPC64:
|
1462
|
+
//ppc64
|
1463
|
+
arch = "ppc64";
|
1464
|
+
break;
|
1465
|
+
}
|
1466
|
+
if (arch != NULL && strcmp(arch, target_arch) == 0){
|
1467
|
+
return i;
|
1468
|
+
}
|
1469
|
+
i++;
|
1470
|
+
}
|
1471
|
+
if (arch == NULL){
|
1472
|
+
printf("unknow arch: %s\n", target_arch);
|
1473
|
+
}
|
1474
|
+
return -1;
|
1475
|
+
}
|
1476
|
+
|
1477
|
+
struct target_file *parse_file(const char *filename){
|
1478
|
+
FILE *fp = fopen(filename, "rb");
|
1479
|
+
if (fp == NULL){
|
1480
|
+
fprintf(stderr, "Can not open file %s for read.\n", filename);
|
1481
|
+
PyErr_Format(ATOSError, "Can not open file %s for read\n", filename);
|
1482
|
+
return NULL;
|
1483
|
+
}
|
1484
|
+
|
1485
|
+
//tell file type by their magic number
|
1486
|
+
//Values for integer types in all Mach-O data structures are written
|
1487
|
+
//using the host CPU’s byte ordering scheme, except for fat_header and
|
1488
|
+
//fat_arch, which are written in big-endian byte order.
|
1489
|
+
|
1490
|
+
struct target_file *tf = malloc(sizeof(struct target_file));
|
1491
|
+
if (tf == NULL){
|
1492
|
+
PyErr_NoMemory();
|
1493
|
+
return NULL;
|
1494
|
+
}
|
1495
|
+
memset(tf, '\0', sizeof(struct target_file));
|
1496
|
+
|
1497
|
+
int rc = 0;
|
1498
|
+
int seekreturn = 0;
|
1499
|
+
uint32_t magic_number = 0;
|
1500
|
+
int parse_result = -1;
|
1501
|
+
if( (rc = fread(&magic_number, sizeof(uint32_t), 1, fp)) != 0 )
|
1502
|
+
{
|
1503
|
+
seekreturn = fseek (fp, 0 - sizeof(uint32_t), SEEK_CUR);
|
1504
|
+
assert(seekreturn == 0);
|
1505
|
+
if (seekreturn != 0){
|
1506
|
+
debug("seekreturn != 0");
|
1507
|
+
PyErr_Format(ATOSError, "seek error");
|
1508
|
+
fclose(fp);
|
1509
|
+
return NULL;
|
1510
|
+
}
|
1511
|
+
debug("magic_number: %x\n", magic_number);
|
1512
|
+
switch(magic_number){
|
1513
|
+
case MH_MAGIC:
|
1514
|
+
//current machine endian is same with host machine
|
1515
|
+
parse_result = parse_normal(fp, MH_MAGIC, tf);
|
1516
|
+
break;
|
1517
|
+
case MH_MAGIC_64:
|
1518
|
+
//current machine endian is same with host machine
|
1519
|
+
parse_result = parse_normal(fp, MH_MAGIC_64, tf);
|
1520
|
+
break;
|
1521
|
+
case MH_CIGAM:
|
1522
|
+
printf("MH_CIGAM: %x\n", MH_CIGAM);
|
1523
|
+
PyErr_Format(ATOSError, "MH_CIGAM: %x\n", MH_CIGAM);
|
1524
|
+
break;
|
1525
|
+
case MH_CIGAM_64:
|
1526
|
+
//current machine endian is not same with host machine
|
1527
|
+
printf("MH_CIGAM_64: %x\n", MH_CIGAM_64);
|
1528
|
+
PyErr_Format(ATOSError, "MH_CIGAM_64: %x\n", MH_CIGAM_64);
|
1529
|
+
break;
|
1530
|
+
case FAT_MAGIC:
|
1531
|
+
//current machine is big endian
|
1532
|
+
parse_result = parse_universal(fp, FAT_MAGIC, tf);
|
1533
|
+
break;
|
1534
|
+
case FAT_CIGAM:
|
1535
|
+
//current machie is small endian
|
1536
|
+
parse_result = parse_universal(fp, FAT_CIGAM, tf);
|
1537
|
+
break;
|
1538
|
+
default:
|
1539
|
+
fprintf(stderr, "magic_number invalid.");
|
1540
|
+
PyErr_Format(ATOSError, "magic_number invalid");
|
1541
|
+
}
|
1542
|
+
}
|
1543
|
+
fclose(fp);
|
1544
|
+
if(parse_result == -1){
|
1545
|
+
return NULL;
|
1546
|
+
}
|
1547
|
+
return tf;
|
1548
|
+
}
|
1549
|
+
|
1550
|
+
//static void int32_endian_convert(int32_t *num)
|
1551
|
+
//{
|
1552
|
+
// int32_t original_num = *num;
|
1553
|
+
// *num = 0;
|
1554
|
+
// int i;
|
1555
|
+
// for (i = 0; i < 4; i++)
|
1556
|
+
// {
|
1557
|
+
// *num <<= 8;
|
1558
|
+
// *num |= (original_num & 0xFF);
|
1559
|
+
// original_num >>= 8;
|
1560
|
+
// }
|
1561
|
+
//}
|
1562
|
+
|
1563
|
+
static void uint32_endian_convert(uint32_t *num)
|
1564
|
+
{
|
1565
|
+
uint32_t original_num = *num;
|
1566
|
+
*num = 0;
|
1567
|
+
int i;
|
1568
|
+
for (i = 0; i < 4; i++)
|
1569
|
+
{
|
1570
|
+
*num <<= 8;
|
1571
|
+
*num |= (original_num & 0xFF);
|
1572
|
+
original_num >>= 8;
|
1573
|
+
}
|
1574
|
+
}
|
1575
|
+
|
1576
|
+
static void integer_t_endian_convert(integer_t *num)
|
1577
|
+
{
|
1578
|
+
integer_t original_num = *num;
|
1579
|
+
*num = 0;
|
1580
|
+
int i;
|
1581
|
+
for (i = 0; i < 4; i++)
|
1582
|
+
{
|
1583
|
+
*num <<= 8;
|
1584
|
+
*num |= (original_num & 0xFF);
|
1585
|
+
original_num >>= 8;
|
1586
|
+
}
|
1587
|
+
}
|
1588
|
+
|
1589
|
+
int parse_fat_arch(FILE *fp, struct fat_arch *fa, struct thin_macho**thin_macho, uint32_t magic_number){
|
1590
|
+
if (magic_number == FAT_CIGAM){
|
1591
|
+
integer_t_endian_convert(&fa->cputype);
|
1592
|
+
integer_t_endian_convert(&fa->cpusubtype);
|
1593
|
+
uint32_endian_convert(&fa->offset);
|
1594
|
+
uint32_endian_convert(&fa->size);
|
1595
|
+
uint32_endian_convert(&fa->align);
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
//printf("offset: 0x%x\n", fa->offset);
|
1599
|
+
//printf("size: 0x%x\n", fa->size);
|
1600
|
+
//printf("align: 0x%x\n", fa->align);
|
1601
|
+
|
1602
|
+
(*thin_macho)->data = malloc(fa->size);
|
1603
|
+
memset((*thin_macho)->data, '\0', fa->size);
|
1604
|
+
|
1605
|
+
//record current pos
|
1606
|
+
long cur_position = ftell(fp);
|
1607
|
+
int seekreturn = 0;
|
1608
|
+
seekreturn = fseek(fp, fa->offset, SEEK_SET);
|
1609
|
+
assert(seekreturn == 0);
|
1610
|
+
if(seekreturn != 0){
|
1611
|
+
PyErr_Format(ATOSError, "seek error");
|
1612
|
+
fprintf(stderr, "seek error.\n");
|
1613
|
+
return -1;
|
1614
|
+
}
|
1615
|
+
|
1616
|
+
int numofbytes = 0;
|
1617
|
+
numofbytes = fread((*thin_macho)->data, sizeof(char), fa->size, fp);
|
1618
|
+
assert(numofbytes == fa->size);
|
1619
|
+
if(numofbytes != fa->size){
|
1620
|
+
PyErr_Format(ATOSError, "read macho data error");
|
1621
|
+
fprintf(stderr, "read macho data error.\n");
|
1622
|
+
return -1;
|
1623
|
+
}
|
1624
|
+
seekreturn = fseek(fp, cur_position, SEEK_SET);
|
1625
|
+
assert(seekreturn == 0);
|
1626
|
+
if(seekreturn != 0){
|
1627
|
+
PyErr_Format(ATOSError, "seek error.");
|
1628
|
+
fprintf(stderr, "seek error.\n");
|
1629
|
+
return -1;
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
return 0;
|
1633
|
+
}
|
1634
|
+
|
1635
|
+
int parse_universal(FILE *fp, uint32_t magic_number, struct target_file *tf){
|
1636
|
+
int rc = 0;
|
1637
|
+
struct fat_header fh = {0};
|
1638
|
+
|
1639
|
+
uint32_t nfat_arch = 0;
|
1640
|
+
if( (rc = fread(&fh ,sizeof(struct fat_header), 1, fp)) != 0 )
|
1641
|
+
{
|
1642
|
+
if (magic_number == FAT_CIGAM){
|
1643
|
+
uint32_endian_convert(&fh.nfat_arch);
|
1644
|
+
}
|
1645
|
+
nfat_arch = fh.nfat_arch;
|
1646
|
+
//printf("nfat_arch: %u\n", nfat_arch);
|
1647
|
+
}
|
1648
|
+
//free maloc failed?
|
1649
|
+
tf->numofarchs = nfat_arch;
|
1650
|
+
tf->thin_machos = malloc(nfat_arch *sizeof(struct thin_macho*));
|
1651
|
+
if (tf->thin_machos == NULL){
|
1652
|
+
PyErr_NoMemory();
|
1653
|
+
return -1;
|
1654
|
+
}
|
1655
|
+
memset(tf->thin_machos, '\0', nfat_arch * sizeof(struct thin_macho*));
|
1656
|
+
|
1657
|
+
uint32_t i = 0;
|
1658
|
+
struct fat_arch fa = {0};
|
1659
|
+
while (i < nfat_arch){
|
1660
|
+
tf->thin_machos[i] = malloc(sizeof(struct thin_macho));
|
1661
|
+
if (tf->thin_machos[i] == NULL){
|
1662
|
+
PyErr_NoMemory();
|
1663
|
+
return -1;
|
1664
|
+
}
|
1665
|
+
memset(tf->thin_machos[i], '\0', sizeof(struct thin_macho));
|
1666
|
+
if( (rc = fread(&fa ,sizeof(struct fat_arch), 1, fp)) == 1 )
|
1667
|
+
{
|
1668
|
+
int parse_fat_arch_result = parse_fat_arch(fp, &fa, &tf->thin_machos[i], magic_number);
|
1669
|
+
if(parse_fat_arch_result == -1){
|
1670
|
+
return -1;
|
1671
|
+
}
|
1672
|
+
}else{
|
1673
|
+
PyErr_Format(ATOSError, "fread fat arch error");
|
1674
|
+
fprintf(stderr, "read fat arch error\n");
|
1675
|
+
return -1;
|
1676
|
+
}
|
1677
|
+
//FIXME
|
1678
|
+
int parse_macho_result = parse_macho(tf->thin_machos[i]);
|
1679
|
+
if (parse_macho_result == -1){
|
1680
|
+
return -1;
|
1681
|
+
}
|
1682
|
+
i++;
|
1683
|
+
}
|
1684
|
+
return 0;
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
int parse_macho(struct thin_macho*tm){
|
1688
|
+
char *macho_str = tm->data;
|
1689
|
+
|
1690
|
+
int num_load_cmds = 0;
|
1691
|
+
long offset = 0;
|
1692
|
+
size_t header_size = 0;
|
1693
|
+
|
1694
|
+
uint32_t magic_number = 0;
|
1695
|
+
memcpy(&magic_number, macho_str, sizeof(uint32_t));
|
1696
|
+
//printf("magic_number: %x\n", magic_number);
|
1697
|
+
switch(magic_number){
|
1698
|
+
case MH_MAGIC:
|
1699
|
+
{
|
1700
|
+
//current machine endian is same with host machine
|
1701
|
+
//printf("MH_MAGIC: %x\n", MH_MAGIC);
|
1702
|
+
//parse_normal(fp, MH_MAGIC, tf);
|
1703
|
+
struct mach_header mh = {0};
|
1704
|
+
header_size = sizeof(struct mach_header);
|
1705
|
+
memcpy(&mh, macho_str + offset, header_size);
|
1706
|
+
num_load_cmds = mh.ncmds;
|
1707
|
+
tm->cputype = mh.cputype;
|
1708
|
+
tm->cpusubtype = mh.cpusubtype;
|
1709
|
+
break;
|
1710
|
+
}
|
1711
|
+
case MH_MAGIC_64:
|
1712
|
+
{
|
1713
|
+
//current machine endian is same with host machine
|
1714
|
+
//printf("MH_MAGIC_64: %x\n", MH_MAGIC_64);
|
1715
|
+
//parse_normal(fp, MH_MAGIC_64, tf);
|
1716
|
+
struct mach_header_64 mh64 = {0};
|
1717
|
+
header_size = sizeof(struct mach_header_64);
|
1718
|
+
memcpy(&mh64, macho_str + offset, header_size);
|
1719
|
+
num_load_cmds = mh64.ncmds;
|
1720
|
+
tm->cputype = mh64.cputype;
|
1721
|
+
tm->cpusubtype = mh64.cpusubtype;
|
1722
|
+
break;
|
1723
|
+
}
|
1724
|
+
case MH_CIGAM:
|
1725
|
+
//current machine endian is not same with host machine
|
1726
|
+
//printf("MH_CIGAM: %x\n", MH_CIGAM);
|
1727
|
+
printf("TODO: MH_CIGAM\n");
|
1728
|
+
PyErr_Format(ATOSError, "TODO: MH_CIGAM");
|
1729
|
+
break;
|
1730
|
+
case MH_CIGAM_64:
|
1731
|
+
printf("TODO: MH_CIGAM_64\n");
|
1732
|
+
PyErr_Format(ATOSError, "TODO: MH_CIGAM_64");
|
1733
|
+
//current machine endian is not same with host machine
|
1734
|
+
//printf("MH_CIGAM_64: %x\n", MH_CIGAM_64);
|
1735
|
+
break;
|
1736
|
+
case FAT_MAGIC:
|
1737
|
+
case FAT_CIGAM:
|
1738
|
+
fprintf(stderr, "fat in fat?\n");
|
1739
|
+
PyErr_Format(ATOSError, "fat in fat?");
|
1740
|
+
return -1;
|
1741
|
+
break;
|
1742
|
+
default:
|
1743
|
+
fprintf(stderr, "magic_number invalid");
|
1744
|
+
PyErr_Format(ATOSError, "magic_number invalid");
|
1745
|
+
return -1;
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
offset += header_size;
|
1749
|
+
|
1750
|
+
struct load_command lc = {0};
|
1751
|
+
int i = 0;
|
1752
|
+
while (i < num_load_cmds){
|
1753
|
+
memcpy(&lc, macho_str + offset, sizeof(struct load_command));
|
1754
|
+
//because we will try to read the actual load_command depend on
|
1755
|
+
//load_command type, so we do not need to add the offset.
|
1756
|
+
//offset += sizeof(struct load_command);
|
1757
|
+
//printf("%d\n",i);
|
1758
|
+
int parse_load_command_result = parse_load_command(macho_str, &offset, &lc, tm);
|
1759
|
+
if (parse_load_command_result == -1){
|
1760
|
+
return -1;
|
1761
|
+
}
|
1762
|
+
i++;
|
1763
|
+
}
|
1764
|
+
// printf("finished\n");
|
1765
|
+
return 0;
|
1766
|
+
}
|
1767
|
+
|
1768
|
+
/* Return a pointer to just past the end of an LEB128 number in BUF. */
|
1769
|
+
|
1770
|
+
static unsigned int get_num_attr_spec_pair(char* info_ptr){
|
1771
|
+
unsigned int bytes_read = 0;
|
1772
|
+
unsigned int num_attr_spec_pair = 0;
|
1773
|
+
unsigned int attr_name_code = (unsigned int)read_unsigned_leb128(info_ptr, &bytes_read);
|
1774
|
+
info_ptr += bytes_read;
|
1775
|
+
unsigned int attr_form_code = (unsigned int)read_unsigned_leb128(info_ptr, &bytes_read);
|
1776
|
+
info_ptr += bytes_read;
|
1777
|
+
while(attr_name_code != 0 || attr_form_code != 0){
|
1778
|
+
attr_name_code = (unsigned int)read_unsigned_leb128(info_ptr ,&bytes_read);
|
1779
|
+
info_ptr += bytes_read;
|
1780
|
+
attr_form_code = (unsigned int)read_unsigned_leb128(info_ptr ,&bytes_read);
|
1781
|
+
info_ptr += bytes_read;
|
1782
|
+
num_attr_spec_pair ++;
|
1783
|
+
}
|
1784
|
+
return num_attr_spec_pair;
|
1785
|
+
}
|
1786
|
+
|
1787
|
+
/* Lookup an abbrev_info structure in the abbrev hash table. */
|
1788
|
+
|
1789
|
+
static struct abbrev_info * dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu)
|
1790
|
+
{
|
1791
|
+
unsigned int hash_number;
|
1792
|
+
struct abbrev_info *abbrev;
|
1793
|
+
|
1794
|
+
hash_number = number % ABBREV_HASH_SIZE;
|
1795
|
+
abbrev = cu->dwarf2_abbrevs[hash_number];
|
1796
|
+
|
1797
|
+
while (abbrev)
|
1798
|
+
{
|
1799
|
+
if (abbrev->number == number)
|
1800
|
+
return abbrev;
|
1801
|
+
else
|
1802
|
+
abbrev = abbrev->next;
|
1803
|
+
}
|
1804
|
+
return NULL;
|
1805
|
+
}
|
1806
|
+
|
1807
|
+
static char * read_comp_unit_head (struct comp_unit_head *header, char *info_ptr)
|
1808
|
+
{
|
1809
|
+
header->addr_size = 4;
|
1810
|
+
header->offset_size = 4;
|
1811
|
+
unsigned int cu_head_length = read_unsigned_int(info_ptr);
|
1812
|
+
//printf("length: \t0X%08X\n", cu_head_length);
|
1813
|
+
info_ptr += 4;
|
1814
|
+
header->length = cu_head_length;
|
1815
|
+
|
1816
|
+
unsigned short cu_version = read_unsigned_short(info_ptr);
|
1817
|
+
info_ptr += 2;
|
1818
|
+
//printf("version: \t0X%04X\n", cu_version);
|
1819
|
+
header->version = cu_version;
|
1820
|
+
|
1821
|
+
unsigned int cu_abbrev_offset= read_unsigned_int(info_ptr);
|
1822
|
+
info_ptr += 4;
|
1823
|
+
//printf("abbr_offset: \t0X%08X\n", cu_abbrev_offset);
|
1824
|
+
header->abbrev_offset = cu_abbrev_offset;
|
1825
|
+
|
1826
|
+
unsigned char cu_addr_size = read_unsigned_char(info_ptr);
|
1827
|
+
info_ptr += 1;
|
1828
|
+
//printf("abbr_size: \t0X%02X\n", cu_addr_size);
|
1829
|
+
header->addr_size = cu_addr_size;
|
1830
|
+
return info_ptr;
|
1831
|
+
}
|
1832
|
+
|
1833
|
+
/* Read the initial uleb128 in the die at current position in compilation unit CU.
|
1834
|
+
Return the corresponding abbrev, or NULL if the number is zero (indicating
|
1835
|
+
an empty DIE). In either case *BYTES_READ will be set to the length of
|
1836
|
+
the initial number. */
|
1837
|
+
|
1838
|
+
//static struct abbrev_info * peek_die_abbrev (char *info_ptr, unsigned int *bytes_read, struct dwarf2_cu *cu)
|
1839
|
+
//{
|
1840
|
+
// unsigned int abbrev_number;
|
1841
|
+
// struct abbrev_info *abbrev;
|
1842
|
+
//
|
1843
|
+
// abbrev_number = (unsigned int)read_unsigned_leb128(info_ptr, bytes_read);
|
1844
|
+
// printf("%u\n", abbrev_number);
|
1845
|
+
//
|
1846
|
+
// if (abbrev_number == 0)
|
1847
|
+
// return NULL;
|
1848
|
+
//
|
1849
|
+
// abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
|
1850
|
+
// if (!abbrev)
|
1851
|
+
// {
|
1852
|
+
// printf("Dwarf Error: Could not find abbrev number %d\n", abbrev_number);
|
1853
|
+
// }
|
1854
|
+
//
|
1855
|
+
// return abbrev;
|
1856
|
+
//}
|
1857
|
+
|
1858
|
+
static char * read_n_bytes (char *buf, unsigned int size)
|
1859
|
+
{
|
1860
|
+
/* If the size of a host char is 8 bits, we can return a pointer
|
1861
|
+
to the buffer, otherwise we have to copy the data to a buffer
|
1862
|
+
allocated on the temporary obstack. */
|
1863
|
+
//gdb_assert (HOST_CHAR_BIT == 8);
|
1864
|
+
return buf;
|
1865
|
+
}
|
1866
|
+
|
1867
|
+
static CORE_ADDR read_address_of_arange (char *buf, struct arange *arange, int *bytes_read){
|
1868
|
+
CORE_ADDR retval = 0;
|
1869
|
+
switch (arange->aranges_header.addr_size){
|
1870
|
+
case 2:
|
1871
|
+
//unsigned
|
1872
|
+
retval = read_signed_16(buf);
|
1873
|
+
break;
|
1874
|
+
case 4:
|
1875
|
+
retval = read_signed_32(buf);
|
1876
|
+
break;
|
1877
|
+
case 8:
|
1878
|
+
retval = read_signed_64(buf);
|
1879
|
+
break;
|
1880
|
+
default:
|
1881
|
+
fprintf(stderr, "read address: bad switch, signed\n");
|
1882
|
+
}
|
1883
|
+
*bytes_read = arange->aranges_header.addr_size;
|
1884
|
+
return retval;
|
1885
|
+
}
|
1886
|
+
|
1887
|
+
/* memory allocation interface */
|
1888
|
+
|
1889
|
+
static struct dwarf_block * dwarf_alloc_block (struct dwarf2_cu *cu)
|
1890
|
+
{
|
1891
|
+
struct dwarf_block *blk;
|
1892
|
+
//FIX ME FREEME
|
1893
|
+
blk = (struct dwarf_block *) malloc(sizeof (struct dwarf_block));
|
1894
|
+
memset(blk, '\0', sizeof(struct dwarf_block));
|
1895
|
+
return (blk);
|
1896
|
+
}
|
1897
|
+
|
1898
|
+
|
1899
|
+
|
1900
|
+
static char * read_indirect_string (char *buf, const struct comp_unit_head *cu_header, unsigned int *bytes_read_ptr, char *debug_str_buffer)
|
1901
|
+
{
|
1902
|
+
long str_offset = read_offset (buf, cu_header, (int *) bytes_read_ptr);
|
1903
|
+
|
1904
|
+
//if (dwarf2_per_objfile->str_buffer == NULL)
|
1905
|
+
//{
|
1906
|
+
// error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
|
1907
|
+
// bfd_get_filename (abfd));
|
1908
|
+
// return NULL;
|
1909
|
+
//}
|
1910
|
+
//if (str_offset >= dwarf2_per_objfile->str_size)
|
1911
|
+
//{
|
1912
|
+
// error (_("DW_FORM_strp pointing outside of .debug_str section [in module %s]"),
|
1913
|
+
// bfd_get_filename (abfd));
|
1914
|
+
// return NULL;
|
1915
|
+
//}
|
1916
|
+
//gdb_assert (HOST_CHAR_BIT == 8);
|
1917
|
+
//if (dwarf2_per_objfile->str_buffer[str_offset] == '\0')
|
1918
|
+
// return NULL;
|
1919
|
+
return debug_str_buffer + str_offset;
|
1920
|
+
}
|
1921
|
+
|
1922
|
+
/* Read an attribute value described by an attribute form. */
|
1923
|
+
|
1924
|
+
static char * read_attribute_value (struct attribute *attr, unsigned int form, char *info_ptr, struct dwarf2_cu *cu)
|
1925
|
+
{
|
1926
|
+
struct comp_unit_head *cu_header = &cu->header;
|
1927
|
+
struct dwarf2_per_objfile *dwarf2_per_objfile = cu->dwarf2_per_objfile;
|
1928
|
+
unsigned int bytes_read;
|
1929
|
+
struct dwarf_block *blk;
|
1930
|
+
|
1931
|
+
attr->form = form;
|
1932
|
+
switch (form)
|
1933
|
+
{
|
1934
|
+
case DW_FORM_addr:
|
1935
|
+
case DW_FORM_ref_addr:
|
1936
|
+
/* APPLE LOCAL Add cast to avoid type mismatch in arg4 warning. */
|
1937
|
+
attr->u.addr = read_address_of_cu (info_ptr, cu, (int *) &bytes_read);
|
1938
|
+
info_ptr += bytes_read;
|
1939
|
+
break;
|
1940
|
+
case DW_FORM_block2:
|
1941
|
+
blk = dwarf_alloc_block (cu);
|
1942
|
+
blk->size = read_2_bytes (info_ptr);
|
1943
|
+
info_ptr += 2;
|
1944
|
+
blk->data = read_n_bytes (info_ptr, blk->size);
|
1945
|
+
info_ptr += blk->size;
|
1946
|
+
attr->u.blk = blk;
|
1947
|
+
break;
|
1948
|
+
case DW_FORM_block4:
|
1949
|
+
blk = dwarf_alloc_block (cu);
|
1950
|
+
blk->size = read_4_bytes (info_ptr);
|
1951
|
+
info_ptr += 4;
|
1952
|
+
blk->data = read_n_bytes (info_ptr, blk->size);
|
1953
|
+
info_ptr += blk->size;
|
1954
|
+
attr->u.blk = blk;
|
1955
|
+
break;
|
1956
|
+
case DW_FORM_data2:
|
1957
|
+
//FIXME
|
1958
|
+
attr->u.unsnd = read_2_bytes (info_ptr);
|
1959
|
+
info_ptr += 2;
|
1960
|
+
break;
|
1961
|
+
case DW_FORM_data4:
|
1962
|
+
//FIXME
|
1963
|
+
attr->u.unsnd = read_4_bytes (info_ptr);
|
1964
|
+
info_ptr += 4;
|
1965
|
+
break;
|
1966
|
+
case DW_FORM_data8:
|
1967
|
+
//FIXME
|
1968
|
+
attr->u.unsnd = read_8_bytes (info_ptr);
|
1969
|
+
info_ptr += 8;
|
1970
|
+
break;
|
1971
|
+
case DW_FORM_string:
|
1972
|
+
attr->u.str = read_string (info_ptr, &bytes_read);
|
1973
|
+
info_ptr += bytes_read;
|
1974
|
+
break;
|
1975
|
+
case DW_FORM_strp:
|
1976
|
+
attr->u.str = read_indirect_string (info_ptr, cu_header, &bytes_read, dwarf2_per_objfile->str_buffer);
|
1977
|
+
//printf("attr->u.addr %s\n", attr->u.str);
|
1978
|
+
info_ptr += bytes_read;
|
1979
|
+
break;
|
1980
|
+
case DW_FORM_block:
|
1981
|
+
blk = dwarf_alloc_block (cu);
|
1982
|
+
blk->size = read_unsigned_leb128 (info_ptr, &bytes_read);
|
1983
|
+
info_ptr += bytes_read;
|
1984
|
+
blk->data = read_n_bytes (info_ptr, blk->size);
|
1985
|
+
info_ptr += blk->size;
|
1986
|
+
attr->u.blk = blk;
|
1987
|
+
break;
|
1988
|
+
case DW_FORM_block1:
|
1989
|
+
blk = dwarf_alloc_block (cu);
|
1990
|
+
blk->size = read_1_byte (info_ptr);
|
1991
|
+
info_ptr += 1;
|
1992
|
+
blk->data = read_n_bytes (info_ptr, blk->size);
|
1993
|
+
info_ptr += blk->size;
|
1994
|
+
attr->u.blk = blk;
|
1995
|
+
break;
|
1996
|
+
case DW_FORM_data1:
|
1997
|
+
attr->u.unsnd = read_1_byte (info_ptr);
|
1998
|
+
info_ptr += 1;
|
1999
|
+
break;
|
2000
|
+
case DW_FORM_flag:
|
2001
|
+
attr->u.unsnd = read_1_byte (info_ptr);
|
2002
|
+
info_ptr += 1;
|
2003
|
+
break;
|
2004
|
+
case DW_FORM_sdata:
|
2005
|
+
attr->u.snd = read_signed_leb128 (info_ptr, &bytes_read);
|
2006
|
+
info_ptr += bytes_read;
|
2007
|
+
break;
|
2008
|
+
case DW_FORM_APPLE_db_str:
|
2009
|
+
case DW_FORM_udata:
|
2010
|
+
attr->u.unsnd = read_unsigned_leb128 (info_ptr, &bytes_read);
|
2011
|
+
info_ptr += bytes_read;
|
2012
|
+
break;
|
2013
|
+
case DW_FORM_ref1:
|
2014
|
+
//FIXME
|
2015
|
+
attr->u.addr = cu->header.offset + read_1_byte (info_ptr);
|
2016
|
+
info_ptr += 1;
|
2017
|
+
break;
|
2018
|
+
case DW_FORM_ref2:
|
2019
|
+
attr->u.addr = cu->header.offset + read_2_bytes (info_ptr);
|
2020
|
+
info_ptr += 2;
|
2021
|
+
break;
|
2022
|
+
case DW_FORM_ref4:
|
2023
|
+
attr->u.addr = cu->header.offset + read_4_bytes (info_ptr);
|
2024
|
+
info_ptr += 4;
|
2025
|
+
break;
|
2026
|
+
case DW_FORM_ref8:
|
2027
|
+
attr->u.addr = cu->header.offset + read_8_bytes (info_ptr);
|
2028
|
+
info_ptr += 8;
|
2029
|
+
break;
|
2030
|
+
case DW_FORM_ref_udata:
|
2031
|
+
attr->u.addr = (cu->header.offset + read_unsigned_leb128 (info_ptr, &bytes_read));
|
2032
|
+
info_ptr += bytes_read;
|
2033
|
+
break;
|
2034
|
+
case DW_FORM_indirect:
|
2035
|
+
form = read_unsigned_leb128 (info_ptr, &bytes_read);
|
2036
|
+
info_ptr += bytes_read;
|
2037
|
+
info_ptr = read_attribute_value (attr, form, info_ptr, cu);
|
2038
|
+
break;
|
2039
|
+
default:
|
2040
|
+
fprintf(stderr, "Dwarf Error: Cannot handle in DWARF reader [in module s]");
|
2041
|
+
// dwarf_form_name (form),
|
2042
|
+
// bfd_get_filename (abfd));
|
2043
|
+
}
|
2044
|
+
return info_ptr;
|
2045
|
+
}
|
2046
|
+
|
2047
|
+
|
2048
|
+
/* Read an attribute described by an abbreviated attribute. */
|
2049
|
+
|
2050
|
+
static char * read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, char *info_ptr, struct dwarf2_cu *cu)
|
2051
|
+
{
|
2052
|
+
attr->name = abbrev->name;
|
2053
|
+
return read_attribute_value (attr, abbrev->form, info_ptr, cu);
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
static struct die_info * dwarf_alloc_die(void)
|
2057
|
+
{
|
2058
|
+
struct die_info *die;
|
2059
|
+
|
2060
|
+
die = (struct die_info *) malloc (sizeof (struct die_info));
|
2061
|
+
memset (die, 0, sizeof (struct die_info));
|
2062
|
+
return (die);
|
2063
|
+
}
|
2064
|
+
|
2065
|
+
|
2066
|
+
/* Read the die from the .debug_info section buffer. Set DIEP to
|
2067
|
+
point to a newly allocated die with its information, except for its
|
2068
|
+
child, sibling, and parent fields. Set HAS_CHILDREN to tell
|
2069
|
+
whether the die has children or not. */
|
2070
|
+
|
2071
|
+
static char * read_full_die (struct die_info **diep, char *info_ptr,
|
2072
|
+
struct dwarf2_cu *cu, int *has_children)
|
2073
|
+
{
|
2074
|
+
unsigned int abbrev_number, i;
|
2075
|
+
//unsigned int offset;
|
2076
|
+
unsigned int bytes_read;
|
2077
|
+
struct abbrev_info *abbrev;
|
2078
|
+
struct die_info *die;
|
2079
|
+
char *comp_dir = NULL;
|
2080
|
+
|
2081
|
+
abbrev_number = read_unsigned_leb128 (info_ptr, &bytes_read);
|
2082
|
+
info_ptr += bytes_read;
|
2083
|
+
if (!abbrev_number)
|
2084
|
+
{
|
2085
|
+
die = dwarf_alloc_die ();
|
2086
|
+
die->tag = 0;
|
2087
|
+
die->abbrev = abbrev_number;
|
2088
|
+
//die->type = NULL;
|
2089
|
+
*diep = die;
|
2090
|
+
*has_children = 0;
|
2091
|
+
return info_ptr;
|
2092
|
+
}
|
2093
|
+
|
2094
|
+
abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
|
2095
|
+
if (!abbrev)
|
2096
|
+
{
|
2097
|
+
fprintf(stderr, "Dwarf Error: could not find abbrev number %d\n", abbrev_number);
|
2098
|
+
}
|
2099
|
+
die = dwarf_alloc_die ();
|
2100
|
+
//die->offset = offset;
|
2101
|
+
die->tag = abbrev->tag;
|
2102
|
+
die->abbrev = abbrev_number;
|
2103
|
+
//die->type = NULL;
|
2104
|
+
|
2105
|
+
die->num_attrs = abbrev->num_attrs;
|
2106
|
+
die->attrs = (struct attribute *)malloc (die->num_attrs * sizeof (struct attribute));
|
2107
|
+
// printf("%s\n", dwarf_tag_name(die->tag));
|
2108
|
+
|
2109
|
+
for (i = 0; i < abbrev->num_attrs; ++i){
|
2110
|
+
info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], info_ptr, cu);
|
2111
|
+
// printf("%s\t %s\n", dwarf_attr_name(die->attrs[i].name), dwarf_form_name(die->attrs[i].form));
|
2112
|
+
|
2113
|
+
// /* APPLE LOCAL begin dwarf repository */
|
2114
|
+
// if (die->attrs[i].name == DW_AT_APPLE_repository_file)
|
2115
|
+
// repository_name = DW_STRING (&die->attrs[i]);
|
2116
|
+
if (die->attrs[i].name == DW_AT_comp_dir){
|
2117
|
+
comp_dir = die->attrs[i].u.str;
|
2118
|
+
//printf("%s\n", comp_dir);
|
2119
|
+
cu->comp_dir = comp_dir;
|
2120
|
+
}
|
2121
|
+
}
|
2122
|
+
|
2123
|
+
*diep = die;
|
2124
|
+
*has_children = abbrev->has_children;
|
2125
|
+
return info_ptr;
|
2126
|
+
}
|
2127
|
+
|
2128
|
+
|
2129
|
+
/* Read a whole compilation unit into a linked list of dies. */
|
2130
|
+
|
2131
|
+
static struct die_info * read_comp_unit (char *info_ptr, struct dwarf2_cu *cu)
|
2132
|
+
{
|
2133
|
+
return read_die_and_children (info_ptr, cu, &info_ptr, NULL);
|
2134
|
+
}
|
2135
|
+
|
2136
|
+
/* Read a single die and all its descendents. Set the die's sibling
|
2137
|
+
field to NULL; set other fields in the die correctly, and set all
|
2138
|
+
of the descendents' fields correctly. Set *NEW_INFO_PTR to the
|
2139
|
+
location of the info_ptr after reading all of those dies. PARENT
|
2140
|
+
is the parent of the die in question. */
|
2141
|
+
|
2142
|
+
static struct die_info * read_die_and_children (char *info_ptr, struct dwarf2_cu *cu, char **new_info_ptr, struct die_info *parent)
|
2143
|
+
{
|
2144
|
+
struct die_info *die;
|
2145
|
+
char *cur_ptr;
|
2146
|
+
int has_children;
|
2147
|
+
|
2148
|
+
cur_ptr = read_full_die (&die, info_ptr, cu, &has_children);
|
2149
|
+
//store_in_ref_table (die->offset, die, cu);
|
2150
|
+
|
2151
|
+
if (has_children)
|
2152
|
+
{
|
2153
|
+
die->child = read_die_and_siblings (cur_ptr, cu, new_info_ptr, die);
|
2154
|
+
}
|
2155
|
+
else
|
2156
|
+
{
|
2157
|
+
die->child = NULL;
|
2158
|
+
*new_info_ptr = cur_ptr;
|
2159
|
+
}
|
2160
|
+
|
2161
|
+
die->sibling = NULL;
|
2162
|
+
die->parent = parent;
|
2163
|
+
return die;
|
2164
|
+
}
|
2165
|
+
|
2166
|
+
/* Read a die, all of its descendents, and all of its siblings; set
|
2167
|
+
all of the fields of all of the dies correctly. Arguments are as
|
2168
|
+
in read_die_and_children. */
|
2169
|
+
|
2170
|
+
static struct die_info * read_die_and_siblings (char *info_ptr, struct dwarf2_cu *cu, char **new_info_ptr, struct die_info *parent)
|
2171
|
+
{
|
2172
|
+
struct die_info *first_die, *last_sibling;
|
2173
|
+
char *cur_ptr;
|
2174
|
+
|
2175
|
+
cur_ptr = info_ptr;
|
2176
|
+
first_die = last_sibling = NULL;
|
2177
|
+
|
2178
|
+
while (1)
|
2179
|
+
{
|
2180
|
+
struct die_info *die
|
2181
|
+
= read_die_and_children (cur_ptr, cu, &cur_ptr, parent);
|
2182
|
+
|
2183
|
+
if (!first_die)
|
2184
|
+
{
|
2185
|
+
first_die = die;
|
2186
|
+
}
|
2187
|
+
else
|
2188
|
+
{
|
2189
|
+
last_sibling->sibling = die;
|
2190
|
+
}
|
2191
|
+
|
2192
|
+
if (die->tag == 0)
|
2193
|
+
{
|
2194
|
+
*new_info_ptr = cur_ptr;
|
2195
|
+
return first_die;
|
2196
|
+
}
|
2197
|
+
else
|
2198
|
+
{
|
2199
|
+
last_sibling = die;
|
2200
|
+
}
|
2201
|
+
}
|
2202
|
+
}
|
2203
|
+
|
2204
|
+
/* Load the DIEs associated with PST and PER_CU into memory. */
|
2205
|
+
/* APPLE LOCAL debug map: Accept an optional 2nd parameter ADDR_MAP */
|
2206
|
+
|
2207
|
+
//static struct dwarf2_cu * load_full_comp_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, int i)
|
2208
|
+
static void load_full_comp_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, int i)
|
2209
|
+
{
|
2210
|
+
struct dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->all_comp_units[i];
|
2211
|
+
//struct partial_symtab *pst = per_cu->psymtab;
|
2212
|
+
//bfd *abfd = pst->objfile->obfd;
|
2213
|
+
struct dwarf2_cu *cu;
|
2214
|
+
unsigned long offset;
|
2215
|
+
char *info_ptr;
|
2216
|
+
//`struct cleanup *back_to, *free_cu_cleanup;
|
2217
|
+
//TODO ADD TARGET LANGUAGE
|
2218
|
+
//struct attribute *attr;
|
2219
|
+
/* APPLE LOCAL avoid unused var warning. */
|
2220
|
+
/* CORE_ADDR baseaddr; */
|
2221
|
+
|
2222
|
+
/* Set local variables from the partial symbol table info. */
|
2223
|
+
offset = per_cu->offset;
|
2224
|
+
//printf("offset: %08lx\n", offset);
|
2225
|
+
|
2226
|
+
info_ptr = dwarf2_per_objfile->info_buffer + offset;
|
2227
|
+
|
2228
|
+
cu = malloc (sizeof (struct dwarf2_cu));
|
2229
|
+
memset (cu, 0, sizeof (struct dwarf2_cu));
|
2230
|
+
cu->dwarf2_per_objfile = dwarf2_per_objfile;
|
2231
|
+
|
2232
|
+
/* If an error occurs while loading, release our storage. */
|
2233
|
+
//free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
|
2234
|
+
|
2235
|
+
//cu->objfile = pst->objfile;
|
2236
|
+
|
2237
|
+
/* read in the comp_unit header */
|
2238
|
+
info_ptr = read_comp_unit_head (&cu->header, info_ptr);
|
2239
|
+
|
2240
|
+
/* Read the abbrevs for this compilation unit */
|
2241
|
+
//dwarf2_read_abbrevs (cu);
|
2242
|
+
cu->dwarf2_abbrevs = dwarf2_per_objfile->dwarf2_abbrevs;
|
2243
|
+
|
2244
|
+
|
2245
|
+
// back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
|
2246
|
+
|
2247
|
+
cu->header.offset = offset;
|
2248
|
+
|
2249
|
+
/* APPLE LOCAL debug map */
|
2250
|
+
//cu->addr_map = addr_map;
|
2251
|
+
|
2252
|
+
cu->per_cu = per_cu;
|
2253
|
+
per_cu->cu = cu;
|
2254
|
+
|
2255
|
+
/* We use this obstack for block values in dwarf_alloc_block. */
|
2256
|
+
//obstack_init (&cu->comp_unit_obstack);
|
2257
|
+
|
2258
|
+
cu->dies = read_comp_unit (info_ptr, cu);
|
2259
|
+
|
2260
|
+
/* We try not to read any attributes in this function, because not
|
2261
|
+
all objfiles needed for references have been loaded yet, and symbol
|
2262
|
+
table processing isn't initialized. But we have to set the CU language,
|
2263
|
+
or we won't be able to build types correctly. */
|
2264
|
+
//attr = dwarf2_attr (cu->dies, DW_AT_language, cu);
|
2265
|
+
//if (attr)
|
2266
|
+
// set_cu_language (attr->u.unsnd., cu);
|
2267
|
+
//else
|
2268
|
+
// set_cu_language (language_minimal, cu);
|
2269
|
+
|
2270
|
+
//do_cleanups (back_to);
|
2271
|
+
|
2272
|
+
/* We've successfully allocated this compilation unit. Let our caller
|
2273
|
+
clean it up when finished with it. */
|
2274
|
+
//discard_cleanups (free_cu_cleanup);
|
2275
|
+
|
2276
|
+
//return cu;
|
2277
|
+
}
|
2278
|
+
|
2279
|
+
/* Generate full symbol information for PST and CU, whose DIEs have
|
2280
|
+
already been loaded into memory. */
|
2281
|
+
|
2282
|
+
|
2283
|
+
/* Create a list of all compilation units in OBJFILE. We do this only
|
2284
|
+
if an inter-comp-unit reference is found; presumably if there is one,
|
2285
|
+
there will be many, and one will occur early in the .debug_info section.
|
2286
|
+
So there's no point in building this list incrementally. */
|
2287
|
+
|
2288
|
+
static void create_all_comp_units(struct dwarf2_per_objfile *dwarf2_per_objfile)
|
2289
|
+
{
|
2290
|
+
int n_allocated;
|
2291
|
+
int n_comp_units;
|
2292
|
+
struct dwarf2_per_cu_data **all_comp_units;
|
2293
|
+
char *info_ptr = dwarf2_per_objfile->info_buffer;
|
2294
|
+
|
2295
|
+
n_comp_units = 0;
|
2296
|
+
n_allocated = 10;
|
2297
|
+
all_comp_units = malloc (n_allocated * sizeof (struct dwarf2_per_cu_data *));
|
2298
|
+
|
2299
|
+
while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
|
2300
|
+
{
|
2301
|
+
struct comp_unit_head cu_header;
|
2302
|
+
struct dwarf2_per_cu_data *this_cu;
|
2303
|
+
unsigned long offset;
|
2304
|
+
int bytes_read;
|
2305
|
+
|
2306
|
+
offset = info_ptr - dwarf2_per_objfile->info_buffer;
|
2307
|
+
|
2308
|
+
/* Read just enough information to find out where the next
|
2309
|
+
compilation unit is. */
|
2310
|
+
cu_header.initial_length_size = 0;
|
2311
|
+
cu_header.length = read_initial_length_of_comp_unit(info_ptr, &cu_header, &bytes_read);
|
2312
|
+
|
2313
|
+
/* Save the compilation unit for later lookup. */
|
2314
|
+
this_cu = malloc(sizeof (struct dwarf2_per_cu_data));
|
2315
|
+
memset (this_cu, 0, sizeof (*this_cu));
|
2316
|
+
this_cu->offset = offset;
|
2317
|
+
this_cu->length = cu_header.length + cu_header.initial_length_size;
|
2318
|
+
|
2319
|
+
if (n_comp_units == n_allocated)
|
2320
|
+
{
|
2321
|
+
n_allocated *= 2;
|
2322
|
+
all_comp_units = realloc (all_comp_units, n_allocated * sizeof (struct dwarf2_per_cu_data *));
|
2323
|
+
}
|
2324
|
+
all_comp_units[n_comp_units++] = this_cu;
|
2325
|
+
|
2326
|
+
info_ptr = info_ptr + this_cu->length;
|
2327
|
+
//printf("%p %p\n",info_ptr , dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size);
|
2328
|
+
}
|
2329
|
+
|
2330
|
+
dwarf2_per_objfile->all_comp_units = malloc (n_comp_units * sizeof (struct dwarf2_per_cu_data *));
|
2331
|
+
memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
|
2332
|
+
n_comp_units * sizeof (struct dwarf2_per_cu_data *));
|
2333
|
+
free (all_comp_units);
|
2334
|
+
dwarf2_per_objfile->n_comp_units = n_comp_units;
|
2335
|
+
}
|
2336
|
+
|
2337
|
+
static int parse_dwarf_abbrev(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
2338
|
+
//allocate space form the abbrev hash
|
2339
|
+
struct abbrev_info **dwarf2_abbrevs= malloc(sizeof(struct abbrev_info *) * ABBREV_HASH_SIZE);
|
2340
|
+
memset(dwarf2_abbrevs, 0, sizeof(struct abbrev_info *) * ABBREV_HASH_SIZE);
|
2341
|
+
|
2342
|
+
dwarf2_per_objfile->dwarf2_abbrevs = dwarf2_abbrevs;
|
2343
|
+
char * info_ptr = dwarf2_per_objfile->abbrev_buffer;
|
2344
|
+
int size = dwarf2_per_objfile->abbrev_size;
|
2345
|
+
char* endof_abbrev_pos = info_ptr + size;
|
2346
|
+
int i = 0;
|
2347
|
+
while(info_ptr < endof_abbrev_pos && *info_ptr != '\0'){
|
2348
|
+
unsigned int bytes_read = 0;
|
2349
|
+
unsigned long long abbrev_code = read_unsigned_leb128(info_ptr, &bytes_read);
|
2350
|
+
//printf("%llu %u\n", abbrev_code, bytes_read);
|
2351
|
+
info_ptr += bytes_read;
|
2352
|
+
unsigned long long entry_code = read_unsigned_leb128(info_ptr, &bytes_read);
|
2353
|
+
//printf("%llu\n", entry_code);
|
2354
|
+
info_ptr += bytes_read;
|
2355
|
+
unsigned char has_children = (unsigned char)*info_ptr;
|
2356
|
+
//printf("%u\n", has_children);
|
2357
|
+
info_ptr ++;
|
2358
|
+
|
2359
|
+
unsigned int num_attr_spec_pair = 0;
|
2360
|
+
num_attr_spec_pair = get_num_attr_spec_pair(info_ptr);
|
2361
|
+
|
2362
|
+
struct abbrev_info *ai = malloc(sizeof(struct abbrev_info));
|
2363
|
+
memset(ai, '\0', sizeof(struct abbrev_info));
|
2364
|
+
ai->number = (unsigned int)abbrev_code;
|
2365
|
+
ai->tag = (unsigned int)entry_code;
|
2366
|
+
ai->has_children = (unsigned short)has_children;
|
2367
|
+
ai->num_attrs = (unsigned short)num_attr_spec_pair;
|
2368
|
+
ai->next = NULL;
|
2369
|
+
//printf("%s\t", dwarf_tag_name(ai->tag));
|
2370
|
+
//printf("num_attr_spec_pair: %d\n", num_attr_spec_pair);
|
2371
|
+
if (num_attr_spec_pair != 0){
|
2372
|
+
struct attr_abbrev *attrs = malloc(num_attr_spec_pair * sizeof(struct attr_abbrev));
|
2373
|
+
memset(attrs, '\0', num_attr_spec_pair * sizeof(struct attr_abbrev));
|
2374
|
+
unsigned int attr_name_code = (unsigned int)read_unsigned_leb128(info_ptr, &bytes_read);
|
2375
|
+
info_ptr += bytes_read;
|
2376
|
+
unsigned int attr_form_code = (unsigned int)read_unsigned_leb128(info_ptr, &bytes_read);
|
2377
|
+
info_ptr += bytes_read;
|
2378
|
+
int j = 0;
|
2379
|
+
while(attr_name_code != 0 || attr_form_code != 0){
|
2380
|
+
attrs[j].name = attr_name_code;
|
2381
|
+
attrs[j].form = attr_form_code;
|
2382
|
+
debug("%s %s\n", dwarf_attr_name(attrs[j].name), dwarf_form_name(attrs[j].form));
|
2383
|
+
attr_name_code = (unsigned int)read_unsigned_leb128(info_ptr ,&bytes_read);
|
2384
|
+
info_ptr += bytes_read;
|
2385
|
+
attr_form_code = (unsigned int)read_unsigned_leb128(info_ptr ,&bytes_read);
|
2386
|
+
info_ptr += bytes_read;
|
2387
|
+
j++;
|
2388
|
+
}
|
2389
|
+
ai->attrs = attrs;
|
2390
|
+
}else{
|
2391
|
+
info_ptr += 2;
|
2392
|
+
ai->attrs = NULL;
|
2393
|
+
}
|
2394
|
+
struct abbrev_info **temp_abbr = &dwarf2_abbrevs[ai->number % ABBREV_HASH_SIZE];
|
2395
|
+
while(*temp_abbr){
|
2396
|
+
temp_abbr = &(*temp_abbr)->next;
|
2397
|
+
}
|
2398
|
+
*temp_abbr = ai;
|
2399
|
+
i++;
|
2400
|
+
}
|
2401
|
+
debug("parse dwarf2_per_objfile finished.");
|
2402
|
+
return 0;
|
2403
|
+
}
|
2404
|
+
|
2405
|
+
static int parse_dwarf_info(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
2406
|
+
create_all_comp_units(dwarf2_per_objfile);
|
2407
|
+
int i = 0;
|
2408
|
+
// struct dwarf2_cu *temp = NULL;
|
2409
|
+
for (i = 0; i< dwarf2_per_objfile->n_comp_units; i++){
|
2410
|
+
load_full_comp_unit(dwarf2_per_objfile, i);
|
2411
|
+
}
|
2412
|
+
return 0;
|
2413
|
+
}
|
2414
|
+
|
2415
|
+
static unsigned int get_num_arange_descriptor(char *aranges_ptr, struct arange *arange, int *flag){
|
2416
|
+
int bytes_read = 0;
|
2417
|
+
unsigned int num_of_ards = 0;
|
2418
|
+
CORE_ADDR beginning_addr = 0;
|
2419
|
+
unsigned int length = 0;
|
2420
|
+
while(1){
|
2421
|
+
beginning_addr = read_address_of_arange(aranges_ptr, arange, &bytes_read);
|
2422
|
+
aranges_ptr += bytes_read;
|
2423
|
+
|
2424
|
+
switch (arange->aranges_header.addr_size){
|
2425
|
+
case 2:
|
2426
|
+
length = read_signed_16(aranges_ptr);
|
2427
|
+
aranges_ptr += 2;
|
2428
|
+
break;
|
2429
|
+
case 4:
|
2430
|
+
length = read_signed_32(aranges_ptr);
|
2431
|
+
aranges_ptr += 4;
|
2432
|
+
break;
|
2433
|
+
case 8:
|
2434
|
+
length = read_signed_64(aranges_ptr);
|
2435
|
+
aranges_ptr += 8;
|
2436
|
+
break;
|
2437
|
+
default:
|
2438
|
+
fprintf(stderr, "read address length offset: bad switch, signed\n");
|
2439
|
+
PyErr_Format(ATOSError, "read address length offset: bad switch, signed");
|
2440
|
+
*flag = -1;
|
2441
|
+
return 0;
|
2442
|
+
}
|
2443
|
+
if(beginning_addr == 0 && length == 0){
|
2444
|
+
break;
|
2445
|
+
}
|
2446
|
+
num_of_ards ++;
|
2447
|
+
}
|
2448
|
+
return num_of_ards;
|
2449
|
+
}
|
2450
|
+
|
2451
|
+
static int parse_dwarf_aranges(struct dwarf2_per_objfile *dwarf2_per_objfile)
|
2452
|
+
{
|
2453
|
+
|
2454
|
+
int n_allocated;
|
2455
|
+
int n_aranges;
|
2456
|
+
struct arange **all_aranges;
|
2457
|
+
//struct dwarf2_per_cu_data **all_comp_units;
|
2458
|
+
//char *info_ptr = dwarf2_per_objfile->info_buffer;
|
2459
|
+
char *aranges_ptr = dwarf2_per_objfile->aranges_buffer;
|
2460
|
+
|
2461
|
+
n_aranges = 0;
|
2462
|
+
n_allocated = 10;
|
2463
|
+
//all_comp_units = malloc (n_allocated * sizeof (struct dwarf2_per_cu_data *));
|
2464
|
+
all_aranges = malloc(n_allocated * sizeof(struct arange *));
|
2465
|
+
|
2466
|
+
while (aranges_ptr < dwarf2_per_objfile->aranges_buffer+ dwarf2_per_objfile->aranges_size)
|
2467
|
+
{
|
2468
|
+
//struct aranges_header aranges_header;
|
2469
|
+
// struct dwarf2_per_cu_data *this_cu;
|
2470
|
+
//unsigned long offset;
|
2471
|
+
int bytes_read;
|
2472
|
+
|
2473
|
+
//offset = aranges_ptr - dwarf2_per_objfile->aranges_buffer;
|
2474
|
+
|
2475
|
+
// /* Read just enough information to find out where the next
|
2476
|
+
// compilation unit is. */
|
2477
|
+
// cu_header.initial_length_size = 0;
|
2478
|
+
// cu_header.length = read_initial_length (info_ptr, &cu_header, &bytes_read);
|
2479
|
+
|
2480
|
+
struct arange *arange = malloc(sizeof(struct arange));
|
2481
|
+
memset(arange, 0, sizeof(struct arange));
|
2482
|
+
|
2483
|
+
arange->aranges_header.length = read_initial_length_of_aranges(aranges_ptr, &arange->aranges_header, &bytes_read);
|
2484
|
+
aranges_ptr += 4;
|
2485
|
+
|
2486
|
+
arange->aranges_header.version = read_2_bytes(aranges_ptr);
|
2487
|
+
aranges_ptr += 2;
|
2488
|
+
|
2489
|
+
arange->aranges_header.info_offset = read_4_bytes(aranges_ptr);
|
2490
|
+
aranges_ptr += 4;
|
2491
|
+
|
2492
|
+
arange->aranges_header.addr_size = read_1_byte(aranges_ptr);
|
2493
|
+
aranges_ptr += 1;
|
2494
|
+
|
2495
|
+
arange->aranges_header.seg_size = read_1_byte(aranges_ptr);
|
2496
|
+
aranges_ptr += 1;
|
2497
|
+
|
2498
|
+
//FIXME 4 additional null bytes
|
2499
|
+
unsigned int zeros = read_4_bytes(aranges_ptr);
|
2500
|
+
assert(zeros == 0);
|
2501
|
+
if(zeros != 0){
|
2502
|
+
fprintf(stderr, "should be 4 additional null bytes.");
|
2503
|
+
PyErr_Format(ATOSError, "should be 4 additional null bytes");
|
2504
|
+
return -1;
|
2505
|
+
}
|
2506
|
+
aranges_ptr += 4;
|
2507
|
+
int flag = 0;
|
2508
|
+
unsigned int num_of_ards = get_num_arange_descriptor(aranges_ptr, arange, &flag);
|
2509
|
+
if (flag == -1){
|
2510
|
+
return -1;
|
2511
|
+
}
|
2512
|
+
arange->num_of_ards = num_of_ards;
|
2513
|
+
//printf("num_of_ards: %d\n", num_of_ards);
|
2514
|
+
|
2515
|
+
arange->address_range_descriptors = malloc(num_of_ards * sizeof(struct address_range_descriptor));
|
2516
|
+
assert(arange->address_range_descriptors != NULL);
|
2517
|
+
if(arange->address_range_descriptors == NULL){
|
2518
|
+
PyErr_NoMemory();
|
2519
|
+
return -1;
|
2520
|
+
}
|
2521
|
+
memset(arange->address_range_descriptors, 0, num_of_ards * sizeof(struct address_range_descriptor));
|
2522
|
+
//struct address_range_descriptor ard
|
2523
|
+
int i = 0;
|
2524
|
+
int aranges_header_addr_size = 0;
|
2525
|
+
for(i = 0; i < num_of_ards; i++){
|
2526
|
+
arange->address_range_descriptors[i].beginning_addr = read_address_of_arange(aranges_ptr, arange, &bytes_read);
|
2527
|
+
aranges_ptr += bytes_read;
|
2528
|
+
//save the address size for skipping the right number of bytes from the end of address_range_descriptors
|
2529
|
+
aranges_header_addr_size = bytes_read;
|
2530
|
+
switch (arange->aranges_header.addr_size){
|
2531
|
+
case 2:
|
2532
|
+
arange->address_range_descriptors[i].length = read_signed_16(aranges_ptr);
|
2533
|
+
aranges_ptr += 2;
|
2534
|
+
break;
|
2535
|
+
case 4:
|
2536
|
+
arange->address_range_descriptors[i].length = read_signed_32(aranges_ptr);
|
2537
|
+
aranges_ptr += 4;
|
2538
|
+
break;
|
2539
|
+
case 8:
|
2540
|
+
arange->address_range_descriptors[i].length = read_signed_64(aranges_ptr);
|
2541
|
+
aranges_ptr += 8;
|
2542
|
+
break;
|
2543
|
+
default:
|
2544
|
+
fprintf(stderr, "read address length offset: bad switch, signed\n");
|
2545
|
+
PyErr_Format(ATOSError, "read address length offset: bad switch, signed\n");
|
2546
|
+
return -1;
|
2547
|
+
}
|
2548
|
+
|
2549
|
+
//arange->address_range_descriptors[i].length = read_4_bytes(aranges_ptr);
|
2550
|
+
|
2551
|
+
// printf("beginning_addr: 0X%X\t", arange->address_range_descriptors[i].beginning_addr);
|
2552
|
+
// printf("length: 0X%X\n", arange->address_range_descriptors[i].length);
|
2553
|
+
}
|
2554
|
+
//skip ending zeros
|
2555
|
+
aranges_ptr += (2 * aranges_header_addr_size);
|
2556
|
+
// /* Save the compilation unit for later lookup. */
|
2557
|
+
// this_cu = malloc(sizeof (struct dwarf2_per_cu_data));
|
2558
|
+
// memset (this_cu, 0, sizeof (*this_cu));
|
2559
|
+
// this_cu->offset = offset;
|
2560
|
+
// this_cu->length = cu_header.length + cu_header.initial_length_size;
|
2561
|
+
|
2562
|
+
if (n_aranges == n_allocated)
|
2563
|
+
{
|
2564
|
+
n_allocated *= 2;
|
2565
|
+
all_aranges = realloc (all_aranges, n_allocated * sizeof (struct arange*));
|
2566
|
+
}
|
2567
|
+
all_aranges[n_aranges++] = arange;
|
2568
|
+
|
2569
|
+
// info_ptr = info_ptr + this_cu->length;
|
2570
|
+
// //printf("%p %p\n",info_ptr , dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size);
|
2571
|
+
}
|
2572
|
+
|
2573
|
+
//dwarf2_per_objfile->all_comp_units = malloc (n_comp_units * sizeof (struct dwarf2_per_cu_data *));
|
2574
|
+
dwarf2_per_objfile->all_aranges = malloc (n_aranges * sizeof (struct arange*));
|
2575
|
+
memcpy (dwarf2_per_objfile->all_aranges, all_aranges, n_aranges * sizeof (struct arange *));
|
2576
|
+
free (all_aranges);
|
2577
|
+
dwarf2_per_objfile->n_aranges = n_aranges;
|
2578
|
+
return 0;
|
2579
|
+
}
|
2580
|
+
|
2581
|
+
static int is_target_subprogram(struct die_info *die, struct address_range_descriptor *target_ard, CORE_ADDR integer_address){
|
2582
|
+
//FIXME May not need target_ard
|
2583
|
+
int flag = 0;
|
2584
|
+
unsigned int i = 0;
|
2585
|
+
for(i = 0; i< die->num_attrs; i++){
|
2586
|
+
//if(die->attrs[i].name == DW_AT_low_pc && die->attrs[i].u.addr >= target_ard->beginning_addr && integer_address ){
|
2587
|
+
// flag++;
|
2588
|
+
//}
|
2589
|
+
|
2590
|
+
//if(die->attrs[i].name == DW_AT_high_pc && die->attrs[i].u.addr <= (target_ard->beginning_addr + target_ard->length)){
|
2591
|
+
// flag++;
|
2592
|
+
//}
|
2593
|
+
if(die->attrs[i].name == DW_AT_low_pc && die->attrs[i].u.addr <= integer_address ){
|
2594
|
+
flag++;
|
2595
|
+
}
|
2596
|
+
|
2597
|
+
if(die->attrs[i].name == DW_AT_high_pc && die->attrs[i].u.addr > integer_address){
|
2598
|
+
flag++;
|
2599
|
+
}
|
2600
|
+
|
2601
|
+
|
2602
|
+
if(flag == 2){
|
2603
|
+
return 1;
|
2604
|
+
}
|
2605
|
+
}
|
2606
|
+
|
2607
|
+
return -1;
|
2608
|
+
|
2609
|
+
}
|
2610
|
+
|
2611
|
+
static struct die_info *find_target_subprogram(struct die_info *die, struct address_range_descriptor *target_ard, CORE_ADDR integer_address){
|
2612
|
+
if(die->tag == DW_TAG_subprogram){
|
2613
|
+
if(is_target_subprogram(die, target_ard, integer_address) == 1){
|
2614
|
+
return die;
|
2615
|
+
}
|
2616
|
+
}
|
2617
|
+
|
2618
|
+
if(die->sibling != NULL){
|
2619
|
+
return find_target_subprogram(die->sibling, target_ard, integer_address);
|
2620
|
+
}
|
2621
|
+
|
2622
|
+
if(die->child != NULL){
|
2623
|
+
return find_target_subprogram(die->child, target_ard, integer_address);
|
2624
|
+
}
|
2625
|
+
return NULL;
|
2626
|
+
|
2627
|
+
}
|
2628
|
+
static char *get_name_attribute(struct die_info *die){
|
2629
|
+
unsigned int i = 0;
|
2630
|
+
for(i = 0; i < die->num_attrs; i++){
|
2631
|
+
if (die->attrs[i].name == DW_AT_name){
|
2632
|
+
return die->attrs[i].u.str;
|
2633
|
+
}
|
2634
|
+
}
|
2635
|
+
return NULL;
|
2636
|
+
}
|
2637
|
+
|
2638
|
+
static unsigned int get_stmt_list_attribute(struct die_info *die, char *flag){
|
2639
|
+
unsigned int i = 0;
|
2640
|
+
for(i = 0; i < die->num_attrs; i++){
|
2641
|
+
if (die->attrs[i].name == DW_AT_stmt_list){
|
2642
|
+
*flag = 0;
|
2643
|
+
return die->attrs[i].u.addr;
|
2644
|
+
}
|
2645
|
+
}
|
2646
|
+
*flag = 1;
|
2647
|
+
return 0;
|
2648
|
+
}
|
2649
|
+
|
2650
|
+
static int get_lineno_for_address(struct subfile *subfile, CORE_ADDR address){
|
2651
|
+
struct linetable_entry *current_entry;
|
2652
|
+
struct linetable_entry *next_entry;
|
2653
|
+
int i = 0;
|
2654
|
+
for(i = 0; i < subfile->line_vector->nitems; i ++){
|
2655
|
+
current_entry = subfile->line_vector->item + i;
|
2656
|
+
next_entry = subfile->line_vector->item + i + 1;
|
2657
|
+
if(address >= current_entry->pc && address < next_entry->pc ){
|
2658
|
+
return current_entry ->line;
|
2659
|
+
}
|
2660
|
+
}
|
2661
|
+
return 0;
|
2662
|
+
}
|
2663
|
+
|
2664
|
+
void free_sub_file(struct subfile *subfile){
|
2665
|
+
free(subfile->line_vector);
|
2666
|
+
free(subfile);
|
2667
|
+
}
|
2668
|
+
|
2669
|
+
void print_thin_macho_aranges(struct thin_macho *thin_macho){
|
2670
|
+
struct dwarf2_per_objfile* dwarf2_per_objfile = thin_macho->dwarf2_per_objfile;
|
2671
|
+
unsigned int num = dwarf2_per_objfile->n_aranges;
|
2672
|
+
struct arange **all_aranges = dwarf2_per_objfile->all_aranges;
|
2673
|
+
|
2674
|
+
unsigned int i = 0, j = 0;
|
2675
|
+
for(i = 0; i< num; i++){
|
2676
|
+
struct arange *arange = all_aranges[i];
|
2677
|
+
printf("Address Range Header: length = 0x%08x version = 0x%04x cu_offset = 0x%08x addr_size = 0x%02x seg_size = 0x%02x\n", arange->aranges_header.length, arange->aranges_header.version, arange->aranges_header.info_offset, arange->aranges_header.addr_size, arange->aranges_header.seg_size);
|
2678
|
+
for (j = 0; j < arange->num_of_ards; j++){
|
2679
|
+
printf("0x%016llx + 0x%016llx = 0x%016llx\n", arange->address_range_descriptors[j].beginning_addr, arange->address_range_descriptors[j].length, arange->address_range_descriptors[j].beginning_addr + arange->address_range_descriptors[j].length);
|
2680
|
+
//printf("0x%08x + 0x%08x = 0x%08x\n", arange->address_range_descriptors[j].beginning_addr, arange->address_range_descriptors[j].length, arange->address_range_descriptors[j].beginning_addr + arange->address_range_descriptors[j].length);
|
2681
|
+
}
|
2682
|
+
}
|
2683
|
+
}
|
2684
|
+
|
2685
|
+
static void select_symbol_by_address(struct nlist *symbols, uint32_t nsyms, CORE_ADDR target, struct nlist **found_symbol, int *offset){
|
2686
|
+
uint32_t i= 0;
|
2687
|
+
for (i = 0; i < nsyms; ++i) {
|
2688
|
+
/* The symbol must be defined in a section, and must not be a debugging entry. */
|
2689
|
+
if ((symbols[i].n_type & N_TYPE) != N_SECT || ((symbols[i].n_type & N_STAB) != 0)) {
|
2690
|
+
continue;
|
2691
|
+
}
|
2692
|
+
/* If we haven't already found a symbol and the address we want is
|
2693
|
+
* greater than the symbol's value, save this symbol. */
|
2694
|
+
if (!*found_symbol && symbols[i].n_value <= target) {
|
2695
|
+
*found_symbol = &symbols[i];
|
2696
|
+
*offset = target - symbols[i].n_value;
|
2697
|
+
/* If we have found a symbol already, but if the address we want is
|
2698
|
+
* greater than the current symbol's value and the current symbol is later
|
2699
|
+
* than the last one found, the current one is a closer match. */
|
2700
|
+
} else if (*found_symbol && symbols[i].n_value <= target && ((*found_symbol)->n_value < symbols[i].n_value)) {
|
2701
|
+
*found_symbol = &symbols[i];
|
2702
|
+
*offset = target - symbols[i].n_value;
|
2703
|
+
}
|
2704
|
+
}
|
2705
|
+
}
|
2706
|
+
|
2707
|
+
int lookup_by_address_in_symtable(struct thin_macho *tm, CORE_ADDR integer_address){
|
2708
|
+
int offset = -1;
|
2709
|
+
struct nlist *found_symbol = NULL;
|
2710
|
+
//struct nlist *global_syms = (struct nlist *)(tm->all_symbols + tm->symbolInformation.firstGlobalSymbol * sizeof(struct nlist)),
|
2711
|
+
// *local_syms = (struct nlist *)(tm->all_symbols + tm->symbolInformation.firstLocalSymbol * sizeof(struct nlist));
|
2712
|
+
//select_symbol_by_address(global_syms, tm->symbolInformation.numGlobalSymbols, integer_address, &found_symbol, &offset);
|
2713
|
+
//select_symbol_by_address(local_syms, tm->symbolInformation.numLocalSymbols, integer_address, &found_symbol, &offset);
|
2714
|
+
select_symbol_by_address(tm->all_symbols, tm->nsyms, integer_address, &found_symbol, &offset);
|
2715
|
+
if(found_symbol){
|
2716
|
+
printf("%s (in %s) + %d\n", tm->strings + found_symbol->n_un.n_strx, project_name, offset);
|
2717
|
+
return 0;
|
2718
|
+
}else{
|
2719
|
+
return -1;
|
2720
|
+
}
|
2721
|
+
}
|
2722
|
+
|
2723
|
+
int lookup_by_address_in_dwarf(struct thin_macho *thin_macho, CORE_ADDR integer_address){
|
2724
|
+
CORE_ADDR address = (CORE_ADDR)integer_address;
|
2725
|
+
struct dwarf2_per_objfile* dwarf2_per_objfile = thin_macho->dwarf2_per_objfile;
|
2726
|
+
unsigned int num = dwarf2_per_objfile->n_aranges;
|
2727
|
+
struct arange **all_aranges = dwarf2_per_objfile->all_aranges;
|
2728
|
+
struct arange *target_arange = NULL;
|
2729
|
+
struct address_range_descriptor *target_ard = NULL;
|
2730
|
+
unsigned int i = 0, j = 0;
|
2731
|
+
for(i = 0; i< num; i++){
|
2732
|
+
struct arange *arange = all_aranges[i];
|
2733
|
+
for(j = 0; j < arange->num_of_ards; j++){
|
2734
|
+
//debug
|
2735
|
+
CORE_ADDR beginning_addr = arange->address_range_descriptors[j].beginning_addr;
|
2736
|
+
CORE_ADDR ending_addr = arange->address_range_descriptors[j].beginning_addr + arange->address_range_descriptors[j].length;
|
2737
|
+
//printf("0x%016llx + 0x%016llx = 0x%016llx\n", arange->address_range_descriptors[j].beginning_addr, arange->address_range_descriptors[j].length, arange->address_range_descriptors[j].beginning_addr + arange->address_range_descriptors[j].length);
|
2738
|
+
if (address >= beginning_addr && address < ending_addr){
|
2739
|
+
target_arange = arange;
|
2740
|
+
target_ard = &arange->address_range_descriptors[j];
|
2741
|
+
break;
|
2742
|
+
}
|
2743
|
+
}
|
2744
|
+
}
|
2745
|
+
|
2746
|
+
if(target_arange == NULL){
|
2747
|
+
debug("target_arange is NULL\n\n");
|
2748
|
+
return -1;
|
2749
|
+
}
|
2750
|
+
|
2751
|
+
if(target_ard == NULL){
|
2752
|
+
debug("target_ard is NULL\n\n");
|
2753
|
+
return -1;
|
2754
|
+
}
|
2755
|
+
|
2756
|
+
//find the target compilation unit
|
2757
|
+
struct dwarf2_per_cu_data *target_dwarf2_per_cu_data= NULL;
|
2758
|
+
for (i = 0; i < dwarf2_per_objfile->n_comp_units; i++){
|
2759
|
+
if (dwarf2_per_objfile->all_comp_units[i]->offset == target_arange->aranges_header.info_offset){
|
2760
|
+
debug("offset :0x%08lx\tlength: 0x%08lx\n", dwarf2_per_objfile->all_comp_units[i]->offset, dwarf2_per_objfile->all_comp_units[i]->length);
|
2761
|
+
target_dwarf2_per_cu_data = dwarf2_per_objfile->all_comp_units[i];
|
2762
|
+
break;
|
2763
|
+
}
|
2764
|
+
}
|
2765
|
+
struct dwarf2_cu *target_cu = target_dwarf2_per_cu_data->cu;
|
2766
|
+
|
2767
|
+
struct die_info *target_die = find_target_subprogram(target_cu->dies, target_ard, integer_address);
|
2768
|
+
if(target_die == NULL){
|
2769
|
+
debug("Can not find target subprogram.\n");
|
2770
|
+
return -1;
|
2771
|
+
}
|
2772
|
+
char *target_program_full_name = get_name_attribute(target_cu->dies);
|
2773
|
+
char *target_program_name = strrchr(target_program_full_name, '/');
|
2774
|
+
if(target_program_name == NULL){
|
2775
|
+
target_program_name = target_program_full_name;
|
2776
|
+
}else{
|
2777
|
+
target_program_name = target_program_name +1;
|
2778
|
+
}
|
2779
|
+
char *target_subprogram_name = get_name_attribute(target_die);
|
2780
|
+
|
2781
|
+
//Lookup address infomation
|
2782
|
+
char flag = 0;
|
2783
|
+
unsigned int offset = get_stmt_list_attribute(target_cu->dies, &flag);
|
2784
|
+
if(flag == 1){
|
2785
|
+
fprintf(stderr, "do not have stmt_list attribute\n");
|
2786
|
+
PyErr_Format(ATOSError, "do not have stmt_list attribute");
|
2787
|
+
return -1;
|
2788
|
+
}else{
|
2789
|
+
debug("offset: 0x%08x\n", offset);
|
2790
|
+
}
|
2791
|
+
struct line_header *lh = dwarf_decode_line_header (offset, target_cu);
|
2792
|
+
if(lh == NULL){
|
2793
|
+
return -1;
|
2794
|
+
}
|
2795
|
+
struct subfile * current_subfile = dwarf_decode_lines (lh, NULL, target_cu);
|
2796
|
+
//print_line_vector(current_subfile);
|
2797
|
+
int lineno = get_lineno_for_address(current_subfile, address);
|
2798
|
+
debug("lineno: %d\n",lineno);
|
2799
|
+
printf("%s (in %s) (%s:%d)\n", target_subprogram_name, project_name, target_program_name, lineno);
|
2800
|
+
free_sub_file(current_subfile);
|
2801
|
+
free_line_header(lh);
|
2802
|
+
|
2803
|
+
return 0;
|
2804
|
+
}
|
2805
|
+
|
2806
|
+
void print_symbols(struct nlist *all_symbols, uint32_t numofsyms, char *strings, uint32_t strsize){
|
2807
|
+
int i = 0;
|
2808
|
+
for (i = 0; i < numofsyms; i++){
|
2809
|
+
printf("%08x: %s\n", all_symbols[i].n_value, strings + all_symbols[i].n_un.n_strx);
|
2810
|
+
}
|
2811
|
+
}
|
2812
|
+
|
2813
|
+
void parse_lc_symtab(char *macho_str, struct symtab_command *command, struct thin_macho*tm){
|
2814
|
+
//FIXME BIGENDIAN?
|
2815
|
+
uint32_t symoff = command->symoff;
|
2816
|
+
uint32_t nsyms = command->nsyms;
|
2817
|
+
uint32_t stroff = command->stroff;
|
2818
|
+
uint32_t strsize = command->strsize;
|
2819
|
+
|
2820
|
+
//struct nlist_64 *all_symbols64;
|
2821
|
+
|
2822
|
+
|
2823
|
+
tm->all_symbols = malloc(command->nsyms * sizeof(struct nlist));
|
2824
|
+
memset(tm->all_symbols, '\0', command->nsyms * sizeof(struct nlist));
|
2825
|
+
memcpy(tm->all_symbols, macho_str + symoff, command->nsyms * sizeof(struct nlist));
|
2826
|
+
tm->nsyms = nsyms;
|
2827
|
+
|
2828
|
+
tm->strings = macho_str + stroff;
|
2829
|
+
tm->strsize = strsize;
|
2830
|
+
//print_symbols(tm->all_symbols, tm->nsyms, tm->strings, tm->strsize);
|
2831
|
+
//FIXME for 64
|
2832
|
+
//all_symbols64 = (struct nlist_64 *)(ofile->object_addr +st->symoff);
|
2833
|
+
}
|
2834
|
+
|
2835
|
+
int parse_dwarf2_per_objfile(struct dwarf2_per_objfile *dwarf2_per_objfile){
|
2836
|
+
int result = -1;
|
2837
|
+
//TODO
|
2838
|
+
debug("about to parse_dwarf_abbrev");
|
2839
|
+
result = parse_dwarf_abbrev(dwarf2_per_objfile);
|
2840
|
+
if (result == -1){
|
2841
|
+
return -1;
|
2842
|
+
}
|
2843
|
+
debug("about to parse_dwarf_info");
|
2844
|
+
result = parse_dwarf_info(dwarf2_per_objfile);
|
2845
|
+
if (result == -1){
|
2846
|
+
return -1;
|
2847
|
+
}
|
2848
|
+
debug("about to parse_dwarf_aranges");
|
2849
|
+
result = parse_dwarf_aranges(dwarf2_per_objfile);
|
2850
|
+
if (result == -1){
|
2851
|
+
return -1;
|
2852
|
+
}
|
2853
|
+
return 0;
|
2854
|
+
}
|
2855
|
+
|
2856
|
+
int parse_load_command(char *macho_str, long *offset, struct load_command *lc, struct thin_macho*tm){
|
2857
|
+
int load_command_result = -1;
|
2858
|
+
switch (lc->cmd){
|
2859
|
+
case LC_UUID:
|
2860
|
+
load_command_result = process_lc_uuid(macho_str, offset, tm);
|
2861
|
+
break;
|
2862
|
+
case LC_SEGMENT:
|
2863
|
+
load_command_result = process_lc_segment(macho_str, offset, tm);
|
2864
|
+
break;
|
2865
|
+
case LC_SEGMENT_64:
|
2866
|
+
load_command_result = process_lc_segment_64(macho_str, offset, tm);
|
2867
|
+
break;
|
2868
|
+
case LC_SYMTAB:
|
2869
|
+
load_command_result = process_lc_symtab(macho_str, offset, tm);
|
2870
|
+
break;
|
2871
|
+
case LC_DYSYMTAB:
|
2872
|
+
load_command_result = process_lc_dysymtab(macho_str, offset, tm);
|
2873
|
+
break;
|
2874
|
+
case LC_THREAD:
|
2875
|
+
load_command_result = process_lc_thread(macho_str, offset);
|
2876
|
+
break;
|
2877
|
+
case LC_UNIXTHREAD:
|
2878
|
+
load_command_result = process_lc_unixthread(macho_str, offset);
|
2879
|
+
break;
|
2880
|
+
case LC_LOAD_DYLIB:
|
2881
|
+
load_command_result = process_lc_load_dylib(macho_str, offset);
|
2882
|
+
break;
|
2883
|
+
case LC_ID_DYLIB:
|
2884
|
+
load_command_result = process_lc_id_dylib(macho_str, offset);
|
2885
|
+
break;
|
2886
|
+
case LC_PREBOUND_DYLIB:
|
2887
|
+
load_command_result = process_lc_prebound_dylib(macho_str, offset);
|
2888
|
+
break;
|
2889
|
+
case LC_LOAD_DYLINKER:
|
2890
|
+
load_command_result = process_lc_load_dylinker(macho_str, offset);
|
2891
|
+
break;
|
2892
|
+
case LC_ID_DYLINKER:
|
2893
|
+
load_command_result = process_lc_id_dylinker(macho_str, offset);
|
2894
|
+
break;
|
2895
|
+
case LC_ROUTINES:
|
2896
|
+
load_command_result = process_lc_routines(macho_str, offset);
|
2897
|
+
break;
|
2898
|
+
case LC_ROUTINES_64:
|
2899
|
+
load_command_result = process_lc_routines_64(macho_str, offset);
|
2900
|
+
break;
|
2901
|
+
case LC_TWOLEVEL_HINTS:
|
2902
|
+
load_command_result = process_lc_twolevel_hints(macho_str, offset);
|
2903
|
+
break;
|
2904
|
+
case LC_SUB_FRAMEWORK:
|
2905
|
+
load_command_result = process_lc_sub_framework(macho_str, offset);
|
2906
|
+
break;
|
2907
|
+
case LC_SUB_UMBRELLA:
|
2908
|
+
load_command_result = process_lc_sub_umbrella(macho_str, offset);
|
2909
|
+
break;
|
2910
|
+
case LC_SUB_LIBRARY:
|
2911
|
+
load_command_result = process_lc_sub_library(macho_str, offset);
|
2912
|
+
break;
|
2913
|
+
case LC_SUB_CLIENT:
|
2914
|
+
load_command_result = process_lc_sub_client(macho_str, offset);
|
2915
|
+
break;
|
2916
|
+
case LC_DATA_IN_CODE:
|
2917
|
+
load_command_result = process_lc_data_in_code(macho_str, offset);
|
2918
|
+
break;
|
2919
|
+
case LC_FUNCTION_STARTS:
|
2920
|
+
load_command_result = process_lc_function_starts(macho_str, offset);
|
2921
|
+
break;
|
2922
|
+
case LC_DYLD_INFO_ONLY:
|
2923
|
+
load_command_result = process_lc_dyld_info_only(macho_str, offset);
|
2924
|
+
break;
|
2925
|
+
case LC_DYLD_INFO:
|
2926
|
+
load_command_result = process_lc_dyld_info_only(macho_str, offset);
|
2927
|
+
break;
|
2928
|
+
case LC_VERSION_MIN_IPHONEOS:
|
2929
|
+
load_command_result = process_lc_version_min_iphoneos(macho_str, offset);
|
2930
|
+
break;
|
2931
|
+
case LC_VERSION_MIN_MACOSX:
|
2932
|
+
load_command_result = process_lc_version_min_macosx(macho_str, offset);
|
2933
|
+
break;
|
2934
|
+
case LC_SOURCE_VERSION:
|
2935
|
+
load_command_result = process_lc_source_version(macho_str, offset);
|
2936
|
+
break;
|
2937
|
+
case LC_REEXPORT_DYLIB:
|
2938
|
+
load_command_result = process_lc_reexport_dylib(macho_str, offset);
|
2939
|
+
break;
|
2940
|
+
case LC_SYMSEG:
|
2941
|
+
load_command_result = process_lc_symseg(macho_str, offset);
|
2942
|
+
break;
|
2943
|
+
case LC_LOADFVMLIB:
|
2944
|
+
load_command_result = process_lc_loadfvmlib(macho_str, offset);
|
2945
|
+
break;
|
2946
|
+
case LC_IDFVMLIB:
|
2947
|
+
load_command_result = process_lc_idfvmlib(macho_str, offset);
|
2948
|
+
break;
|
2949
|
+
case LC_IDENT:
|
2950
|
+
load_command_result = process_lc_ident(macho_str, offset);
|
2951
|
+
break;
|
2952
|
+
case LC_FVMFILE:
|
2953
|
+
load_command_result = process_lc_fvmfile(macho_str, offset);
|
2954
|
+
break;
|
2955
|
+
case LC_PREBIND_CKSUM:
|
2956
|
+
load_command_result = process_lc_prebind_cksum(macho_str, offset);
|
2957
|
+
break;
|
2958
|
+
case LC_LOAD_WEAK_DYLIB:
|
2959
|
+
load_command_result = process_lc_load_weak_dylib(macho_str, offset);
|
2960
|
+
break;
|
2961
|
+
case LC_RPATH:
|
2962
|
+
load_command_result = process_lc_rpath(macho_str, offset);
|
2963
|
+
break;
|
2964
|
+
case LC_CODE_SIGNATURE:
|
2965
|
+
load_command_result = process_lc_code_signature(macho_str, offset);
|
2966
|
+
break;
|
2967
|
+
case LC_SEGMENT_SPLIT_INFO:
|
2968
|
+
load_command_result = process_lc_segment_split_info(macho_str, offset);
|
2969
|
+
break;
|
2970
|
+
case LC_ENCRYPTION_INFO:
|
2971
|
+
load_command_result = process_lc_encryption_info(macho_str, offset);
|
2972
|
+
break;
|
2973
|
+
case LC_DYLD_ENVIRONMENT:
|
2974
|
+
load_command_result = process_lc_dyld_environment(macho_str, offset);
|
2975
|
+
break;
|
2976
|
+
case LC_MAIN:
|
2977
|
+
load_command_result = process_lc_main(macho_str, offset);
|
2978
|
+
break;
|
2979
|
+
case LC_DYLIB_CODE_SIGN_DRS:
|
2980
|
+
load_command_result = process_lc_dylib_code_sign_drs(macho_str, offset);
|
2981
|
+
break;
|
2982
|
+
case LC_PREPAGE:
|
2983
|
+
//printf("known load commmand type LC_PREPAGE, but ignoring...\n");
|
2984
|
+
load_command_result = process_lc_command(macho_str, offset);
|
2985
|
+
break;
|
2986
|
+
case LC_LAZY_LOAD_DYLIB:
|
2987
|
+
//printf("known load commmand type LC_LAZY_LOAD_DYLIB, but ignoring...\n");
|
2988
|
+
load_command_result = process_lc_command(macho_str, offset);
|
2989
|
+
break;
|
2990
|
+
case LC_LOAD_UPWARD_DYLIB:
|
2991
|
+
//printf("known load commmand type LC_LOAD_UPWARD_DYLIB, but ignoring...\n");
|
2992
|
+
load_command_result = process_lc_command(macho_str, offset);
|
2993
|
+
break;
|
2994
|
+
default:
|
2995
|
+
fprintf(stderr, "unknown load commmand type, ignoring...\n");
|
2996
|
+
}
|
2997
|
+
return load_command_result;
|
2998
|
+
}
|
2999
|
+
|
3000
|
+
void print_uuid(struct uuid_command *command){
|
3001
|
+
int numofbytes = sizeof(command->uuid)/sizeof(*command->uuid);
|
3002
|
+
printf("uuid: ");
|
3003
|
+
int i = 0;
|
3004
|
+
for (i = 0; i < numofbytes; i++){
|
3005
|
+
printf("%02X", command->uuid[i]);
|
3006
|
+
}
|
3007
|
+
printf("\n");
|
3008
|
+
}
|
3009
|
+
|
3010
|
+
int process_lc_source_version(char *macho_str, long *offset){
|
3011
|
+
struct source_version_command command = {0};
|
3012
|
+
memcpy(&command, macho_str + *offset, sizeof(struct source_version_command));
|
3013
|
+
*offset += command.cmdsize;
|
3014
|
+
return 0;
|
3015
|
+
}
|
3016
|
+
int process_lc_version_min_macosx(char *macho_str, long *offset){
|
3017
|
+
struct version_min_command command = {0};
|
3018
|
+
memcpy(&command, macho_str + *offset, sizeof(struct version_min_command));
|
3019
|
+
*offset += command.cmdsize;
|
3020
|
+
return 0;
|
3021
|
+
}
|
3022
|
+
|
3023
|
+
int process_lc_version_min_iphoneos(char *macho_str, long *offset){
|
3024
|
+
struct version_min_command command = {0};
|
3025
|
+
memcpy(&command, macho_str + *offset, sizeof(struct version_min_command));
|
3026
|
+
*offset += command.cmdsize;
|
3027
|
+
return 0;
|
3028
|
+
}
|
3029
|
+
|
3030
|
+
int process_lc_dyld_info_only(char *macho_str, long *offset){
|
3031
|
+
struct dyld_info_command command = {0};
|
3032
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dyld_info_command));
|
3033
|
+
*offset += command.cmdsize;
|
3034
|
+
return 0;
|
3035
|
+
}
|
3036
|
+
|
3037
|
+
int process_lc_dyld_info(char *macho_str, long *offset){
|
3038
|
+
struct dyld_info_command command = {0};
|
3039
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dyld_info_command));
|
3040
|
+
*offset += command.cmdsize;
|
3041
|
+
return 0;
|
3042
|
+
}
|
3043
|
+
|
3044
|
+
int process_lc_data_in_code(char *macho_str, long *offset){
|
3045
|
+
struct lc_data_in_code command = {0};
|
3046
|
+
memcpy(&command, macho_str + *offset, sizeof(struct lc_data_in_code));
|
3047
|
+
*offset += command.cmdsize;
|
3048
|
+
return 0;
|
3049
|
+
}
|
3050
|
+
|
3051
|
+
int process_lc_function_starts(char *macho_str, long *offset){
|
3052
|
+
struct lc_function_starts command = {0};
|
3053
|
+
memcpy(&command, macho_str + *offset, sizeof(struct lc_function_starts));
|
3054
|
+
*offset += command.cmdsize;
|
3055
|
+
return 0;
|
3056
|
+
}
|
3057
|
+
|
3058
|
+
int process_lc_uuid(char *macho_str, long *offset, struct thin_macho*tm){
|
3059
|
+
struct uuid_command command = {0};
|
3060
|
+
memcpy(&command, macho_str + *offset, sizeof(struct uuid_command));
|
3061
|
+
//print_uuid(&command);
|
3062
|
+
*offset += command.cmdsize;
|
3063
|
+
int i = 0;
|
3064
|
+
while(i < 16){
|
3065
|
+
tm->uuid[i] = command.uuid[i];
|
3066
|
+
i++;
|
3067
|
+
}
|
3068
|
+
return 0;
|
3069
|
+
}
|
3070
|
+
|
3071
|
+
int process_lc_segment(char *macho_str, long *offset, struct thin_macho*tm){
|
3072
|
+
struct segment_command command = {0};
|
3073
|
+
|
3074
|
+
memcpy(&command, macho_str + *offset, sizeof(struct segment_command));
|
3075
|
+
*offset += sizeof(struct segment_command);
|
3076
|
+
//if(strcmp(command.segname, "__TEXT") == 0){
|
3077
|
+
// doi.text_vmaddr = command.vmaddr;
|
3078
|
+
//}
|
3079
|
+
if(strcmp(command.segname, "__DWARF") == 0){
|
3080
|
+
tm->dwarf2_per_objfile = parse_dwarf_segment(macho_str, *offset, &command);
|
3081
|
+
if (tm->dwarf2_per_objfile == NULL){
|
3082
|
+
return -1;
|
3083
|
+
}
|
3084
|
+
}
|
3085
|
+
//in case there are sections, we need to seek the file point to the next load command
|
3086
|
+
*offset += command.cmdsize - sizeof(struct segment_command);
|
3087
|
+
return 0;
|
3088
|
+
}
|
3089
|
+
|
3090
|
+
int process_lc_segment_64(char *macho_str, long *offset, struct thin_macho*tm){
|
3091
|
+
struct segment_command_64 command = {0};
|
3092
|
+
memcpy(&command, macho_str + *offset, sizeof(struct segment_command_64));
|
3093
|
+
*offset += sizeof(struct segment_command_64);
|
3094
|
+
//if(strcmp(command.segname, "__TEXT") == 0){
|
3095
|
+
// doi.text_vmaddr_64 = command.vmaddr;
|
3096
|
+
//}
|
3097
|
+
if(strcmp(command.segname, "__DWARF") == 0){
|
3098
|
+
tm->dwarf2_per_objfile = parse_dwarf_segment_64(macho_str, *offset, &command);
|
3099
|
+
if (tm->dwarf2_per_objfile == NULL){
|
3100
|
+
return -1;
|
3101
|
+
}
|
3102
|
+
}
|
3103
|
+
*offset += command.cmdsize - sizeof(struct segment_command_64);
|
3104
|
+
|
3105
|
+
return 0;
|
3106
|
+
}
|
3107
|
+
|
3108
|
+
int process_lc_sub_client(char *macho_str, long *offset){
|
3109
|
+
struct sub_client_command command = {0};
|
3110
|
+
memcpy(&command, macho_str + *offset, sizeof(struct sub_client_command));
|
3111
|
+
*offset += command.cmdsize;
|
3112
|
+
return 0;
|
3113
|
+
}
|
3114
|
+
|
3115
|
+
int process_lc_sub_library(char *macho_str, long *offset){
|
3116
|
+
struct sub_library_command command = {0};
|
3117
|
+
memcpy(&command, macho_str + *offset, sizeof(struct sub_library_command));
|
3118
|
+
*offset += command.cmdsize;
|
3119
|
+
return 0;
|
3120
|
+
}
|
3121
|
+
|
3122
|
+
int process_lc_sub_umbrella(char *macho_str, long *offset){
|
3123
|
+
struct sub_umbrella_command command = {0};
|
3124
|
+
memcpy(&command, macho_str + *offset, sizeof(struct sub_umbrella_command));
|
3125
|
+
*offset += command.cmdsize;
|
3126
|
+
return 0;
|
3127
|
+
}
|
3128
|
+
|
3129
|
+
int process_lc_sub_framework(char *macho_str, long *offset){
|
3130
|
+
struct sub_framework_command command = {0};
|
3131
|
+
memcpy(&command, macho_str + *offset, sizeof(struct sub_framework_command));
|
3132
|
+
*offset += command.cmdsize;
|
3133
|
+
return 0;
|
3134
|
+
}
|
3135
|
+
int process_lc_twolevel_hints(char *macho_str, long *offset){
|
3136
|
+
struct twolevel_hints_command command = {0};
|
3137
|
+
memcpy(&command, macho_str + *offset, sizeof(struct twolevel_hints_command));
|
3138
|
+
*offset += command.cmdsize;
|
3139
|
+
return 0;
|
3140
|
+
}
|
3141
|
+
|
3142
|
+
int process_lc_routines_64(char *macho_str, long *offset){
|
3143
|
+
struct routines_command_64 command = {0};
|
3144
|
+
memcpy(&command, macho_str + *offset, sizeof(struct routines_command_64));
|
3145
|
+
*offset += command.cmdsize;
|
3146
|
+
return 0;
|
3147
|
+
}
|
3148
|
+
|
3149
|
+
int process_lc_routines(char *macho_str, long *offset){
|
3150
|
+
struct routines_command command = {0};
|
3151
|
+
memcpy(&command, macho_str + *offset, sizeof(struct routines_command));
|
3152
|
+
*offset += command.cmdsize;
|
3153
|
+
return 0;
|
3154
|
+
}
|
3155
|
+
|
3156
|
+
int process_lc_id_dylinker(char *macho_str, long *offset){
|
3157
|
+
struct dylinker_command command = {0};
|
3158
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylinker_command));
|
3159
|
+
*offset += command.cmdsize;
|
3160
|
+
return 0;
|
3161
|
+
}
|
3162
|
+
int process_lc_load_dylinker(char *macho_str, long *offset){
|
3163
|
+
struct dylinker_command command = {0};
|
3164
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylinker_command));
|
3165
|
+
*offset += command.cmdsize;
|
3166
|
+
return 0;
|
3167
|
+
}
|
3168
|
+
int process_lc_prebound_dylib(char *macho_str, long *offset){
|
3169
|
+
struct prebound_dylib_command command = {0};
|
3170
|
+
memcpy(&command, macho_str + *offset, sizeof(struct prebound_dylib_command));
|
3171
|
+
*offset += command.cmdsize;
|
3172
|
+
return 0;
|
3173
|
+
}
|
3174
|
+
|
3175
|
+
int process_lc_reexport_dylib(char *macho_str, long *offset){
|
3176
|
+
struct prebound_dylib_command command = {0};
|
3177
|
+
memcpy(&command, macho_str + *offset, sizeof(struct prebound_dylib_command));
|
3178
|
+
*offset += command.cmdsize;
|
3179
|
+
return 0;
|
3180
|
+
}
|
3181
|
+
|
3182
|
+
int process_lc_id_dylib(char *macho_str, long *offset){
|
3183
|
+
struct dylib_command command = {0};
|
3184
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylib_command));
|
3185
|
+
*offset += command.cmdsize;
|
3186
|
+
return 0;
|
3187
|
+
}
|
3188
|
+
|
3189
|
+
int process_lc_load_dylib(char *macho_str, long *offset){
|
3190
|
+
struct dylib_command command = {0};
|
3191
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylib_command));
|
3192
|
+
*offset += command.cmdsize;
|
3193
|
+
return 0;
|
3194
|
+
}
|
3195
|
+
|
3196
|
+
int process_lc_thread(char *macho_str, long *offset){
|
3197
|
+
struct thread_command command = {0};
|
3198
|
+
memcpy(&command, macho_str + *offset, sizeof(struct thread_command));
|
3199
|
+
*offset += command.cmdsize;
|
3200
|
+
return 0;
|
3201
|
+
}
|
3202
|
+
|
3203
|
+
int process_lc_unixthread(char *macho_str, long *offset){
|
3204
|
+
struct thread_command command = {0};
|
3205
|
+
memcpy(&command, macho_str + *offset, sizeof(struct thread_command));
|
3206
|
+
*offset += command.cmdsize;
|
3207
|
+
return 0;
|
3208
|
+
}
|
3209
|
+
|
3210
|
+
int process_lc_dysymtab(char *macho_str, long *offset, struct thin_macho*tm){
|
3211
|
+
struct dysymtab_command command = {0};
|
3212
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dysymtab_command));
|
3213
|
+
tm->symbolInformation.firstGlobalSymbol = command.iextdefsym;
|
3214
|
+
tm->symbolInformation.numGlobalSymbols = command.nextdefsym;
|
3215
|
+
tm->symbolInformation.firstLocalSymbol = command.ilocalsym;
|
3216
|
+
tm->symbolInformation.numLocalSymbols = command.nlocalsym;
|
3217
|
+
*offset += command.cmdsize;
|
3218
|
+
return 0;
|
3219
|
+
}
|
3220
|
+
|
3221
|
+
int process_lc_symtab(char *macho_str, long *offset, struct thin_macho*tm){
|
3222
|
+
struct symtab_command command = {0};
|
3223
|
+
memcpy(&command, macho_str + *offset, sizeof(struct symtab_command));
|
3224
|
+
parse_lc_symtab(macho_str, &command, tm);
|
3225
|
+
*offset += command.cmdsize;
|
3226
|
+
return 0;
|
3227
|
+
}
|
3228
|
+
|
3229
|
+
int process_lc_symseg(char *macho_str, long *offset){
|
3230
|
+
struct symseg_command command = {0};
|
3231
|
+
memcpy(&command, macho_str + *offset, sizeof(struct symseg_command));
|
3232
|
+
*offset += command.cmdsize;
|
3233
|
+
return 0;
|
3234
|
+
}
|
3235
|
+
|
3236
|
+
int process_lc_loadfvmlib(char *macho_str, long *offset){
|
3237
|
+
struct fvmlib_command command = {0};
|
3238
|
+
memcpy(&command, macho_str + *offset, sizeof(struct fvmlib_command));
|
3239
|
+
*offset += command.cmdsize;
|
3240
|
+
return 0;
|
3241
|
+
}
|
3242
|
+
|
3243
|
+
int process_lc_idfvmlib(char *macho_str, long *offset){
|
3244
|
+
struct fvmlib_command command = {0};
|
3245
|
+
memcpy(&command, macho_str + *offset, sizeof(struct fvmlib_command));
|
3246
|
+
*offset += command.cmdsize;
|
3247
|
+
return 0;
|
3248
|
+
}
|
3249
|
+
int process_lc_ident(char *macho_str, long *offset){
|
3250
|
+
struct ident_command command = {0};
|
3251
|
+
memcpy(&command, macho_str + *offset, sizeof(struct ident_command));
|
3252
|
+
*offset += command.cmdsize;
|
3253
|
+
return 0;
|
3254
|
+
}
|
3255
|
+
int process_lc_fvmfile(char *macho_str, long *offset){
|
3256
|
+
struct fvmfile_command command = {0};
|
3257
|
+
memcpy(&command, macho_str + *offset, sizeof(struct fvmfile_command));
|
3258
|
+
*offset += command.cmdsize;
|
3259
|
+
return 0;
|
3260
|
+
}
|
3261
|
+
int process_lc_prepage(char *macho_str, long *offset){
|
3262
|
+
struct symtab_command command = {0};
|
3263
|
+
memcpy(&command, macho_str + *offset, sizeof(struct symtab_command));
|
3264
|
+
*offset += command.cmdsize;
|
3265
|
+
return 0;
|
3266
|
+
}
|
3267
|
+
|
3268
|
+
int process_lc_prebind_cksum(char *macho_str, long *offset){
|
3269
|
+
struct prebind_cksum_command command = {0};
|
3270
|
+
memcpy(&command, macho_str + *offset, sizeof(struct prebind_cksum_command));
|
3271
|
+
*offset += command.cmdsize;
|
3272
|
+
return 0;
|
3273
|
+
}
|
3274
|
+
int process_lc_load_weak_dylib(char *macho_str, long *offset){
|
3275
|
+
struct dylib_command command = {0};
|
3276
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylib_command));
|
3277
|
+
*offset += command.cmdsize;
|
3278
|
+
return 0;
|
3279
|
+
}
|
3280
|
+
int process_lc_rpath(char *macho_str, long *offset){
|
3281
|
+
struct rpath_command command = {0};
|
3282
|
+
memcpy(&command, macho_str + *offset, sizeof(struct rpath_command));
|
3283
|
+
*offset += command.cmdsize;
|
3284
|
+
return 0;
|
3285
|
+
}
|
3286
|
+
int process_lc_code_signature(char *macho_str, long *offset){
|
3287
|
+
struct linkedit_data_command command = {0};
|
3288
|
+
memcpy(&command, macho_str + *offset, sizeof(struct linkedit_data_command));
|
3289
|
+
*offset += command.cmdsize;
|
3290
|
+
return 0;
|
3291
|
+
}
|
3292
|
+
int process_lc_segment_split_info(char *macho_str, long *offset){
|
3293
|
+
struct linkedit_data_command command = {0};
|
3294
|
+
memcpy(&command, macho_str + *offset, sizeof(struct linkedit_data_command));
|
3295
|
+
*offset += command.cmdsize;
|
3296
|
+
return 0;
|
3297
|
+
}
|
3298
|
+
int process_lc_lazy_load_dylib(char *macho_str, long *offset){
|
3299
|
+
struct symtab_command command = {0};
|
3300
|
+
memcpy(&command, macho_str + *offset, sizeof(struct symtab_command));
|
3301
|
+
*offset += command.cmdsize;
|
3302
|
+
return 0;
|
3303
|
+
}
|
3304
|
+
int process_lc_encryption_info(char *macho_str, long *offset){
|
3305
|
+
struct encryption_info_command command = {0};
|
3306
|
+
memcpy(&command, macho_str + *offset, sizeof(struct encryption_info_command));
|
3307
|
+
*offset += command.cmdsize;
|
3308
|
+
return 0;
|
3309
|
+
}
|
3310
|
+
int process_lc_command(char *macho_str, long *offset){
|
3311
|
+
struct load_command command = {0};
|
3312
|
+
memcpy(&command, macho_str + *offset, sizeof(struct load_command));
|
3313
|
+
*offset += command.cmdsize;
|
3314
|
+
return 0;
|
3315
|
+
}
|
3316
|
+
int process_lc_dyld_environment(char *macho_str, long *offset){
|
3317
|
+
struct dylinker_command command = {0};
|
3318
|
+
memcpy(&command, macho_str + *offset, sizeof(struct dylinker_command));
|
3319
|
+
*offset += command.cmdsize;
|
3320
|
+
return 0;
|
3321
|
+
}
|
3322
|
+
int process_lc_main(char *macho_str, long *offset){
|
3323
|
+
struct entry_point_command command = {0};
|
3324
|
+
memcpy(&command, macho_str + *offset, sizeof(struct entry_point_command));
|
3325
|
+
*offset += command.cmdsize;
|
3326
|
+
return 0;
|
3327
|
+
}
|
3328
|
+
int process_lc_dylib_code_sign_drs(char *macho_str, long *offset){
|
3329
|
+
struct linkedit_data_command command = {0};
|
3330
|
+
memcpy(&command, macho_str + *offset, sizeof(struct linkedit_data_command));
|
3331
|
+
*offset += command.cmdsize;
|
3332
|
+
return 0;
|
3333
|
+
}
|