atosl 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }