atosl 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }