1 /**********************************************************************
2
3 addr2line.c -
4
5 $Author$
6
7 Copyright (C) 2010 Shinichiro Hamaji
8
9 **********************************************************************/
10
11 #if defined(__clang__)
12 #pragma clang diagnostic ignored "-Wpedantic"
13 #pragma clang diagnostic ignored "-Wgcc-compat"
14 #elif defined(__GNUC__)
15 #pragma GCC diagnostic ignored "-Wpedantic"
16 #endif
17
18 #include "ruby/config.h"
19 #include "ruby/defines.h"
20 #include "ruby/missing.h"
21 #include "addr2line.h"
22
23 #include <stdio.h>
24 #include <errno.h>
25
26 #ifdef HAVE_STDBOOL_H
27 #include <stdbool.h>
28 #else
29 #include "missing/stdbool.h"
30 #endif
31
32 #if defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)
33
34 #include <fcntl.h>
35 #include <limits.h>
36 #include <stdio.h>
37 #include <stdint.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sys/mman.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44
45 /* Make alloca work the best possible way. */
46 #ifdef __GNUC__
47 # ifndef alloca
48 # define alloca __builtin_alloca
49 # endif
50 #else
51 # ifdef HAVE_ALLOCA_H
52 # include <alloca.h>
53 # else
54 # ifdef _AIX
55 #pragma alloca
56 # else
57 # ifndef alloca /* predefined by HP cc +Olibcalls */
58 void *alloca();
59 # endif
60 # endif /* AIX */
61 # endif /* HAVE_ALLOCA_H */
62 #endif /* __GNUC__ */
63
64 #ifdef HAVE_DLADDR
65 # include <dlfcn.h>
66 #endif
67
68 #ifdef HAVE_MACH_O_LOADER_H
69 # include <mach-o/fat.h>
70 # include <mach-o/ldsyms.h>
71 # include <mach-o/loader.h>
72 # include <mach-o/nlist.h>
73 # include <mach-o/stab.h>
74 #endif
75
76 #ifdef USE_ELF
77 # ifdef __OpenBSD__
78 # include <elf_abi.h>
79 # else
80 # include <elf.h>
81 # endif
82
83 #ifndef ElfW
84 # if SIZEOF_VOIDP == 8
85 # define ElfW(x) Elf64##_##x
86 # else
87 # define ElfW(x) Elf32##_##x
88 # endif
89 #endif
90 #ifndef ELF_ST_TYPE
91 # if SIZEOF_VOIDP == 8
92 # define ELF_ST_TYPE ELF64_ST_TYPE
93 # else
94 # define ELF_ST_TYPE ELF32_ST_TYPE
95 # endif
96 #endif
97 #endif
98
99 #ifdef SHF_COMPRESSED
100 # if defined(ELFCOMPRESS_ZLIB) && defined(HAVE_LIBZ)
101 /* FreeBSD 11.0 lacks ELFCOMPRESS_ZLIB */
102 # include <zlib.h>
103 # define SUPPORT_COMPRESSED_DEBUG_LINE
104 # endif
105 #else /* compatibility with glibc < 2.22 */
106 # define SHF_COMPRESSED 0
107 #endif
108
109 #ifndef PATH_MAX
110 #define PATH_MAX 4096
111 #endif
112
113 #define DW_LNS_copy 0x01
114 #define DW_LNS_advance_pc 0x02
115 #define DW_LNS_advance_line 0x03
116 #define DW_LNS_set_file 0x04
117 #define DW_LNS_set_column 0x05
118 #define DW_LNS_negate_stmt 0x06
119 #define DW_LNS_set_basic_block 0x07
120 #define DW_LNS_const_add_pc 0x08
121 #define DW_LNS_fixed_advance_pc 0x09
122 #define DW_LNS_set_prologue_end 0x0a /* DWARF3 */
123 #define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */
124 #define DW_LNS_set_isa 0x0c /* DWARF3 */
125
126 /* Line number extended opcode name. */
127 #define DW_LNE_end_sequence 0x01
128 #define DW_LNE_set_address 0x02
129 #define DW_LNE_define_file 0x03
130 #define DW_LNE_set_discriminator 0x04 /* DWARF4 */
131
132 PRINTF_ARGS(static int kprintf(const char *fmt, ...), 1, 2);
133
134 typedef struct line_info {
135 const char *dirname;
136 const char *filename;
137 const char *path; /* object path */
138 int line;
139
140 uintptr_t base_addr;
141 uintptr_t saddr;
142 const char *sname; /* function name */
143
144 struct line_info *next;
145 } line_info_t;
146
147 struct dwarf_section {
148 char *ptr;
149 size_t size;
150 uint64_t flags;
151 };
152
153 typedef struct obj_info {
154 const char *path; /* object path */
155 char *mapped;
156 size_t mapped_size;
157 void *uncompressed;
158 uintptr_t base_addr;
159 uintptr_t vmaddr;
160 struct dwarf_section debug_abbrev;
161 struct dwarf_section debug_info;
162 struct dwarf_section debug_line;
163 struct dwarf_section debug_ranges;
164 struct dwarf_section debug_str;
165 struct obj_info *next;
166 } obj_info_t;
167
168 #define DWARF_SECTION_COUNT 5
169
170 static struct dwarf_section *
obj_dwarf_section_at(obj_info_t * obj,int n)171 obj_dwarf_section_at(obj_info_t *obj, int n)
172 {
173 struct dwarf_section *ary[] = {
174 &obj->debug_abbrev,
175 &obj->debug_info,
176 &obj->debug_line,
177 &obj->debug_ranges,
178 &obj->debug_str
179 };
180 if (n < 0 || DWARF_SECTION_COUNT <= n) {
181 abort();
182 }
183 return ary[n];
184 }
185
186 struct debug_section_definition {
187 const char *name;
188 struct dwarf_section *dwarf;
189 };
190
191 /* Avoid consuming stack as this module may be used from signal handler */
192 static char binary_filename[PATH_MAX];
193
194 static unsigned long
uleb128(char ** p)195 uleb128(char **p)
196 {
197 unsigned long r = 0;
198 int s = 0;
199 for (;;) {
200 unsigned char b = *(unsigned char *)(*p)++;
201 if (b < 0x80) {
202 r += (unsigned long)b << s;
203 break;
204 }
205 r += (b & 0x7f) << s;
206 s += 7;
207 }
208 return r;
209 }
210
211 static long
sleb128(char ** p)212 sleb128(char **p)
213 {
214 long r = 0;
215 int s = 0;
216 for (;;) {
217 unsigned char b = *(unsigned char *)(*p)++;
218 if (b < 0x80) {
219 if (b & 0x40) {
220 r -= (0x80 - b) << s;
221 }
222 else {
223 r += (b & 0x3f) << s;
224 }
225 break;
226 }
227 r += (b & 0x7f) << s;
228 s += 7;
229 }
230 return r;
231 }
232
233 static const char *
get_nth_dirname(unsigned long dir,char * p)234 get_nth_dirname(unsigned long dir, char *p)
235 {
236 if (!dir--) {
237 return "";
238 }
239 while (dir--) {
240 while (*p) p++;
241 p++;
242 if (!*p) {
243 kprintf("Unexpected directory number %lu in %s\n",
244 dir, binary_filename);
245 return "";
246 }
247 }
248 return p;
249 }
250
251 static void
fill_filename(int file,char * include_directories,char * filenames,line_info_t * line,obj_info_t * obj)252 fill_filename(int file, char *include_directories, char *filenames, line_info_t *line, obj_info_t *obj)
253 {
254 int i;
255 char *p = filenames;
256 char *filename;
257 unsigned long dir;
258 for (i = 1; i <= file; i++) {
259 filename = p;
260 if (!*p) {
261 /* Need to output binary file name? */
262 kprintf("Unexpected file number %d in %s at %tx\n",
263 file, binary_filename, filenames - obj->mapped);
264 return;
265 }
266 while (*p) p++;
267 p++;
268 dir = uleb128(&p);
269 /* last modified. */
270 uleb128(&p);
271 /* size of the file. */
272 uleb128(&p);
273
274 if (i == file) {
275 line->filename = filename;
276 line->dirname = get_nth_dirname(dir, include_directories);
277 }
278 }
279 }
280
281 static void
fill_line(int num_traces,void ** traces,uintptr_t addr,int file,int line,char * include_directories,char * filenames,obj_info_t * obj,line_info_t * lines,int offset)282 fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
283 char *include_directories, char *filenames,
284 obj_info_t *obj, line_info_t *lines, int offset)
285 {
286 int i;
287 addr += obj->base_addr - obj->vmaddr;
288 for (i = offset; i < num_traces; i++) {
289 uintptr_t a = (uintptr_t)traces[i];
290 /* We assume one line code doesn't result >100 bytes of native code.
291 We may want more reliable way eventually... */
292 if (addr < a && a < addr + 100) {
293 fill_filename(file, include_directories, filenames, &lines[i], obj);
294 lines[i].line = line;
295 }
296 }
297 }
298
299 struct LineNumberProgramHeader {
300 uint64_t unit_length;
301 uint16_t version;
302 uint8_t format; /* 4 or 8 */
303 uint64_t header_length;
304 uint8_t minimum_instruction_length;
305 uint8_t maximum_operations_per_instruction;
306 uint8_t default_is_stmt;
307 int8_t line_base;
308 uint8_t line_range;
309 uint8_t opcode_base;
310 /* uint8_t standard_opcode_lengths[opcode_base-1]; */
311 const char *include_directories;
312 const char *filenames;
313 const char *cu_start;
314 const char *cu_end;
315 };
316
317 static int
parse_debug_line_header(const char ** pp,struct LineNumberProgramHeader * header)318 parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
319 {
320 const char *p = *pp;
321 header->unit_length = *(uint32_t *)p;
322 p += sizeof(uint32_t);
323
324 header->format = 4;
325 if (header->unit_length == 0xffffffff) {
326 header->unit_length = *(uint64_t *)p;
327 p += sizeof(uint64_t);
328 header->format = 8;
329 }
330
331 header->cu_end = p + header->unit_length;
332
333 header->version = *(uint16_t *)p;
334 p += sizeof(uint16_t);
335 if (header->version > 4) return -1;
336
337 header->header_length = header->format == 4 ? *(uint32_t *)p : *(uint64_t *)p;
338 p += header->format;
339 header->cu_start = p + header->header_length;
340
341 header->minimum_instruction_length = *(uint8_t *)p++;
342
343 if (header->version >= 4) {
344 /* maximum_operations_per_instruction = *(uint8_t *)p; */
345 if (*p != 1) return -1; /* For non-VLIW architectures, this field is 1 */
346 p++;
347 }
348
349 header->default_is_stmt = *(uint8_t *)p++;
350 header->line_base = *(int8_t *)p++;
351 header->line_range = *(uint8_t *)p++;
352 header->opcode_base = *(uint8_t *)p++;
353 /* header->standard_opcode_lengths = (uint8_t *)p - 1; */
354 p += header->opcode_base - 1;
355
356 header->include_directories = p;
357
358 /* temporary measure for compress-debug-sections */
359 if (p >= header->cu_end) return -1;
360
361 /* skip include directories */
362 while (*p) {
363 p = memchr(p, '\0', header->cu_end - p);
364 if (!p) return -1;
365 p++;
366 }
367 p++;
368
369 header->filenames = p;
370
371 *pp = header->cu_start;
372
373 return 0;
374 }
375
376 static int
parse_debug_line_cu(int num_traces,void ** traces,char ** debug_line,obj_info_t * obj,line_info_t * lines,int offset)377 parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
378 obj_info_t *obj, line_info_t *lines, int offset)
379 {
380 const char *p = (const char *)*debug_line;
381 struct LineNumberProgramHeader header;
382
383 /* The registers. */
384 unsigned long addr = 0;
385 unsigned int file = 1;
386 unsigned int line = 1;
387 /* unsigned int column = 0; */
388 int is_stmt;
389 /* int basic_block = 0; */
390 /* int end_sequence = 0; */
391 /* int prologue_end = 0; */
392 /* int epilogue_begin = 0; */
393 /* unsigned int isa = 0; */
394
395 if (parse_debug_line_header(&p, &header))
396 return -1;
397 is_stmt = header.default_is_stmt;
398
399 #define FILL_LINE() \
400 do { \
401 fill_line(num_traces, traces, addr, file, line, \
402 (char *)header.include_directories, \
403 (char *)header.filenames, \
404 obj, lines, offset); \
405 /*basic_block = prologue_end = epilogue_begin = 0;*/ \
406 } while (0)
407
408 while (p < header.cu_end) {
409 unsigned long a;
410 unsigned char op = *p++;
411 switch (op) {
412 case DW_LNS_copy:
413 FILL_LINE();
414 break;
415 case DW_LNS_advance_pc:
416 a = uleb128((char **)&p);
417 addr += a;
418 break;
419 case DW_LNS_advance_line: {
420 long a = sleb128((char **)&p);
421 line += a;
422 break;
423 }
424 case DW_LNS_set_file:
425 file = (unsigned int)uleb128((char **)&p);
426 break;
427 case DW_LNS_set_column:
428 /*column = (unsigned int)*/(void)uleb128((char **)&p);
429 break;
430 case DW_LNS_negate_stmt:
431 is_stmt = !is_stmt;
432 break;
433 case DW_LNS_set_basic_block:
434 /*basic_block = 1; */
435 break;
436 case DW_LNS_const_add_pc:
437 a = ((255 - header.opcode_base) / header.line_range) *
438 header.minimum_instruction_length;
439 addr += a;
440 break;
441 case DW_LNS_fixed_advance_pc:
442 a = *(unsigned char *)p++;
443 addr += a;
444 break;
445 case DW_LNS_set_prologue_end:
446 /* prologue_end = 1; */
447 break;
448 case DW_LNS_set_epilogue_begin:
449 /* epilogue_begin = 1; */
450 break;
451 case DW_LNS_set_isa:
452 /* isa = (unsigned int)*/(void)uleb128((char **)&p);
453 break;
454 case 0:
455 a = *(unsigned char *)p++;
456 op = *p++;
457 switch (op) {
458 case DW_LNE_end_sequence:
459 /* end_sequence = 1; */
460 FILL_LINE();
461 addr = 0;
462 file = 1;
463 line = 1;
464 /* column = 0; */
465 is_stmt = header.default_is_stmt;
466 /* end_sequence = 0; */
467 /* isa = 0; */
468 break;
469 case DW_LNE_set_address:
470 addr = *(unsigned long *)p;
471 p += sizeof(unsigned long);
472 break;
473 case DW_LNE_define_file:
474 kprintf("Unsupported operation in %s\n",
475 binary_filename);
476 break;
477 case DW_LNE_set_discriminator:
478 /* TODO:currently ignore */
479 uleb128((char **)&p);
480 break;
481 default:
482 kprintf("Unknown extended opcode: %d in %s\n",
483 op, binary_filename);
484 }
485 break;
486 default: {
487 uint8_t adjusted_opcode = op - header.opcode_base;
488 uint8_t operation_advance = adjusted_opcode / header.line_range;
489 /* NOTE: this code doesn't support VLIW */
490 addr += operation_advance * header.minimum_instruction_length;
491 line += header.line_base + (adjusted_opcode % header.line_range);
492 FILL_LINE();
493 }
494 }
495 }
496 *debug_line = (char *)p;
497 return 0;
498 }
499
500 static int
parse_debug_line(int num_traces,void ** traces,char * debug_line,unsigned long size,obj_info_t * obj,line_info_t * lines,int offset)501 parse_debug_line(int num_traces, void **traces,
502 char *debug_line, unsigned long size,
503 obj_info_t *obj, line_info_t *lines, int offset)
504 {
505 char *debug_line_end = debug_line + size;
506 while (debug_line < debug_line_end) {
507 if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
508 return -1;
509 }
510 if (debug_line != debug_line_end) {
511 kprintf("Unexpected size of .debug_line in %s\n",
512 binary_filename);
513 }
514 return 0;
515 }
516
517 /* read file and fill lines */
518 static uintptr_t
519 fill_lines(int num_traces, void **traces, int check_debuglink,
520 obj_info_t **objp, line_info_t *lines, int offset);
521
522 static void
append_obj(obj_info_t ** objp)523 append_obj(obj_info_t **objp)
524 {
525 obj_info_t *newobj = calloc(1, sizeof(obj_info_t));
526 if (*objp) (*objp)->next = newobj;
527 *objp = newobj;
528 }
529
530 #ifdef USE_ELF
531 static void
follow_debuglink(const char * debuglink,int num_traces,void ** traces,obj_info_t ** objp,line_info_t * lines,int offset)532 follow_debuglink(const char *debuglink, int num_traces, void **traces,
533 obj_info_t **objp, line_info_t *lines, int offset)
534 {
535 /* Ideally we should check 4 paths to follow gnu_debuglink,
536 but we handle only one case for now as this format is used
537 by some linux distributions. See GDB's info for detail. */
538 static const char global_debug_dir[] = "/usr/lib/debug";
539 const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
540 char *p;
541 obj_info_t *o1 = *objp, *o2;
542 size_t len;
543
544 p = strrchr(binary_filename, '/');
545 if (!p) {
546 return;
547 }
548 p[1] = '\0';
549
550 len = strlen(binary_filename);
551 if (len >= PATH_MAX - global_debug_dir_len)
552 len = PATH_MAX - global_debug_dir_len - 1;
553 memmove(binary_filename + global_debug_dir_len, binary_filename, len);
554 memcpy(binary_filename, global_debug_dir, global_debug_dir_len);
555 len += global_debug_dir_len;
556 strlcpy(binary_filename + len, debuglink, PATH_MAX - len);
557
558 append_obj(objp);
559 o2 = *objp;
560 o2->base_addr = o1->base_addr;
561 o2->path = o1->path;
562 fill_lines(num_traces, traces, 0, objp, lines, offset);
563 }
564 #endif
565
566 enum
567 {
568 DW_TAG_compile_unit = 0x11,
569 DW_TAG_inlined_subroutine = 0x1d,
570 DW_TAG_subprogram = 0x2e,
571 };
572
573 /* Attributes encodings */
574 enum
575 {
576 DW_AT_sibling = 0x01,
577 DW_AT_location = 0x02,
578 DW_AT_name = 0x03,
579 /* Reserved 0x04 */
580 /* Reserved 0x05 */
581 /* Reserved 0x06 */
582 /* Reserved 0x07 */
583 /* Reserved 0x08 */
584 DW_AT_ordering = 0x09,
585 /* Reserved 0x0a */
586 DW_AT_byte_size = 0x0b,
587 /* Reserved 0x0c */
588 DW_AT_bit_size = 0x0d,
589 /* Reserved 0x0e */
590 /* Reserved 0x0f */
591 DW_AT_stmt_list = 0x10,
592 DW_AT_low_pc = 0x11,
593 DW_AT_high_pc = 0x12,
594 DW_AT_language = 0x13,
595 /* Reserved 0x14 */
596 DW_AT_discr = 0x15,
597 DW_AT_discr_value = 0x16,
598 DW_AT_visibility = 0x17,
599 DW_AT_import = 0x18,
600 DW_AT_string_length = 0x19,
601 DW_AT_common_reference = 0x1a,
602 DW_AT_comp_dir = 0x1b,
603 DW_AT_const_value = 0x1c,
604 DW_AT_containing_type = 0x1d,
605 DW_AT_default_value = 0x1e,
606 /* Reserved 0x1f */
607 DW_AT_inline = 0x20,
608 DW_AT_is_optional = 0x21,
609 DW_AT_lower_bound = 0x22,
610 /* Reserved 0x23 */
611 /* Reserved 0x24 */
612 DW_AT_producer = 0x25,
613 /* Reserved 0x26 */
614 DW_AT_prototyped = 0x27,
615 /* Reserved 0x28 */
616 /* Reserved 0x29 */
617 DW_AT_return_addr = 0x2a,
618 /* Reserved 0x2b */
619 DW_AT_start_scope = 0x2c,
620 /* Reserved 0x2d */
621 DW_AT_bit_stride = 0x2e,
622 DW_AT_upper_bound = 0x2f,
623 /* Reserved 0x30 */
624 DW_AT_abstract_origin = 0x31,
625 DW_AT_accessibility = 0x32,
626 DW_AT_address_class = 0x33,
627 DW_AT_artificial = 0x34,
628 DW_AT_base_types = 0x35,
629 DW_AT_calling_convention = 0x36,
630 DW_AT_count = 0x37,
631 DW_AT_data_member_location = 0x38,
632 DW_AT_decl_column = 0x39,
633 DW_AT_decl_file = 0x3a,
634 DW_AT_decl_line = 0x3b,
635 DW_AT_declaration = 0x3c,
636 DW_AT_discr_list = 0x3d,
637 DW_AT_encoding = 0x3e,
638 DW_AT_external = 0x3f,
639 DW_AT_frame_base = 0x40,
640 DW_AT_friend = 0x41,
641 DW_AT_identifier_case = 0x42,
642 /* Reserved 0x43 */
643 DW_AT_namelist_item = 0x44,
644 DW_AT_priority = 0x45,
645 DW_AT_segment = 0x46,
646 DW_AT_specification = 0x47,
647 DW_AT_static_link = 0x48,
648 DW_AT_type = 0x49,
649 DW_AT_use_location = 0x4a,
650 DW_AT_variable_parameter = 0x4b,
651 DW_AT_virtuality = 0x4c,
652 DW_AT_vtable_elem_location = 0x4d,
653 DW_AT_allocated = 0x4e,
654 DW_AT_associated = 0x4f,
655 DW_AT_data_location = 0x50,
656 DW_AT_byte_stride = 0x51,
657 DW_AT_entry_pc = 0x52,
658 DW_AT_use_UTF8 = 0x53,
659 DW_AT_extension = 0x54,
660 DW_AT_ranges = 0x55,
661 DW_AT_trampoline = 0x56,
662 DW_AT_call_column = 0x57,
663 DW_AT_call_file = 0x58,
664 DW_AT_call_line = 0x59,
665 DW_AT_description = 0x5a,
666 DW_AT_binary_scale = 0x5b,
667 DW_AT_decimal_scale = 0x5c,
668 DW_AT_small = 0x5d,
669 DW_AT_decimal_sign = 0x5e,
670 DW_AT_digit_count = 0x5f,
671 DW_AT_picture_string = 0x60,
672 DW_AT_mutable = 0x61,
673 DW_AT_threads_scaled = 0x62,
674 DW_AT_explicit = 0x63,
675 DW_AT_object_pointer = 0x64,
676 DW_AT_endianity = 0x65,
677 DW_AT_elemental = 0x66,
678 DW_AT_pure = 0x67,
679 DW_AT_recursive = 0x68,
680 DW_AT_signature = 0x69,
681 DW_AT_main_subprogram = 0x6a,
682 DW_AT_data_bit_offset = 0x6b,
683 DW_AT_const_expr = 0x6c,
684 DW_AT_enum_class = 0x6d,
685 DW_AT_linkage_name = 0x6e,
686 DW_AT_string_length_bit_size = 0x6f,
687 DW_AT_string_length_byte_size = 0x70,
688 DW_AT_rank = 0x71,
689 DW_AT_str_offsets_base = 0x72,
690 DW_AT_addr_base = 0x73,
691 DW_AT_rnglists_base = 0x74,
692 /* Reserved 0x75 */
693 DW_AT_dwo_name = 0x76,
694 DW_AT_reference = 0x77,
695 DW_AT_rvalue_reference = 0x78,
696 DW_AT_macros = 0x79,
697 DW_AT_call_all_calls = 0x7a,
698 DW_AT_call_all_source_calls = 0x7b,
699 DW_AT_call_all_tail_calls = 0x7c,
700 DW_AT_call_return_pc = 0x7d,
701 DW_AT_call_value = 0x7e,
702 DW_AT_call_origin = 0x7f,
703 DW_AT_call_parameter = 0x80,
704 DW_AT_call_pc = 0x81,
705 DW_AT_call_tail_call = 0x82,
706 DW_AT_call_target = 0x83,
707 DW_AT_call_target_clobbered = 0x84,
708 DW_AT_call_data_location = 0x85,
709 DW_AT_call_data_value = 0x86,
710 DW_AT_noreturn = 0x87,
711 DW_AT_alignment = 0x88,
712 DW_AT_export_symbols = 0x89,
713 DW_AT_deleted = 0x8a,
714 DW_AT_defaulted = 0x8b,
715 DW_AT_loclists_base = 0x8c,
716 DW_AT_lo_user = 0x2000,
717 DW_AT_hi_user = 0x3fff
718 };
719
720 /* Attribute form encodings */
721 enum
722 {
723 DW_FORM_addr = 0x01,
724 /* Reserved 0x02 */
725 DW_FORM_block2 = 0x03,
726 DW_FORM_block4 = 0x04,
727 DW_FORM_data2 = 0x05,
728 DW_FORM_data4 = 0x06,
729 DW_FORM_data8 = 0x07,
730 DW_FORM_string = 0x08,
731 DW_FORM_block = 0x09,
732 DW_FORM_block1 = 0x0a,
733 DW_FORM_data1 = 0x0b,
734 DW_FORM_flag = 0x0c,
735 DW_FORM_sdata = 0x0d,
736 DW_FORM_strp = 0x0e,
737 DW_FORM_udata = 0x0f,
738 DW_FORM_ref_addr = 0x10,
739 DW_FORM_ref1 = 0x11,
740 DW_FORM_ref2 = 0x12,
741 DW_FORM_ref4 = 0x13,
742 DW_FORM_ref8 = 0x14,
743 DW_FORM_ref_udata = 0x15,
744 DW_FORM_indirect = 0x16,
745 DW_FORM_sec_offset = 0x17,
746 DW_FORM_exprloc = 0x18,
747 DW_FORM_flag_present = 0x19,
748 DW_FORM_strx = 0x1a,
749 DW_FORM_addrx = 0x1b,
750 DW_FORM_ref_sup4 = 0x1c,
751 DW_FORM_strp_sup = 0x1d,
752 DW_FORM_data16 = 0x1e,
753 DW_FORM_line_strp = 0x1f,
754 DW_FORM_ref_sig8 = 0x20,
755 DW_FORM_implicit_const = 0x21,
756 DW_FORM_loclistx = 0x22,
757 DW_FORM_rnglistx = 0x23,
758 DW_FORM_ref_sup8 = 0x24,
759 DW_FORM_strx1 = 0x25,
760 DW_FORM_strx2 = 0x26,
761 DW_FORM_strx3 = 0x27,
762 DW_FORM_strx4 = 0x28,
763 DW_FORM_addrx1 = 0x29,
764 DW_FORM_addrx2 = 0x2a,
765 DW_FORM_addrx3 = 0x2b,
766 DW_FORM_addrx4 = 0x2c
767 };
768
769 enum {
770 VAL_none = 0,
771 VAL_cstr = 1,
772 VAL_data = 2,
773 VAL_uint = 3,
774 VAL_int = 4
775 };
776
777 # define ABBREV_TABLE_SIZE 256
778 typedef struct {
779 obj_info_t *obj;
780 char *file;
781 char *current_cu;
782 uint64_t current_low_pc;
783 char *debug_line_cu_end;
784 char *debug_line_files;
785 char *debug_line_directories;
786 char *p;
787 char *cu_end;
788 char *pend;
789 char *q0;
790 char *q;
791 int format; /* 4 or 8 */;
792 uint8_t address_size;
793 int level;
794 char *abbrev_table[ABBREV_TABLE_SIZE];
795 } DebugInfoReader;
796
797 typedef struct {
798 ptrdiff_t pos;
799 int tag;
800 int has_children;
801 } DIE;
802
803 typedef struct {
804 union {
805 char *ptr;
806 uint64_t uint64;
807 int64_t int64;
808 } as;
809 uint64_t off;
810 uint64_t at;
811 uint64_t form;
812 size_t size;
813 int type;
814 } DebugInfoValue;
815
816 /* TODO: Big Endian */
817 #define MERGE_2INTS(a,b,sz) (((uint64_t)(b)<<sz)|(a))
818
819 static uint16_t
get_uint16(const uint8_t * p)820 get_uint16(const uint8_t *p)
821 {
822 return (uint16_t)MERGE_2INTS(p[0],p[1],8);
823 }
824
825 static uint32_t
get_uint32(const uint8_t * p)826 get_uint32(const uint8_t *p)
827 {
828 return (uint32_t)MERGE_2INTS(get_uint16(p),get_uint16(p+2),16);
829 }
830
831 static uint64_t
get_uint64(const uint8_t * p)832 get_uint64(const uint8_t *p)
833 {
834 return MERGE_2INTS(get_uint32(p),get_uint32(p+4),32);
835 }
836
837 static uint8_t
read_uint8(char ** ptr)838 read_uint8(char **ptr)
839 {
840 const unsigned char *p = (const unsigned char *)*ptr;
841 *ptr = (char *)(p + 1);
842 return *p;
843 }
844
845 static uint16_t
read_uint16(char ** ptr)846 read_uint16(char **ptr)
847 {
848 const unsigned char *p = (const unsigned char *)*ptr;
849 *ptr = (char *)(p + 2);
850 return get_uint16(p);
851 }
852
853 static uint32_t
read_uint24(char ** ptr)854 read_uint24(char **ptr)
855 {
856 const unsigned char *p = (const unsigned char *)*ptr;
857 *ptr = (char *)(p + 3);
858 return (*p << 16) | get_uint16(p+1);
859 }
860
861 static uint32_t
read_uint32(char ** ptr)862 read_uint32(char **ptr)
863 {
864 const unsigned char *p = (const unsigned char *)*ptr;
865 *ptr = (char *)(p + 4);
866 return get_uint32(p);
867 }
868
869 static uint64_t
read_uint64(char ** ptr)870 read_uint64(char **ptr)
871 {
872 const unsigned char *p = (const unsigned char *)*ptr;
873 *ptr = (char *)(p + 8);
874 return get_uint64(p);
875 }
876
877 static uintptr_t
read_uintptr(char ** ptr)878 read_uintptr(char **ptr)
879 {
880 const unsigned char *p = (const unsigned char *)*ptr;
881 *ptr = (char *)(p + SIZEOF_VOIDP);
882 #if SIZEOF_VOIDP == 8
883 return get_uint64(p);
884 #else
885 return get_uint32(p);
886 #endif
887 }
888
889 static uint64_t
read_uint(DebugInfoReader * reader)890 read_uint(DebugInfoReader *reader)
891 {
892 if (reader->format == 4) {
893 return read_uint32(&reader->p);
894 } else { /* 64 bit */
895 return read_uint64(&reader->p);
896 }
897 }
898
899 static uint64_t
read_uleb128(DebugInfoReader * reader)900 read_uleb128(DebugInfoReader *reader)
901 {
902 return uleb128(&reader->p);
903 }
904
905 static int64_t
read_sleb128(DebugInfoReader * reader)906 read_sleb128(DebugInfoReader *reader)
907 {
908 return sleb128(&reader->p);
909 }
910
911 static void
debug_info_reader_init(DebugInfoReader * reader,obj_info_t * obj)912 debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
913 {
914 reader->file = obj->mapped;
915 reader->obj = obj;
916 reader->p = obj->debug_info.ptr;
917 reader->pend = obj->debug_info.ptr + obj->debug_info.size;
918 reader->debug_line_cu_end = obj->debug_line.ptr;
919 }
920
921 static void
di_read_debug_abbrev_cu(DebugInfoReader * reader)922 di_read_debug_abbrev_cu(DebugInfoReader *reader)
923 {
924 uint64_t prev = 0;
925 char *p = reader->q0;
926 for (;;) {
927 uint64_t abbrev_number = uleb128(&p);
928 if (abbrev_number <= prev) break;
929 if (abbrev_number < ABBREV_TABLE_SIZE) {
930 reader->abbrev_table[abbrev_number] = p;
931 }
932 prev = abbrev_number;
933 uleb128(&p); /* tag */
934 p++; /* has_children */
935 /* skip content */
936 for (;;) {
937 uint64_t at = uleb128(&p);
938 uint64_t form = uleb128(&p);
939 if (!at && !form) break;
940 }
941 }
942 }
943
944 static int
di_read_debug_line_cu(DebugInfoReader * reader)945 di_read_debug_line_cu(DebugInfoReader *reader)
946 {
947 const char *p;
948 struct LineNumberProgramHeader header;
949
950 p = (const char *)reader->debug_line_cu_end;
951 if (parse_debug_line_header(&p, &header))
952 return -1;
953
954 reader->debug_line_cu_end = (char *)header.cu_end;
955 reader->debug_line_directories = (char *)header.include_directories;
956 reader->debug_line_files = (char *)header.filenames;
957
958 return 0;
959 }
960
961 static void
set_uint_value(DebugInfoValue * v,uint64_t n)962 set_uint_value(DebugInfoValue *v, uint64_t n)
963 {
964 v->as.uint64 = n;
965 v->type = VAL_uint;
966 }
967
968 static void
set_int_value(DebugInfoValue * v,int64_t n)969 set_int_value(DebugInfoValue *v, int64_t n)
970 {
971 v->as.int64 = n;
972 v->type = VAL_int;
973 }
974
975 static void
set_cstr_value(DebugInfoValue * v,char * s)976 set_cstr_value(DebugInfoValue *v, char *s)
977 {
978 v->as.ptr = s;
979 v->off = 0;
980 v->type = VAL_cstr;
981 }
982
983 static void
set_cstrp_value(DebugInfoValue * v,char * s,uint64_t off)984 set_cstrp_value(DebugInfoValue *v, char *s, uint64_t off)
985 {
986 v->as.ptr = s;
987 v->off = off;
988 v->type = VAL_cstr;
989 }
990
991 static void
set_data_value(DebugInfoValue * v,char * s)992 set_data_value(DebugInfoValue *v, char *s)
993 {
994 v->as.ptr = s;
995 v->type = VAL_data;
996 }
997
998 static const char *
get_cstr_value(DebugInfoValue * v)999 get_cstr_value(DebugInfoValue *v)
1000 {
1001 if (v->as.ptr) {
1002 return v->as.ptr + v->off;
1003 } else {
1004 return NULL;
1005 }
1006 }
1007
1008 static void
debug_info_reader_read_value(DebugInfoReader * reader,uint64_t form,DebugInfoValue * v)1009 debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
1010 {
1011 switch (form) {
1012 case DW_FORM_addr:
1013 if (reader->address_size == 4) {
1014 set_uint_value(v, read_uint32(&reader->p));
1015 } else if (reader->address_size == 8) {
1016 set_uint_value(v, read_uint64(&reader->p));
1017 } else {
1018 fprintf(stderr,"unknown address_size:%d", reader->address_size);
1019 abort();
1020 }
1021 break;
1022 case DW_FORM_block2:
1023 v->size = read_uint16(&reader->p);
1024 set_data_value(v, reader->p);
1025 reader->p += v->size;
1026 break;
1027 case DW_FORM_block4:
1028 v->size = read_uint32(&reader->p);
1029 set_data_value(v, reader->p);
1030 reader->p += v->size;
1031 break;
1032 case DW_FORM_data2:
1033 set_uint_value(v, read_uint16(&reader->p));
1034 break;
1035 case DW_FORM_data4:
1036 set_uint_value(v, read_uint32(&reader->p));
1037 break;
1038 case DW_FORM_data8:
1039 set_uint_value(v, read_uint64(&reader->p));
1040 break;
1041 case DW_FORM_string:
1042 v->size = strlen(reader->p);
1043 set_cstr_value(v, reader->p);
1044 reader->p += v->size + 1;
1045 break;
1046 case DW_FORM_block:
1047 v->size = uleb128(&reader->p);
1048 set_data_value(v, reader->p);
1049 reader->p += v->size;
1050 break;
1051 case DW_FORM_block1:
1052 v->size = read_uint8(&reader->p);
1053 set_data_value(v, reader->p);
1054 reader->p += v->size;
1055 break;
1056 case DW_FORM_data1:
1057 set_uint_value(v, read_uint8(&reader->p));
1058 break;
1059 case DW_FORM_flag:
1060 set_uint_value(v, read_uint8(&reader->p));
1061 break;
1062 case DW_FORM_sdata:
1063 set_int_value(v, read_sleb128(reader));
1064 break;
1065 case DW_FORM_strp:
1066 set_cstrp_value(v, reader->obj->debug_str.ptr, read_uint(reader));
1067 break;
1068 case DW_FORM_udata:
1069 set_uint_value(v, read_uleb128(reader));
1070 break;
1071 case DW_FORM_ref_addr:
1072 if (reader->address_size == 4) {
1073 set_uint_value(v, read_uint32(&reader->p));
1074 } else if (reader->address_size == 8) {
1075 set_uint_value(v, read_uint64(&reader->p));
1076 } else {
1077 fprintf(stderr,"unknown address_size:%d", reader->address_size);
1078 abort();
1079 }
1080 break;
1081 case DW_FORM_ref1:
1082 set_uint_value(v, read_uint8(&reader->p));
1083 break;
1084 case DW_FORM_ref2:
1085 set_uint_value(v, read_uint16(&reader->p));
1086 break;
1087 case DW_FORM_ref4:
1088 set_uint_value(v, read_uint32(&reader->p));
1089 break;
1090 case DW_FORM_ref8:
1091 set_uint_value(v, read_uint64(&reader->p));
1092 break;
1093 case DW_FORM_ref_udata:
1094 set_uint_value(v, uleb128(&reader->p));
1095 break;
1096 case DW_FORM_indirect:
1097 /* TODO: read the refered value */
1098 set_uint_value(v, uleb128(&reader->p));
1099 break;
1100 case DW_FORM_sec_offset:
1101 set_uint_value(v, read_uint(reader)); /* offset */
1102 /* addrptr: debug_addr */
1103 /* lineptr: debug_line */
1104 /* loclist: debug_loclists */
1105 /* loclistptr: debug_loclists */
1106 /* macptr: debug_macro */
1107 /* rnglist: debug_rnglists */
1108 /* rnglistptr: debug_rnglists */
1109 /* stroffsetsptr: debug_str_offsets */
1110 break;
1111 case DW_FORM_exprloc:
1112 v->size = (size_t)read_uleb128(reader);
1113 set_data_value(v, reader->p);
1114 reader->p += v->size;
1115 break;
1116 case DW_FORM_flag_present:
1117 set_uint_value(v, 1);
1118 break;
1119 case DW_FORM_strx:
1120 set_uint_value(v, uleb128(&reader->p));
1121 break;
1122 case DW_FORM_addrx:
1123 /* TODO: read .debug_addr */
1124 set_uint_value(v, uleb128(&reader->p));
1125 break;
1126 case DW_FORM_ref_sup4:
1127 set_uint_value(v, read_uint32(&reader->p));
1128 break;
1129 case DW_FORM_strp_sup:
1130 set_uint_value(v, read_uint(reader));
1131 /* *p = reader->sup_file + reader->sup_str->sh_offset + ret; */
1132 break;
1133 case DW_FORM_data16:
1134 v->size = 16;
1135 set_data_value(v, reader->p);
1136 reader->p += v->size;
1137 break;
1138 case DW_FORM_line_strp:
1139 set_uint_value(v, read_uint(reader));
1140 /* *p = reader->file + reader->line->sh_offset + ret; */
1141 break;
1142 case DW_FORM_ref_sig8:
1143 set_uint_value(v, read_uint64(&reader->p));
1144 break;
1145 case DW_FORM_implicit_const:
1146 set_int_value(v, sleb128(&reader->q));
1147 break;
1148 case DW_FORM_loclistx:
1149 set_uint_value(v, read_uleb128(reader));
1150 break;
1151 case DW_FORM_rnglistx:
1152 set_uint_value(v, read_uleb128(reader));
1153 break;
1154 case DW_FORM_ref_sup8:
1155 set_uint_value(v, read_uint64(&reader->p));
1156 break;
1157 case DW_FORM_strx1:
1158 set_uint_value(v, read_uint8(&reader->p));
1159 break;
1160 case DW_FORM_strx2:
1161 set_uint_value(v, read_uint16(&reader->p));
1162 break;
1163 case DW_FORM_strx3:
1164 set_uint_value(v, read_uint24(&reader->p));
1165 break;
1166 case DW_FORM_strx4:
1167 set_uint_value(v, read_uint32(&reader->p));
1168 break;
1169 case DW_FORM_addrx1:
1170 set_uint_value(v, read_uint8(&reader->p));
1171 break;
1172 case DW_FORM_addrx2:
1173 set_uint_value(v, read_uint16(&reader->p));
1174 break;
1175 case DW_FORM_addrx3:
1176 set_uint_value(v, read_uint24(&reader->p));
1177 break;
1178 case DW_FORM_addrx4:
1179 set_uint_value(v, read_uint32(&reader->p));
1180 break;
1181 case 0:
1182 goto fail;
1183 break;
1184 }
1185 return;
1186
1187 fail:
1188 fprintf(stderr, "%d: unsupported form: %#"PRIx64"\n", __LINE__, form);
1189 exit(1);
1190 }
1191
1192 /* find abbrev in current compilation unit */
1193 static char *
di_find_abbrev(DebugInfoReader * reader,uint64_t abbrev_number)1194 di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
1195 {
1196 uint64_t n;
1197 char *p;
1198 if (abbrev_number < ABBREV_TABLE_SIZE) {
1199 return reader->abbrev_table[abbrev_number];
1200 }
1201 p = reader->abbrev_table[ABBREV_TABLE_SIZE-1];
1202 /* skip 255th record */
1203 uleb128(&p); /* tag */
1204 p++; /* has_children */
1205 /* skip content */
1206 for (;;) {
1207 uint64_t at = uleb128(&p);
1208 uint64_t form = uleb128(&p);
1209 if (!at && !form) break;
1210 }
1211 for (n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
1212 if (n == 0) {
1213 fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
1214 exit(1);
1215 }
1216 uleb128(&p); /* tag */
1217 p++; /* has_children */
1218 /* skip content */
1219 for (;;) {
1220 uint64_t at = uleb128(&p);
1221 uint64_t form = uleb128(&p);
1222 if (!at && !form) break;
1223 }
1224 }
1225 return p;
1226 }
1227
1228 #if 0
1229 static void
1230 hexdump0(const unsigned char *p, size_t n)
1231 {
1232 size_t i;
1233 fprintf(stderr, " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
1234 for (i=0; i < n; i++){
1235 switch (i & 15) {
1236 case 0:
1237 fprintf(stderr, "%02zd: %02X ", i/16, p[i]);
1238 break;
1239 case 15:
1240 fprintf(stderr, "%02X\n", p[i]);
1241 break;
1242 default:
1243 fprintf(stderr, "%02X ", p[i]);
1244 break;
1245 }
1246 }
1247 if ((i & 15) != 15) {
1248 fprintf(stderr, "\n");
1249 }
1250 }
1251 #define hexdump(p,n) hexdump0((const unsigned char *)p, n)
1252
1253 static void
1254 div_inspect(DebugInfoValue *v)
1255 {
1256 switch (v->type) {
1257 case VAL_uint:
1258 fprintf(stderr,"%d: type:%d size:%zx v:%lx\n",__LINE__,v->type,v->size,v->as.uint64);
1259 break;
1260 case VAL_int:
1261 fprintf(stderr,"%d: type:%d size:%zx v:%ld\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64);
1262 break;
1263 case VAL_cstr:
1264 fprintf(stderr,"%d: type:%d size:%zx v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr);
1265 break;
1266 case VAL_data:
1267 fprintf(stderr,"%d: type:%d size:%zx v:\n",__LINE__,v->type,v->size);
1268 hexdump(v->as.ptr, 16);
1269 break;
1270 }
1271 }
1272 #endif
1273
1274 static DIE *
di_read_die(DebugInfoReader * reader,DIE * die)1275 di_read_die(DebugInfoReader *reader, DIE *die)
1276 {
1277 uint64_t abbrev_number = uleb128(&reader->p);
1278 if (abbrev_number == 0) {
1279 reader->level--;
1280 return NULL;
1281 }
1282
1283 reader->q = di_find_abbrev(reader, abbrev_number);
1284
1285 die->pos = reader->p - reader->obj->debug_info.ptr - 1;
1286 die->tag = (int)uleb128(&reader->q); /* tag */
1287 die->has_children = *reader->q++; /* has_children */
1288 if (die->has_children) {
1289 reader->level++;
1290 }
1291 return die;
1292 }
1293
1294 static DebugInfoValue *
di_read_record(DebugInfoReader * reader,DebugInfoValue * vp)1295 di_read_record(DebugInfoReader *reader, DebugInfoValue *vp)
1296 {
1297 uint64_t at = uleb128(&reader->q);
1298 uint64_t form = uleb128(&reader->q);
1299 if (!at || !form) return NULL;
1300 vp->at = at;
1301 vp->form = form;
1302 debug_info_reader_read_value(reader, form, vp);
1303 return vp;
1304 }
1305
1306 static void
di_skip_records(DebugInfoReader * reader)1307 di_skip_records(DebugInfoReader *reader)
1308 {
1309 for (;;) {
1310 DebugInfoValue v = {{}};
1311 uint64_t at = uleb128(&reader->q);
1312 uint64_t form = uleb128(&reader->q);
1313 if (!at || !form) return;
1314 debug_info_reader_read_value(reader, form, &v);
1315 }
1316 }
1317
1318 typedef struct {
1319 uint64_t low_pc;
1320 uint64_t high_pc;
1321 uint64_t ranges;
1322 bool low_pc_set;
1323 bool high_pc_set;
1324 bool ranges_set;
1325 } ranges_t;
1326
1327 static void
ranges_set(ranges_t * ptr,DebugInfoValue * v)1328 ranges_set(ranges_t *ptr, DebugInfoValue *v)
1329 {
1330 switch (v->at) {
1331 case DW_AT_low_pc:
1332 ptr->low_pc = v->as.uint64;
1333 ptr->low_pc_set = true;
1334 break;
1335 case DW_AT_high_pc:
1336 if (v->form == DW_FORM_addr) {
1337 ptr->high_pc = v->as.uint64;
1338 }
1339 else {
1340 ptr->high_pc = ptr->low_pc + v->as.uint64;
1341 }
1342 ptr->high_pc_set = true;
1343 break;
1344 case DW_AT_ranges:
1345 ptr->ranges = v->as.uint64;
1346 ptr->ranges_set = true;
1347 break;
1348 }
1349 }
1350
1351 static uintptr_t
ranges_include(DebugInfoReader * reader,ranges_t * ptr,uint64_t addr)1352 ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
1353 {
1354 if (ptr->high_pc_set) {
1355 if (ptr->ranges_set || !ptr->low_pc_set) {
1356 exit(1);
1357 }
1358 if (ptr->low_pc <= addr && addr <= ptr->high_pc) {
1359 return (uintptr_t)ptr->low_pc;
1360 }
1361 }
1362 else if (ptr->ranges_set) {
1363 /* TODO: support base address selection entry */
1364 char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
1365 uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
1366 for (;;) {
1367 uintptr_t from = read_uintptr(&p);
1368 uintptr_t to = read_uintptr(&p);
1369 if (!from && !to) break;
1370 if (from == UINTPTR_MAX) {
1371 /* base address selection entry */
1372 base = to;
1373 }
1374 else if (base + from <= addr && addr < base + to) {
1375 return from;
1376 }
1377 }
1378 }
1379 else if (ptr->low_pc_set) {
1380 if (ptr->low_pc == addr) {
1381 return (uintptr_t)ptr->low_pc;
1382 }
1383 }
1384 return false;
1385 }
1386
1387 #if 0
1388 static void
1389 ranges_inspect(DebugInfoReader *reader, ranges_t *ptr)
1390 {
1391 if (ptr->high_pc_set) {
1392 if (ptr->ranges_set || !ptr->low_pc_set) {
1393 fprintf(stderr,"low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set);
1394 exit(1);
1395 }
1396 fprintf(stderr,"low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc);
1397 }
1398 else if (ptr->ranges_set) {
1399 char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
1400 fprintf(stderr,"low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped);
1401 for (;;) {
1402 uintptr_t from = read_uintptr(&p);
1403 uintptr_t to = read_uintptr(&p);
1404 if (!from && !to) break;
1405 fprintf(stderr,"%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to);
1406 }
1407 fprintf(stderr,"\n");
1408 }
1409 else if (ptr->low_pc_set) {
1410 fprintf(stderr,"low_pc:%"PRIx64"\n",ptr->low_pc);
1411 }
1412 else {
1413 fprintf(stderr,"empty\n");
1414 }
1415 }
1416 #endif
1417
1418 static int
di_read_cu(DebugInfoReader * reader)1419 di_read_cu(DebugInfoReader *reader)
1420 {
1421 uint64_t unit_length;
1422 uint16_t version;
1423 uint64_t debug_abbrev_offset;
1424 reader->format = 4;
1425 reader->current_cu = reader->p;
1426 unit_length = read_uint32(&reader->p);
1427 if (unit_length == 0xffffffff) {
1428 unit_length = read_uint64(&reader->p);
1429 reader->format = 8;
1430 }
1431 reader->cu_end = reader->p + unit_length;
1432 version = read_uint16(&reader->p);
1433 if (version > 5) {
1434 return -1;
1435 }
1436 else if (version == 5) {
1437 /* unit_type = */ read_uint8(&reader->p);
1438 reader->address_size = read_uint8(&reader->p);
1439 debug_abbrev_offset = read_uint(reader);
1440 }
1441 else {
1442 debug_abbrev_offset = read_uint(reader);
1443 reader->address_size = read_uint8(&reader->p);
1444 }
1445 reader->q0 = reader->obj->debug_abbrev.ptr + debug_abbrev_offset;
1446
1447 reader->level = 0;
1448 di_read_debug_abbrev_cu(reader);
1449 if (di_read_debug_line_cu(reader)) return -1;
1450
1451 #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER_BUILD_DATE)
1452 /* Though DWARF specifies "the applicable base address defaults to the base
1453 address of the compilation unit", but GCC seems to use zero as default */
1454 #else
1455 do {
1456 DIE die;
1457
1458 if (!di_read_die(reader, &die)) continue;
1459
1460 if (die.tag != DW_TAG_compile_unit) {
1461 di_skip_records(reader);
1462 break;
1463 }
1464
1465 /* enumerate abbrev */
1466 for (;;) {
1467 DebugInfoValue v = {{}};
1468 if (!di_read_record(reader, &v)) break;
1469 switch (v.at) {
1470 case DW_AT_low_pc:
1471 reader->current_low_pc = v.as.uint64;
1472 break;
1473 }
1474 }
1475 } while (0);
1476 #endif
1477 return 0;
1478 }
1479
1480 static void
read_abstract_origin(DebugInfoReader * reader,uint64_t abstract_origin,line_info_t * line)1481 read_abstract_origin(DebugInfoReader *reader, uint64_t abstract_origin, line_info_t *line)
1482 {
1483 char *p = reader->p;
1484 char *q = reader->q;
1485 int level = reader->level;
1486 DIE die;
1487
1488 reader->p = reader->current_cu + abstract_origin;
1489 if (!di_read_die(reader, &die)) goto finish;
1490
1491 /* enumerate abbrev */
1492 for (;;) {
1493 DebugInfoValue v = {{}};
1494 if (!di_read_record(reader, &v)) break;
1495 switch (v.at) {
1496 case DW_AT_name:
1497 line->sname = get_cstr_value(&v);
1498 break;
1499 }
1500 }
1501
1502 finish:
1503 reader->p = p;
1504 reader->q = q;
1505 reader->level = level;
1506 }
1507
1508 static void
debug_info_read(DebugInfoReader * reader,int num_traces,void ** traces,line_info_t * lines,int offset)1509 debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
1510 line_info_t *lines, int offset)
1511 {
1512 int i;
1513 while (reader->p < reader->cu_end) {
1514 DIE die;
1515 ranges_t ranges = {};
1516 line_info_t line = {};
1517
1518 if (!di_read_die(reader, &die)) continue;
1519 /* fprintf(stderr,"%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */
1520
1521 if (die.tag != DW_TAG_subprogram && die.tag != DW_TAG_inlined_subroutine) {
1522 skip_die:
1523 di_skip_records(reader);
1524 continue;
1525 }
1526
1527 /* enumerate abbrev */
1528 for (;;) {
1529 DebugInfoValue v = {{}};
1530 /* ptrdiff_t pos = reader->p - reader->p0; */
1531 if (!di_read_record(reader, &v)) break;
1532 /* fprintf(stderr,"\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */
1533 /* div_inspect(&v); */
1534 switch (v.at) {
1535 case DW_AT_name:
1536 line.sname = get_cstr_value(&v);
1537 break;
1538 case DW_AT_call_file:
1539 fill_filename((int)v.as.uint64, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
1540 break;
1541 case DW_AT_call_line:
1542 line.line = (int)v.as.uint64;
1543 break;
1544 case DW_AT_low_pc:
1545 case DW_AT_high_pc:
1546 case DW_AT_ranges:
1547 ranges_set(&ranges, &v);
1548 break;
1549 case DW_AT_declaration:
1550 goto skip_die;
1551 case DW_AT_inline:
1552 /* 1 or 3 */
1553 break; /* goto skip_die; */
1554 case DW_AT_abstract_origin:
1555 read_abstract_origin(reader, v.as.uint64, &line);
1556 break; /* goto skip_die; */
1557 }
1558 }
1559 /* ranges_inspect(reader, &ranges); */
1560 /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */
1561 for (i=offset; i < num_traces; i++) {
1562 uintptr_t addr = (uintptr_t)traces[i];
1563 uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
1564 uintptr_t saddr = ranges_include(reader, &ranges, offset);
1565 if (saddr) {
1566 /* fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
1567 if (lines[i].sname) {
1568 line_info_t *lp = malloc(sizeof(line_info_t));
1569 memcpy(lp, &lines[i], sizeof(line_info_t));
1570 lines[i].next = lp;
1571 lp->dirname = line.dirname;
1572 lp->filename = line.filename;
1573 lp->line = line.line;
1574 lp->saddr = 0;
1575 }
1576 lines[i].path = reader->obj->path;
1577 lines[i].base_addr = line.base_addr;
1578 lines[i].sname = line.sname;
1579 lines[i].saddr = saddr + reader->obj->base_addr - reader->obj->vmaddr;
1580 }
1581 }
1582 }
1583 }
1584
1585 #ifdef USE_ELF
1586 static unsigned long
uncompress_debug_section(ElfW (Shdr)* shdr,char * file,char ** ptr)1587 uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
1588 {
1589 #ifdef SUPPORT_COMPRESSED_DEBUG_LINE
1590 ElfW(Chdr) *chdr = (ElfW(Chdr) *)(file + shdr->sh_offset);
1591 unsigned long destsize = chdr->ch_size;
1592 int ret = 0;
1593
1594 if (chdr->ch_type != ELFCOMPRESS_ZLIB) {
1595 /* unsupported compression type */
1596 return 0;
1597 }
1598
1599 *ptr = malloc(destsize);
1600 if (!*ptr) return 0;
1601 ret = uncompress((Bytef *)*ptr, &destsize,
1602 (const Bytef*)chdr + sizeof(ElfW(Chdr)),
1603 shdr->sh_size - sizeof(ElfW(Chdr)));
1604 if (ret != Z_OK) goto fail;
1605 return destsize;
1606
1607 fail:
1608 free(*ptr);
1609 #endif
1610 return 0;
1611 }
1612
1613 /* read file and fill lines */
1614 static uintptr_t
fill_lines(int num_traces,void ** traces,int check_debuglink,obj_info_t ** objp,line_info_t * lines,int offset)1615 fill_lines(int num_traces, void **traces, int check_debuglink,
1616 obj_info_t **objp, line_info_t *lines, int offset)
1617 {
1618 int i, j;
1619 char *shstr;
1620 ElfW(Ehdr) *ehdr;
1621 ElfW(Shdr) *shdr, *shstr_shdr;
1622 ElfW(Shdr) *gnu_debuglink_shdr = NULL;
1623 int fd;
1624 off_t filesize;
1625 char *file;
1626 ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
1627 ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
1628 obj_info_t *obj = *objp;
1629 uintptr_t dladdr_fbase = 0;
1630
1631 fd = open(binary_filename, O_RDONLY);
1632 if (fd < 0) {
1633 goto fail;
1634 }
1635 filesize = lseek(fd, 0, SEEK_END);
1636 if (filesize < 0) {
1637 int e = errno;
1638 close(fd);
1639 kprintf("lseek: %s\n", strerror(e));
1640 goto fail;
1641 }
1642 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
1643 if (filesize > (off_t)SIZE_MAX) {
1644 close(fd);
1645 kprintf("Too large file %s\n", binary_filename);
1646 goto fail;
1647 }
1648 #endif
1649 lseek(fd, 0, SEEK_SET);
1650 /* async-signal unsafe */
1651 file = (char *)mmap(NULL, (size_t)filesize, PROT_READ, MAP_SHARED, fd, 0);
1652 if (file == MAP_FAILED) {
1653 int e = errno;
1654 close(fd);
1655 kprintf("mmap: %s\n", strerror(e));
1656 goto fail;
1657 }
1658 close(fd);
1659
1660 ehdr = (ElfW(Ehdr) *)file;
1661 if (memcmp(ehdr->e_ident, "\177ELF", 4) != 0) {
1662 /*
1663 * Huh? Maybe filename was overridden by setproctitle() and
1664 * it match non-elf file.
1665 */
1666 goto fail;
1667 }
1668 obj->mapped = file;
1669 obj->mapped_size = (size_t)filesize;
1670
1671 shdr = (ElfW(Shdr) *)(file + ehdr->e_shoff);
1672
1673 shstr_shdr = shdr + ehdr->e_shstrndx;
1674 shstr = file + shstr_shdr->sh_offset;
1675
1676 for (i = 0; i < ehdr->e_shnum; i++) {
1677 char *section_name = shstr + shdr[i].sh_name;
1678 switch (shdr[i].sh_type) {
1679 case SHT_STRTAB:
1680 if (!strcmp(section_name, ".strtab")) {
1681 strtab_shdr = shdr + i;
1682 }
1683 else if (!strcmp(section_name, ".dynstr")) {
1684 dynstr_shdr = shdr + i;
1685 }
1686 break;
1687 case SHT_SYMTAB:
1688 /* if (!strcmp(section_name, ".symtab")) */
1689 symtab_shdr = shdr + i;
1690 break;
1691 case SHT_DYNSYM:
1692 /* if (!strcmp(section_name, ".dynsym")) */
1693 dynsym_shdr = shdr + i;
1694 break;
1695 case SHT_PROGBITS:
1696 if (!strcmp(section_name, ".gnu_debuglink")) {
1697 gnu_debuglink_shdr = shdr + i;
1698 }
1699 else {
1700 const char *debug_section_names[] = {
1701 ".debug_abbrev",
1702 ".debug_info",
1703 ".debug_line",
1704 ".debug_ranges",
1705 ".debug_str"
1706 };
1707
1708 for (j=0; j < DWARF_SECTION_COUNT; j++) {
1709 struct dwarf_section *s = obj_dwarf_section_at(obj, j);
1710
1711 if (strcmp(section_name, debug_section_names[j]) != 0)
1712 continue;
1713
1714 s->ptr = file + shdr[i].sh_offset;
1715 s->size = shdr[i].sh_size;
1716 s->flags = shdr[i].sh_flags;
1717 if (s->flags & SHF_COMPRESSED) {
1718 s->size = uncompress_debug_section(&shdr[i], file, &s->ptr);
1719 if (!s->size) goto fail;
1720 }
1721 break;
1722 }
1723 }
1724 break;
1725 }
1726 }
1727
1728 if (offset == -1) {
1729 /* main executable */
1730 offset = 0;
1731 if (dynsym_shdr && dynstr_shdr) {
1732 char *strtab = file + dynstr_shdr->sh_offset;
1733 ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);
1734 int symtab_count = (int)(dynsym_shdr->sh_size / sizeof(ElfW(Sym)));
1735 void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
1736 if (handle) {
1737 for (j = 0; j < symtab_count; j++) {
1738 ElfW(Sym) *sym = &symtab[j];
1739 Dl_info info;
1740 void *s;
1741 if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size == 0) continue;
1742 s = dlsym(handle, strtab + sym->st_name);
1743 if (s && dladdr(s, &info)) {
1744 obj->base_addr = dladdr_fbase;
1745 dladdr_fbase = (uintptr_t)info.dli_fbase;
1746 break;
1747 }
1748 }
1749 dlclose(handle);
1750 }
1751 if (ehdr->e_type == ET_EXEC) {
1752 obj->base_addr = 0;
1753 }
1754 else {
1755 /* PIE (position-independent executable) */
1756 obj->base_addr = dladdr_fbase;
1757 }
1758 }
1759 }
1760
1761 if (obj->debug_info.ptr && obj->debug_abbrev.ptr) {
1762 DebugInfoReader reader;
1763 debug_info_reader_init(&reader, obj);
1764 i = 0;
1765 while (reader.p < reader.pend) {
1766 /* fprintf(stderr, "%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */
1767 if (di_read_cu(&reader)) goto use_symtab;
1768 debug_info_read(&reader, num_traces, traces, lines, offset);
1769 }
1770 }
1771 else {
1772 /* This file doesn't have dwarf, use symtab or dynsym */
1773 use_symtab:
1774 if (!symtab_shdr) {
1775 /* This file doesn't have symtab, use dynsym instead */
1776 symtab_shdr = dynsym_shdr;
1777 strtab_shdr = dynstr_shdr;
1778 }
1779
1780 if (symtab_shdr && strtab_shdr) {
1781 char *strtab = file + strtab_shdr->sh_offset;
1782 ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);
1783 int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym)));
1784 for (j = 0; j < symtab_count; j++) {
1785 ElfW(Sym) *sym = &symtab[j];
1786 uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr;
1787 if (ELF_ST_TYPE(sym->st_info) != STT_FUNC) continue;
1788 for (i = offset; i < num_traces; i++) {
1789 uintptr_t d = (uintptr_t)traces[i] - saddr;
1790 if (lines[i].line > 0 || d > (uintptr_t)sym->st_size)
1791 continue;
1792 /* fill symbol name and addr from .symtab */
1793 if (!lines[i].sname) lines[i].sname = strtab + sym->st_name;
1794 lines[i].saddr = saddr;
1795 lines[i].path = obj->path;
1796 lines[i].base_addr = obj->base_addr;
1797 }
1798 }
1799 }
1800 }
1801
1802 if (!obj->debug_line.ptr) {
1803 /* This file doesn't have .debug_line section,
1804 let's check .gnu_debuglink section instead. */
1805 if (gnu_debuglink_shdr && check_debuglink) {
1806 follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
1807 num_traces, traces,
1808 objp, lines, offset);
1809 }
1810 goto finish;
1811 }
1812
1813 if (parse_debug_line(num_traces, traces,
1814 obj->debug_line.ptr,
1815 obj->debug_line.size,
1816 obj, lines, offset) == -1)
1817 goto fail;
1818
1819 finish:
1820 return dladdr_fbase;
1821 fail:
1822 return (uintptr_t)-1;
1823 }
1824 #else /* Mach-O */
1825 /* read file and fill lines */
1826 static uintptr_t
fill_lines(int num_traces,void ** traces,int check_debuglink,obj_info_t ** objp,line_info_t * lines,int offset)1827 fill_lines(int num_traces, void **traces, int check_debuglink,
1828 obj_info_t **objp, line_info_t *lines, int offset)
1829 {
1830 # ifdef __LP64__
1831 # define LP(x) x##_64
1832 # else
1833 # define LP(x) x
1834 # endif
1835 int fd;
1836 off_t filesize;
1837 char *file, *p = NULL;
1838 obj_info_t *obj = *objp;
1839 struct LP(mach_header) *header;
1840 uintptr_t dladdr_fbase = 0;
1841
1842 {
1843 char *s = binary_filename;
1844 char *base = strrchr(binary_filename, '/')+1;
1845 size_t max = PATH_MAX;
1846 size_t size = strlen(binary_filename);
1847 size_t basesize = size - (base - binary_filename);
1848 s += size;
1849 max -= size;
1850 p = s;
1851 size = strlcpy(s, ".dSYM/Contents/Resources/DWARF/", max);
1852 if (size == 0) goto fail;
1853 s += size;
1854 max -= size;
1855 if (max <= basesize) goto fail;
1856 memcpy(s, base, basesize);
1857 s[basesize] = 0;
1858
1859 fd = open(binary_filename, O_RDONLY);
1860 if (fd < 0) {
1861 *p = 0; /* binary_filename becomes original file name */
1862 fd = open(binary_filename, O_RDONLY);
1863 if (fd < 0) {
1864 goto fail;
1865 }
1866 }
1867 }
1868
1869 filesize = lseek(fd, 0, SEEK_END);
1870 if (filesize < 0) {
1871 int e = errno;
1872 close(fd);
1873 kprintf("lseek: %s\n", strerror(e));
1874 goto fail;
1875 }
1876 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
1877 if (filesize > (off_t)SIZE_MAX) {
1878 close(fd);
1879 kprintf("Too large file %s\n", binary_filename);
1880 goto fail;
1881 }
1882 #endif
1883 lseek(fd, 0, SEEK_SET);
1884 /* async-signal unsafe */
1885 file = (char *)mmap(NULL, (size_t)filesize, PROT_READ, MAP_SHARED, fd, 0);
1886 if (file == MAP_FAILED) {
1887 int e = errno;
1888 close(fd);
1889 kprintf("mmap: %s\n", strerror(e));
1890 goto fail;
1891 }
1892 close(fd);
1893
1894 obj->mapped = file;
1895 obj->mapped_size = (size_t)filesize;
1896
1897 header = (struct LP(mach_header) *)file;
1898 if (header->magic == LP(MH_MAGIC)) {
1899 /* non universal binary */
1900 p = file;
1901 }
1902 else if (header->magic == FAT_CIGAM) {
1903 struct fat_header *fat = (struct fat_header *)file;
1904 char *q = file + sizeof(*fat);
1905 uint32_t nfat_arch = __builtin_bswap32(fat->nfat_arch);
1906 /* fprintf(stderr,"%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */
1907 for (uint32_t i = 0; i < nfat_arch; i++) {
1908 struct fat_arch *arch = (struct fat_arch *)q;
1909 cpu_type_t cputype = __builtin_bswap32(arch->cputype);
1910 cpu_subtype_t cpusubtype = __builtin_bswap32(arch->cpusubtype);
1911 uint32_t offset = __builtin_bswap32(arch->offset);
1912 /* fprintf(stderr,"%d: fat %d %x/%x %x/%x\n",__LINE__, i, _mh_execute_header.cputype,_mh_execute_header.cpusubtype, cputype,cpusubtype); */
1913 if (_mh_execute_header.cputype == cputype &&
1914 (_mh_execute_header.cpusubtype & ~CPU_SUBTYPE_MASK) == cpusubtype) {
1915 p = file + offset;
1916 file = p;
1917 header = (struct LP(mach_header) *)p;
1918 if (header->magic == LP(MH_MAGIC)) {
1919 goto found_mach_header;
1920 }
1921 break;
1922 }
1923 q += sizeof(*arch);
1924 }
1925 kprintf("'%s' is not a Mach-O universal binary file!\n",binary_filename);
1926 close(fd);
1927 goto fail;
1928 }
1929 else {
1930 kprintf("'%s' is not a "
1931 # ifdef __LP64__
1932 "64"
1933 # else
1934 "32"
1935 # endif
1936 "-bit Mach-O file!\n",binary_filename);
1937 close(fd);
1938 goto fail;
1939 }
1940 found_mach_header:
1941 p += sizeof(*header);
1942
1943 for (uint32_t i = 0; i < (uint32_t)header->ncmds; i++) {
1944 struct load_command *lcmd = (struct load_command *)p;
1945 switch (lcmd->cmd) {
1946 case LP(LC_SEGMENT):
1947 {
1948 static const char *debug_section_names[] = {
1949 "__debug_abbrev",
1950 "__debug_info",
1951 "__debug_line",
1952 "__debug_ranges",
1953 "__debug_str"
1954 };
1955 struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
1956 if (strcmp(scmd->segname, "__TEXT") == 0) {
1957 obj->vmaddr = scmd->vmaddr;
1958 }
1959 else if (strcmp(scmd->segname, "__DWARF") == 0) {
1960 p += sizeof(struct LP(segment_command));
1961 for (uint64_t i = 0; i < scmd->nsects; i++) {
1962 struct LP(section) *sect = (struct LP(section) *)p;
1963 p += sizeof(struct LP(section));
1964 for (int j=0; j < DWARF_SECTION_COUNT; j++) {
1965 struct dwarf_section *s = obj_dwarf_section_at(obj, j);
1966
1967 if (strcmp(sect->sectname, debug_section_names[j]) != 0)
1968 continue;
1969
1970 s->ptr = file + sect->offset;
1971 s->size = sect->size;
1972 s->flags = sect->flags;
1973 if (s->flags & SHF_COMPRESSED) {
1974 goto fail;
1975 }
1976 break;
1977 }
1978 }
1979 }
1980 }
1981 break;
1982
1983 case LC_SYMTAB:
1984 {
1985 struct symtab_command *cmd = (struct symtab_command *)lcmd;
1986 struct LP(nlist) *nl = (struct LP(nlist) *)(file + cmd->symoff);
1987 char *strtab = file + cmd->stroff, *sname;
1988 uint32_t j;
1989 uintptr_t saddr;
1990 /* kprintf("[%2d]: %x/symtab %p\n", i, cmd->cmd, p); */
1991 for (j = 0; j < cmd->nsyms; j++) {
1992 uintptr_t symsize, d;
1993 struct LP(nlist) *e = &nl[j];
1994 /* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
1995 if (e->n_type != N_FUN) continue;
1996 if (e->n_sect) {
1997 saddr = (uintptr_t)e->n_value + obj->base_addr - obj->vmaddr;
1998 sname = strtab + e->n_un.n_strx;
1999 /* kprintf("[%2d][%4d]: %02x/%x/%x: %s %llx\n", i, j, e->n_type,e->n_sect,e->n_desc,strtab+e->n_un.n_strx,e->n_value); */
2000 continue;
2001 }
2002 for (int k = offset; k < num_traces; k++) {
2003 d = (uintptr_t)traces[k] - saddr;
2004 symsize = e->n_value;
2005 /* kprintf("%lx %lx %lx\n",saddr,symsize,traces[k]); */
2006 if (lines[k].line > 0 || d > (uintptr_t)symsize)
2007 continue;
2008 /* fill symbol name and addr from .symtab */
2009 if (!lines[k].sname) lines[k].sname = sname;
2010 lines[k].saddr = saddr;
2011 lines[k].path = obj->path;
2012 lines[k].base_addr = obj->base_addr;
2013 }
2014 }
2015 }
2016 }
2017 p += lcmd->cmdsize;
2018 }
2019
2020 if (obj->debug_info.ptr && obj->debug_abbrev.ptr) {
2021 DebugInfoReader reader;
2022 debug_info_reader_init(&reader, obj);
2023 while (reader.p < reader.pend) {
2024 if (di_read_cu(&reader)) goto fail;
2025 debug_info_read(&reader, num_traces, traces, lines, offset);
2026 }
2027 }
2028
2029 if (parse_debug_line(num_traces, traces,
2030 obj->debug_line.ptr,
2031 obj->debug_line.size,
2032 obj, lines, offset) == -1)
2033 goto fail;
2034
2035 return dladdr_fbase;
2036 fail:
2037 return (uintptr_t)-1;
2038 }
2039 #endif
2040
2041 #define HAVE_MAIN_EXE_PATH
2042 #if defined(__FreeBSD__)
2043 # include <sys/sysctl.h>
2044 #endif
2045 /* ssize_t main_exe_path(void)
2046 *
2047 * store the path of the main executable to `binary_filename`,
2048 * and returns strlen(binary_filename).
2049 * it is NUL terminated.
2050 */
2051 #if defined(__linux__)
2052 static ssize_t
main_exe_path(void)2053 main_exe_path(void)
2054 {
2055 # define PROC_SELF_EXE "/proc/self/exe"
2056 ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
2057 binary_filename[len] = 0;
2058 return len;
2059 }
2060 #elif defined(__FreeBSD__)
2061 static ssize_t
main_exe_path(void)2062 main_exe_path(void)
2063 {
2064 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
2065 size_t len = PATH_MAX;
2066 int err = sysctl(mib, 4, binary_filename, &len, NULL, 0);
2067 if (err) {
2068 kprintf("Can't get the path of ruby");
2069 return -1;
2070 }
2071 len--; /* sysctl sets strlen+1 */
2072 return len;
2073 }
2074 #else
2075 #undef HAVE_MAIN_EXE_PATH
2076 #endif
2077
2078 static void
print_line0(line_info_t * line,void * address)2079 print_line0(line_info_t *line, void *address)
2080 {
2081 uintptr_t addr = (uintptr_t)address;
2082 uintptr_t d = addr - line->saddr;
2083 if (!address) {
2084 /* inlined */
2085 if (line->dirname && line->dirname[0]) {
2086 kprintf("%s(%s) %s/%s:%d\n", line->path, line->sname, line->dirname, line->filename, line->line);
2087 }
2088 else {
2089 kprintf("%s(%s) %s:%d\n", line->path, line->sname, line->filename, line->line);
2090 }
2091 }
2092 else if (!line->path) {
2093 kprintf("[0x%"PRIxPTR"]\n", addr);
2094 }
2095 else if (!line->saddr || !line->sname) {
2096 kprintf("%s(0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, addr-line->base_addr, addr);
2097 }
2098 else if (line->line <= 0) {
2099 kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"]\n", line->path, line->sname,
2100 d, addr);
2101 }
2102 else if (!line->filename) {
2103 kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] ???:%d\n", line->path, line->sname,
2104 d, addr, line->line);
2105 }
2106 else if (line->dirname && line->dirname[0]) {
2107 kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] %s/%s:%d\n", line->path, line->sname,
2108 d, addr, line->dirname, line->filename, line->line);
2109 }
2110 else {
2111 kprintf("%s(%s+0x%"PRIxPTR") [0x%"PRIxPTR"] %s:%d\n", line->path, line->sname,
2112 d, addr, line->filename, line->line);
2113 }
2114 }
2115
2116 static void
print_line(line_info_t * line,void * address)2117 print_line(line_info_t *line, void *address)
2118 {
2119 print_line0(line, address);
2120 if (line->next) {
2121 print_line(line->next, NULL);
2122 }
2123 }
2124
2125 void
rb_dump_backtrace_with_lines(int num_traces,void ** traces)2126 rb_dump_backtrace_with_lines(int num_traces, void **traces)
2127 {
2128 int i;
2129 /* async-signal unsafe */
2130 line_info_t *lines = (line_info_t *)calloc(num_traces, sizeof(line_info_t));
2131 obj_info_t *obj = NULL;
2132 /* 2 is NULL + main executable */
2133 void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
2134 #ifdef HAVE_MAIN_EXE_PATH
2135 char *main_path = NULL; /* used on printing backtrace */
2136 ssize_t len;
2137 if ((len = main_exe_path()) > 0) {
2138 main_path = (char *)alloca(len + 1);
2139 if (main_path) {
2140 uintptr_t addr;
2141 memcpy(main_path, binary_filename, len+1);
2142 append_obj(&obj);
2143 obj->path = main_path;
2144 addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
2145 if (addr != (uintptr_t)-1) {
2146 dladdr_fbases[0] = (void *)addr;
2147 }
2148 }
2149 }
2150 #endif
2151
2152 /* fill source lines by reading dwarf */
2153 for (i = 0; i < num_traces; i++) {
2154 Dl_info info;
2155 if (lines[i].line) continue;
2156 if (dladdr(traces[i], &info)) {
2157 const char *path;
2158 void **p;
2159
2160 /* skip symbols which is in already checked objects */
2161 /* if the binary is strip-ed, this may effect */
2162 for (p=dladdr_fbases; *p; p++) {
2163 if (*p == info.dli_fbase) {
2164 lines[i].path = info.dli_fname;
2165 lines[i].sname = info.dli_sname;
2166 goto next_line;
2167 }
2168 }
2169 *p = info.dli_fbase;
2170
2171 append_obj(&obj);
2172 obj->base_addr = (uintptr_t)info.dli_fbase;
2173 path = info.dli_fname;
2174 obj->path = path;
2175 lines[i].path = path;
2176 lines[i].sname = info.dli_sname;
2177 lines[i].saddr = (uintptr_t)info.dli_saddr;
2178 strlcpy(binary_filename, path, PATH_MAX);
2179 if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
2180 break;
2181 }
2182 next_line:
2183 continue;
2184 }
2185
2186 /* output */
2187 for (i = 0; i < num_traces; i++) {
2188 print_line(&lines[i], traces[i]);
2189
2190 /* FreeBSD's backtrace may show _start and so on */
2191 if (lines[i].sname && strcmp("main", lines[i].sname) == 0)
2192 break;
2193 }
2194
2195 /* free */
2196 while (obj) {
2197 obj_info_t *o = obj;
2198 for (i=0; i < DWARF_SECTION_COUNT; i++) {
2199 struct dwarf_section *s = obj_dwarf_section_at(obj, i);
2200 if (s->flags & SHF_COMPRESSED) {
2201 free(s->ptr);
2202 }
2203 }
2204 if (obj->mapped_size) {
2205 munmap(obj->mapped, obj->mapped_size);
2206 }
2207 obj = o->next;
2208 free(o);
2209 }
2210 for (i = 0; i < num_traces; i++) {
2211 line_info_t *line = lines[i].next;
2212 while (line) {
2213 line_info_t *l = line;
2214 line = line->next;
2215 free(l);
2216 }
2217 }
2218 free(lines);
2219 free(dladdr_fbases);
2220 }
2221
2222 /* From FreeBSD's lib/libstand/printf.c */
2223 /*-
2224 * Copyright (c) 1986, 1988, 1991, 1993
2225 * The Regents of the University of California. All rights reserved.
2226 * (c) UNIX System Laboratories, Inc.
2227 * All or some portions of this file are derived from material licensed
2228 * to the University of California by American Telephone and Telegraph
2229 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
2230 * the permission of UNIX System Laboratories, Inc.
2231 *
2232 * Redistribution and use in source and binary forms, with or without
2233 * modification, are permitted provided that the following conditions
2234 * are met:
2235 * 1. Redistributions of source code must retain the above copyright
2236 * notice, this list of conditions and the following disclaimer.
2237 * 2. Redistributions in binary form must reproduce the above copyright
2238 * notice, this list of conditions and the following disclaimer in the
2239 * documentation and/or other materials provided with the distribution.
2240 * 4. Neither the name of the University nor the names of its contributors
2241 * may be used to endorse or promote products derived from this software
2242 * without specific prior written permission.
2243 *
2244 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2245 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2246 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2247 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2248 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2249 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2250 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2251 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2252 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2253 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2254 * SUCH DAMAGE.
2255 *
2256 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
2257 */
2258
2259 #include <stdarg.h>
2260 #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
toupper(int c)2261 static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; }
2262 #define hex2ascii(hex) (hex2ascii_data[hex])
2263 static const char hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
imax(int a,int b)2264 static inline int imax(int a, int b) { return (a > b ? a : b); }
2265 static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
2266
putce(int c)2267 static void putce(int c)
2268 {
2269 char s[1];
2270 ssize_t ret;
2271
2272 s[0] = (char)c;
2273 ret = write(2, s, 1);
2274 (void)ret;
2275 }
2276
2277 static int
kprintf(const char * fmt,...)2278 kprintf(const char *fmt, ...)
2279 {
2280 va_list ap;
2281 int retval;
2282
2283 va_start(ap, fmt);
2284 retval = kvprintf(fmt, putce, NULL, 10, ap);
2285 va_end(ap);
2286 return retval;
2287 }
2288
2289 /*
2290 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
2291 * order; return an optional length and a pointer to the last character
2292 * written in the buffer (i.e., the first character of the string).
2293 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
2294 */
2295 static char *
ksprintn(char * nbuf,uintmax_t num,int base,int * lenp,int upper)2296 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
2297 {
2298 char *p, c;
2299
2300 p = nbuf;
2301 *p = '\0';
2302 do {
2303 c = hex2ascii(num % base);
2304 *++p = upper ? toupper(c) : c;
2305 } while (num /= base);
2306 if (lenp)
2307 *lenp = (int)(p - nbuf);
2308 return (p);
2309 }
2310
2311 /*
2312 * Scaled down version of printf(3).
2313 *
2314 * Two additional formats:
2315 *
2316 * The format %b is supported to decode error registers.
2317 * Its usage is:
2318 *
2319 * printf("reg=%b\n", regval, "<base><arg>*");
2320 *
2321 * where <base> is the output base expressed as a control character, e.g.
2322 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
2323 * the first of which gives the bit number to be inspected (origin 1), and
2324 * the next characters (up to a control character, i.e. a character <= 32),
2325 * give the name of the register. Thus:
2326 *
2327 * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
2328 *
2329 * would produce output:
2330 *
2331 * reg=3<BITTWO,BITONE>
2332 *
2333 * XXX: %D -- Hexdump, takes pointer and separator string:
2334 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
2335 * ("%*D", len, ptr, " " -> XX XX XX XX ...
2336 */
2337 static int
kvprintf(char const * fmt,void (* func)(int),void * arg,int radix,va_list ap)2338 kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
2339 {
2340 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
2341 char nbuf[MAXNBUF];
2342 char *d;
2343 const char *p, *percent, *q;
2344 unsigned char *up;
2345 int ch, n;
2346 uintmax_t num;
2347 int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
2348 int cflag, hflag, jflag, tflag, zflag;
2349 int dwidth, upper;
2350 char padc;
2351 int stop = 0, retval = 0;
2352
2353 num = 0;
2354 if (!func)
2355 d = (char *) arg;
2356 else
2357 d = NULL;
2358
2359 if (fmt == NULL)
2360 fmt = "(fmt null)\n";
2361
2362 if (radix < 2 || radix > 36)
2363 radix = 10;
2364
2365 for (;;) {
2366 padc = ' ';
2367 width = 0;
2368 while ((ch = (unsigned char)*fmt++) != '%' || stop) {
2369 if (ch == '\0')
2370 return (retval);
2371 PCHAR(ch);
2372 }
2373 percent = fmt - 1;
2374 qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
2375 sign = 0; dot = 0; dwidth = 0; upper = 0;
2376 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
2377 reswitch: switch (ch = (unsigned char)*fmt++) {
2378 case '.':
2379 dot = 1;
2380 goto reswitch;
2381 case '#':
2382 sharpflag = 1;
2383 goto reswitch;
2384 case '+':
2385 sign = 1;
2386 goto reswitch;
2387 case '-':
2388 ladjust = 1;
2389 goto reswitch;
2390 case '%':
2391 PCHAR(ch);
2392 break;
2393 case '*':
2394 if (!dot) {
2395 width = va_arg(ap, int);
2396 if (width < 0) {
2397 ladjust = !ladjust;
2398 width = -width;
2399 }
2400 } else {
2401 dwidth = va_arg(ap, int);
2402 }
2403 goto reswitch;
2404 case '0':
2405 if (!dot) {
2406 padc = '0';
2407 goto reswitch;
2408 }
2409 case '1': case '2': case '3': case '4':
2410 case '5': case '6': case '7': case '8': case '9':
2411 for (n = 0;; ++fmt) {
2412 n = n * 10 + ch - '0';
2413 ch = *fmt;
2414 if (ch < '0' || ch > '9')
2415 break;
2416 }
2417 if (dot)
2418 dwidth = n;
2419 else
2420 width = n;
2421 goto reswitch;
2422 case 'b':
2423 num = (unsigned int)va_arg(ap, int);
2424 p = va_arg(ap, char *);
2425 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
2426 PCHAR(*q--);
2427
2428 if (num == 0)
2429 break;
2430
2431 for (tmp = 0; *p;) {
2432 n = *p++;
2433 if (num & (1 << (n - 1))) {
2434 PCHAR(tmp ? ',' : '<');
2435 for (; (n = *p) > ' '; ++p)
2436 PCHAR(n);
2437 tmp = 1;
2438 } else
2439 for (; *p > ' '; ++p)
2440 continue;
2441 }
2442 if (tmp)
2443 PCHAR('>');
2444 break;
2445 case 'c':
2446 PCHAR(va_arg(ap, int));
2447 break;
2448 case 'D':
2449 up = va_arg(ap, unsigned char *);
2450 p = va_arg(ap, char *);
2451 if (!width)
2452 width = 16;
2453 while(width--) {
2454 PCHAR(hex2ascii(*up >> 4));
2455 PCHAR(hex2ascii(*up & 0x0f));
2456 up++;
2457 if (width)
2458 for (q=p;*q;q++)
2459 PCHAR(*q);
2460 }
2461 break;
2462 case 'd':
2463 case 'i':
2464 base = 10;
2465 sign = 1;
2466 goto handle_sign;
2467 case 'h':
2468 if (hflag) {
2469 hflag = 0;
2470 cflag = 1;
2471 } else
2472 hflag = 1;
2473 goto reswitch;
2474 case 'j':
2475 jflag = 1;
2476 goto reswitch;
2477 case 'l':
2478 if (lflag) {
2479 lflag = 0;
2480 qflag = 1;
2481 } else
2482 lflag = 1;
2483 goto reswitch;
2484 case 'n':
2485 if (jflag)
2486 *(va_arg(ap, intmax_t *)) = retval;
2487 else if (qflag)
2488 *(va_arg(ap, int64_t *)) = retval;
2489 else if (lflag)
2490 *(va_arg(ap, long *)) = retval;
2491 else if (zflag)
2492 *(va_arg(ap, size_t *)) = retval;
2493 else if (hflag)
2494 *(va_arg(ap, short *)) = retval;
2495 else if (cflag)
2496 *(va_arg(ap, char *)) = retval;
2497 else
2498 *(va_arg(ap, int *)) = retval;
2499 break;
2500 case 'o':
2501 base = 8;
2502 goto handle_nosign;
2503 case 'p':
2504 base = 16;
2505 sharpflag = (width == 0);
2506 sign = 0;
2507 num = (uintptr_t)va_arg(ap, void *);
2508 goto number;
2509 case 'q':
2510 qflag = 1;
2511 goto reswitch;
2512 case 'r':
2513 base = radix;
2514 if (sign)
2515 goto handle_sign;
2516 goto handle_nosign;
2517 case 's':
2518 p = va_arg(ap, char *);
2519 if (p == NULL)
2520 p = "(null)";
2521 if (!dot)
2522 n = (int)strlen (p);
2523 else
2524 for (n = 0; n < dwidth && p[n]; n++)
2525 continue;
2526
2527 width -= n;
2528
2529 if (!ladjust && width > 0)
2530 while (width--)
2531 PCHAR(padc);
2532 while (n--)
2533 PCHAR(*p++);
2534 if (ladjust && width > 0)
2535 while (width--)
2536 PCHAR(padc);
2537 break;
2538 case 't':
2539 tflag = 1;
2540 goto reswitch;
2541 case 'u':
2542 base = 10;
2543 goto handle_nosign;
2544 case 'X':
2545 upper = 1;
2546 case 'x':
2547 base = 16;
2548 goto handle_nosign;
2549 case 'y':
2550 base = 16;
2551 sign = 1;
2552 goto handle_sign;
2553 case 'z':
2554 zflag = 1;
2555 goto reswitch;
2556 handle_nosign:
2557 sign = 0;
2558 if (jflag)
2559 num = va_arg(ap, uintmax_t);
2560 else if (qflag)
2561 num = va_arg(ap, uint64_t);
2562 else if (tflag)
2563 num = va_arg(ap, ptrdiff_t);
2564 else if (lflag)
2565 num = va_arg(ap, unsigned long);
2566 else if (zflag)
2567 num = va_arg(ap, size_t);
2568 else if (hflag)
2569 num = (unsigned short)va_arg(ap, int);
2570 else if (cflag)
2571 num = (unsigned char)va_arg(ap, int);
2572 else
2573 num = va_arg(ap, unsigned int);
2574 goto number;
2575 handle_sign:
2576 if (jflag)
2577 num = va_arg(ap, intmax_t);
2578 else if (qflag)
2579 num = va_arg(ap, int64_t);
2580 else if (tflag)
2581 num = va_arg(ap, ptrdiff_t);
2582 else if (lflag)
2583 num = va_arg(ap, long);
2584 else if (zflag)
2585 num = va_arg(ap, ssize_t);
2586 else if (hflag)
2587 num = (short)va_arg(ap, int);
2588 else if (cflag)
2589 num = (char)va_arg(ap, int);
2590 else
2591 num = va_arg(ap, int);
2592 number:
2593 if (sign && (intmax_t)num < 0) {
2594 neg = 1;
2595 num = -(intmax_t)num;
2596 }
2597 p = ksprintn(nbuf, num, base, &n, upper);
2598 tmp = 0;
2599 if (sharpflag && num != 0) {
2600 if (base == 8)
2601 tmp++;
2602 else if (base == 16)
2603 tmp += 2;
2604 }
2605 if (neg)
2606 tmp++;
2607
2608 if (!ladjust && padc == '0')
2609 dwidth = width - tmp;
2610 width -= tmp + imax(dwidth, n);
2611 dwidth -= n;
2612 if (!ladjust)
2613 while (width-- > 0)
2614 PCHAR(' ');
2615 if (neg)
2616 PCHAR('-');
2617 if (sharpflag && num != 0) {
2618 if (base == 8) {
2619 PCHAR('0');
2620 } else if (base == 16) {
2621 PCHAR('0');
2622 PCHAR('x');
2623 }
2624 }
2625 while (dwidth-- > 0)
2626 PCHAR('0');
2627
2628 while (*p)
2629 PCHAR(*p--);
2630
2631 if (ladjust)
2632 while (width-- > 0)
2633 PCHAR(' ');
2634
2635 break;
2636 default:
2637 while (percent < fmt)
2638 PCHAR(*percent++);
2639 /*
2640 * Since we ignore an formatting argument it is no
2641 * longer safe to obey the remaining formatting
2642 * arguments as the arguments will no longer match
2643 * the format specs.
2644 */
2645 stop = 1;
2646 break;
2647 }
2648 }
2649 #undef PCHAR
2650 }
2651 #else /* defined(USE_ELF) */
2652 #error not supported
2653 #endif
2654