Ruby  2.5.0dev(2017-10-22revision60238)
addr2line.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  addr2line.c -
4 
5  $Author$
6 
7  Copyright (C) 2010 Shinichiro Hamaji
8 
9 **********************************************************************/
10 
11 #include "ruby/config.h"
12 #include "ruby/missing.h"
13 #include "addr2line.h"
14 
15 #include <stdio.h>
16 #include <errno.h>
17 
18 #ifdef USE_ELF
19 
20 #include <fcntl.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/mman.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 
31 #ifdef __OpenBSD__
32 #include <elf_abi.h>
33 #else
34 #include <elf.h>
35 #endif
36 
37 /* Make alloca work the best possible way. */
38 #ifdef __GNUC__
39 # ifndef alloca
40 # define alloca __builtin_alloca
41 # endif
42 #else
43 # ifdef HAVE_ALLOCA_H
44 # include <alloca.h>
45 # else
46 # ifdef _AIX
47 #pragma alloca
48 # else
49 # ifndef alloca /* predefined by HP cc +Olibcalls */
50 void *alloca();
51 # endif
52 # endif /* AIX */
53 # endif /* HAVE_ALLOCA_H */
54 #endif /* __GNUC__ */
55 
56 #ifdef HAVE_DLADDR
57 # include <dlfcn.h>
58 #endif
59 
60 #define DW_LNS_copy 0x01
61 #define DW_LNS_advance_pc 0x02
62 #define DW_LNS_advance_line 0x03
63 #define DW_LNS_set_file 0x04
64 #define DW_LNS_set_column 0x05
65 #define DW_LNS_negate_stmt 0x06
66 #define DW_LNS_set_basic_block 0x07
67 #define DW_LNS_const_add_pc 0x08
68 #define DW_LNS_fixed_advance_pc 0x09
69 #define DW_LNS_set_prologue_end 0x0a /* DWARF3 */
70 #define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */
71 #define DW_LNS_set_isa 0x0c /* DWARF3 */
72 
73 /* Line number extended opcode name. */
74 #define DW_LNE_end_sequence 0x01
75 #define DW_LNE_set_address 0x02
76 #define DW_LNE_define_file 0x03
77 #define DW_LNE_set_discriminator 0x04 /* DWARF4 */
78 
79 #ifndef ElfW
80 # if SIZEOF_VOIDP == 8
81 # define ElfW(x) Elf64##_##x
82 # else
83 # define ElfW(x) Elf32##_##x
84 # endif
85 #endif
86 #ifndef ELF_ST_TYPE
87 # if SIZEOF_VOIDP == 8
88 # define ELF_ST_TYPE ELF64_ST_TYPE
89 # else
90 # define ELF_ST_TYPE ELF32_ST_TYPE
91 # endif
92 #endif
93 #ifndef PATH_MAX
94 #define PATH_MAX 4096
95 #endif
96 
97 int kprintf(const char *fmt, ...);
98 
99 typedef struct {
100  const char *dirname;
101  const char *filename;
102  const char *path; /* object path */
103  int line;
104 
105  uintptr_t base_addr;
106  uintptr_t saddr;
107  const char *sname; /* function name */
108 } line_info_t;
109 typedef struct obj_info obj_info_t;
110 struct obj_info {
111  const char *path; /* object path */
112  int fd;
113  void *mapped;
114  size_t mapped_size;
115  uintptr_t base_addr;
116  obj_info_t *next;
117 };
118 
119 /* Avoid consuming stack as this module may be used from signal handler */
120 static char binary_filename[PATH_MAX];
121 
122 static unsigned long
123 uleb128(char **p)
124 {
125  unsigned long r = 0;
126  int s = 0;
127  for (;;) {
128  unsigned char b = *(unsigned char *)(*p)++;
129  if (b < 0x80) {
130  r += (unsigned long)b << s;
131  break;
132  }
133  r += (b & 0x7f) << s;
134  s += 7;
135  }
136  return r;
137 }
138 
139 static long
140 sleb128(char **p)
141 {
142  long r = 0;
143  int s = 0;
144  for (;;) {
145  unsigned char b = *(unsigned char *)(*p)++;
146  if (b < 0x80) {
147  if (b & 0x40) {
148  r -= (0x80 - b) << s;
149  }
150  else {
151  r += (b & 0x3f) << s;
152  }
153  break;
154  }
155  r += (b & 0x7f) << s;
156  s += 7;
157  }
158  return r;
159 }
160 
161 static const char *
162 get_nth_dirname(unsigned long dir, char *p)
163 {
164  if (!dir--) {
165  return "";
166  }
167  while (dir--) {
168  while (*p) p++;
169  p++;
170  if (!*p) {
171  kprintf("Unexpected directory number %lu in %s\n",
172  dir, binary_filename);
173  return "";
174  }
175  }
176  return p;
177 }
178 
179 static void
180 fill_filename(int file, char *include_directories, char *filenames,
181  line_info_t *line)
182 {
183  int i;
184  char *p = filenames;
185  char *filename;
186  unsigned long dir;
187  for (i = 1; i <= file; i++) {
188  filename = p;
189  if (!*p) {
190  /* Need to output binary file name? */
191  kprintf("Unexpected file number %d in %s\n",
192  file, binary_filename);
193  return;
194  }
195  while (*p) p++;
196  p++;
197  dir = uleb128(&p);
198  /* last modified. */
199  uleb128(&p);
200  /* size of the file. */
201  uleb128(&p);
202 
203  if (i == file) {
204  line->filename = filename;
205  line->dirname = get_nth_dirname(dir, include_directories);
206  }
207  }
208 }
209 
210 static void
211 fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
212  char *include_directories, char *filenames,
213  obj_info_t *obj, line_info_t *lines, int offset)
214 {
215  int i;
216  addr += obj->base_addr;
217  for (i = offset; i < num_traces; i++) {
218  uintptr_t a = (uintptr_t)traces[i];
219  /* We assume one line code doesn't result >100 bytes of native code.
220  We may want more reliable way eventually... */
221  if (addr < a && a < addr + 100) {
222  fill_filename(file, include_directories, filenames, &lines[i]);
223  lines[i].line = line;
224  }
225  }
226 }
227 
228 static int
229 parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
230  obj_info_t *obj, line_info_t *lines, int offset)
231 {
232  char *p, *cu_end, *cu_start, *include_directories, *filenames;
233  unsigned long unit_length;
234  int default_is_stmt, line_base;
235  unsigned int header_length, minimum_instruction_length, line_range,
236  opcode_base;
237  /* unsigned char *standard_opcode_lengths; */
238 
239  /* The registers. */
240  unsigned long addr = 0;
241  unsigned int file = 1;
242  unsigned int line = 1;
243  /* unsigned int column = 0; */
244  int is_stmt;
245  /* int basic_block = 0; */
246  /* int end_sequence = 0; */
247  /* int prologue_end = 0; */
248  /* int epilogue_begin = 0; */
249  /* unsigned int isa = 0; */
250 
251  p = *debug_line;
252 
253  unit_length = *(unsigned int *)p;
254  p += sizeof(unsigned int);
255  if (unit_length == 0xffffffff) {
256  unit_length = *(unsigned long *)p;
257  p += sizeof(unsigned long);
258  }
259 
260  cu_end = p + unit_length;
261 
262  /*dwarf_version = *(unsigned short *)p;*/
263  p += 2;
264 
265  header_length = *(unsigned int *)p;
266  p += sizeof(unsigned int);
267 
268  cu_start = p + header_length;
269 
270  minimum_instruction_length = *(unsigned char *)p;
271  p++;
272 
273  is_stmt = default_is_stmt = *(unsigned char *)p;
274  p++;
275 
276  line_base = *(signed char *)p;
277  p++;
278 
279  line_range = *(unsigned char *)p;
280  p++;
281 
282  opcode_base = *(unsigned char *)p;
283  p++;
284 
285  /* standard_opcode_lengths = (unsigned char *)p - 1; */
286  p += opcode_base - 1;
287 
288  include_directories = p;
289 
290  /* temporary measure for compress-debug-sections */
291  if (p >= cu_end) return -1;
292 
293  /* skip include directories */
294  while (*p) {
295  p = memchr(p, '\0', cu_end - p);
296  if (!p) return -1;
297  p++;
298  }
299  p++;
300 
301  filenames = p;
302 
303  p = cu_start;
304 
305 #define FILL_LINE() \
306  do { \
307  fill_line(num_traces, traces, addr, file, line, \
308  include_directories, filenames, \
309  obj, lines, offset); \
310  /*basic_block = prologue_end = epilogue_begin = 0;*/ \
311  } while (0)
312 
313  while (p < cu_end) {
314  unsigned long a;
315  unsigned char op = *p++;
316  switch (op) {
317  case DW_LNS_copy:
318  FILL_LINE();
319  break;
320  case DW_LNS_advance_pc:
321  a = uleb128(&p);
322  addr += a;
323  break;
324  case DW_LNS_advance_line: {
325  long a = sleb128(&p);
326  line += a;
327  break;
328  }
329  case DW_LNS_set_file:
330  file = (unsigned int)uleb128(&p);
331  break;
332  case DW_LNS_set_column:
333  /*column = (unsigned int)*/(void)uleb128(&p);
334  break;
335  case DW_LNS_negate_stmt:
336  is_stmt = !is_stmt;
337  break;
338  case DW_LNS_set_basic_block:
339  /*basic_block = 1; */
340  break;
341  case DW_LNS_const_add_pc:
342  a = ((255 - opcode_base) / line_range) *
343  minimum_instruction_length;
344  addr += a;
345  break;
346  case DW_LNS_fixed_advance_pc:
347  a = *(unsigned char *)p++;
348  addr += a;
349  break;
350  case DW_LNS_set_prologue_end:
351  /* prologue_end = 1; */
352  break;
353  case DW_LNS_set_epilogue_begin:
354  /* epilogue_begin = 1; */
355  break;
356  case DW_LNS_set_isa:
357  /* isa = (unsigned int)*/(void)uleb128(&p);
358  break;
359  case 0:
360  a = *(unsigned char *)p++;
361  op = *p++;
362  switch (op) {
363  case DW_LNE_end_sequence:
364  /* end_sequence = 1; */
365  FILL_LINE();
366  addr = 0;
367  file = 1;
368  line = 1;
369  /* column = 0; */
370  is_stmt = default_is_stmt;
371  /* end_sequence = 0; */
372  /* isa = 0; */
373  break;
374  case DW_LNE_set_address:
375  addr = *(unsigned long *)p;
376  p += sizeof(unsigned long);
377  break;
378  case DW_LNE_define_file:
379  kprintf("Unsupported operation in %s\n",
380  binary_filename);
381  break;
382  case DW_LNE_set_discriminator:
383  /* TODO:currently ignore */
384  uleb128(&p);
385  break;
386  default:
387  kprintf("Unknown extended opcode: %d in %s\n",
388  op, binary_filename);
389  }
390  break;
391  default: {
392  unsigned long addr_incr;
393  unsigned long line_incr;
394  a = op - opcode_base;
395  addr_incr = (a / line_range) * minimum_instruction_length;
396  line_incr = line_base + (a % line_range);
397  addr += (unsigned int)addr_incr;
398  line += (unsigned int)line_incr;
399  FILL_LINE();
400  }
401  }
402  }
403  *debug_line = p;
404  return 0;
405 }
406 
407 static int
408 parse_debug_line(int num_traces, void **traces,
409  char *debug_line, unsigned long size,
410  obj_info_t *obj, line_info_t *lines, int offset)
411 {
412  char *debug_line_end = debug_line + size;
413  while (debug_line < debug_line_end) {
414  if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset))
415  return -1;
416  }
417  if (debug_line != debug_line_end) {
418  kprintf("Unexpected size of .debug_line in %s\n",
419  binary_filename);
420  }
421  return 0;
422 }
423 
424 /* read file and fill lines */
425 static uintptr_t
426 fill_lines(int num_traces, void **traces, int check_debuglink,
427  obj_info_t **objp, line_info_t *lines, int offset);
428 
429 static void
430 append_obj(obj_info_t **objp)
431 {
432  obj_info_t *newobj = calloc(1, sizeof(obj_info_t));
433  if (*objp) (*objp)->next = newobj;
434  *objp = newobj;
435 }
436 
437 static void
438 follow_debuglink(const char *debuglink, int num_traces, void **traces,
439  obj_info_t **objp, line_info_t *lines, int offset)
440 {
441  /* Ideally we should check 4 paths to follow gnu_debuglink,
442  but we handle only one case for now as this format is used
443  by some linux distributions. See GDB's info for detail. */
444  static const char global_debug_dir[] = "/usr/lib/debug";
445  const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1;
446  char *p;
447  obj_info_t *o1 = *objp, *o2;
448  size_t len;
449 
450  p = strrchr(binary_filename, '/');
451  if (!p) {
452  return;
453  }
454  p[1] = '\0';
455 
456  len = strlen(binary_filename);
457  if (len >= PATH_MAX - global_debug_dir_len)
458  len = PATH_MAX - global_debug_dir_len - 1;
459  memmove(binary_filename + global_debug_dir_len, binary_filename, len);
460  memcpy(binary_filename, global_debug_dir, global_debug_dir_len);
461  len += global_debug_dir_len;
462  strlcpy(binary_filename + len, debuglink, PATH_MAX - len);
463 
464  append_obj(objp);
465  o2 = *objp;
466  o2->base_addr = o1->base_addr;
467  o2->path = o1->path;
468  fill_lines(num_traces, traces, 0, objp, lines, offset);
469 }
470 
471 /* read file and fill lines */
472 static uintptr_t
473 fill_lines(int num_traces, void **traces, int check_debuglink,
474  obj_info_t **objp, line_info_t *lines, int offset)
475 {
476  int i, j;
477  char *shstr;
478  char *section_name;
479  ElfW(Ehdr) *ehdr;
480  ElfW(Shdr) *shdr, *shstr_shdr;
481  ElfW(Shdr) *debug_line_shdr = NULL, *gnu_debuglink_shdr = NULL;
482  int fd;
483  off_t filesize;
484  char *file;
485  ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
486  ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
487  obj_info_t *obj = *objp;
488  uintptr_t dladdr_fbase = 0;
489 
490  fd = open(binary_filename, O_RDONLY);
491  if (fd < 0) {
492  goto fail;
493  }
494  filesize = lseek(fd, 0, SEEK_END);
495  if (filesize < 0) {
496  int e = errno;
497  close(fd);
498  kprintf("lseek: %s\n", strerror(e));
499  goto fail;
500  }
501 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
502  if (filesize > (off_t)SIZE_MAX) {
503  close(fd);
504  kprintf("Too large file %s\n", binary_filename);
505  goto fail;
506  }
507 #endif
508  lseek(fd, 0, SEEK_SET);
509  /* async-signal unsafe */
510  file = (char *)mmap(NULL, (size_t)filesize, PROT_READ, MAP_SHARED, fd, 0);
511  if (file == MAP_FAILED) {
512  int e = errno;
513  close(fd);
514  kprintf("mmap: %s\n", strerror(e));
515  goto fail;
516  }
517 
518  ehdr = (ElfW(Ehdr) *)file;
519  if (memcmp(ehdr->e_ident, "\177ELF", 4) != 0) {
520  /*
521  * Huh? Maybe filename was overridden by setproctitle() and
522  * it match non-elf file.
523  */
524  close(fd);
525  goto fail;
526  }
527 
528  obj->fd = fd;
529  obj->mapped = file;
530  obj->mapped_size = (size_t)filesize;
531 
532  shdr = (ElfW(Shdr) *)(file + ehdr->e_shoff);
533 
534  shstr_shdr = shdr + ehdr->e_shstrndx;
535  shstr = file + shstr_shdr->sh_offset;
536 
537  for (i = 0; i < ehdr->e_shnum; i++) {
538  section_name = shstr + shdr[i].sh_name;
539  switch (shdr[i].sh_type) {
540  case SHT_STRTAB:
541  if (!strcmp(section_name, ".strtab")) {
542  strtab_shdr = shdr + i;
543  }
544  else if (!strcmp(section_name, ".dynstr")) {
545  dynstr_shdr = shdr + i;
546  }
547  break;
548  case SHT_SYMTAB:
549  /* if (!strcmp(section_name, ".symtab")) */
550  symtab_shdr = shdr + i;
551  break;
552  case SHT_DYNSYM:
553  /* if (!strcmp(section_name, ".dynsym")) */
554  dynsym_shdr = shdr + i;
555  break;
556  case SHT_PROGBITS:
557  if (!strcmp(section_name, ".debug_line")) {
558  debug_line_shdr = shdr + i;
559  }
560  else if (!strcmp(section_name, ".gnu_debuglink")) {
561  gnu_debuglink_shdr = shdr + i;
562  }
563  break;
564  }
565  }
566 
567  if (offset == -1) {
568  /* main executable */
569  offset = 0;
570  if (dynsym_shdr && dynstr_shdr) {
571  char *strtab = file + dynstr_shdr->sh_offset;
572  ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);
573  int symtab_count = (int)(dynsym_shdr->sh_size / sizeof(ElfW(Sym)));
574  for (j = 0; j < symtab_count; j++) {
575  ElfW(Sym) *sym = &symtab[j];
576  Dl_info info;
577  void *h, *s;
578  if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
579  h = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
580  if (!h) continue;
581  s = dlsym(h, strtab + sym->st_name);
582  if (!s) continue;
583  if (dladdr(s, &info)) {
584  dladdr_fbase = (uintptr_t)info.dli_fbase;
585  break;
586  }
587  }
588  if (ehdr->e_type == ET_EXEC) {
589  obj->base_addr = 0;
590  }
591  else {
592  /* PIE (position-independent executable) */
593  obj->base_addr = dladdr_fbase;
594  }
595  }
596  }
597 
598  if (!symtab_shdr) {
599  symtab_shdr = dynsym_shdr;
600  strtab_shdr = dynstr_shdr;
601  }
602 
603  if (symtab_shdr && strtab_shdr) {
604  char *strtab = file + strtab_shdr->sh_offset;
605  ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);
606  int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym)));
607  for (j = 0; j < symtab_count; j++) {
608  ElfW(Sym) *sym = &symtab[j];
609  uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr;
610  if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
611  for (i = offset; i < num_traces; i++) {
612  uintptr_t d = (uintptr_t)traces[i] - saddr;
613  if (lines[i].line > 0 || d <= 0 || d > (uintptr_t)sym->st_size)
614  continue;
615  /* fill symbol name and addr from .symtab */
616  lines[i].sname = strtab + sym->st_name;
617  lines[i].saddr = saddr;
618  lines[i].path = obj->path;
619  lines[i].base_addr = obj->base_addr;
620  }
621  }
622  }
623 
624  if (!debug_line_shdr) {
625  /* This file doesn't have .debug_line section,
626  let's check .gnu_debuglink section instead. */
627  if (gnu_debuglink_shdr && check_debuglink) {
628  follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
629  num_traces, traces,
630  objp, lines, offset);
631  }
632  goto finish;
633  }
634 
635  if (parse_debug_line(num_traces, traces,
636  file + debug_line_shdr->sh_offset,
637  debug_line_shdr->sh_size,
638  obj, lines, offset))
639  goto fail;
640 finish:
641  return dladdr_fbase;
642 fail:
643  return (uintptr_t)-1;
644 }
645 
646 #define HAVE_MAIN_EXE_PATH
647 #if defined(__FreeBSD__)
648 # include <sys/sysctl.h>
649 #endif
650 /* ssize_t main_exe_path(void)
651  *
652  * store the path of the main executable to `binary_filename`,
653  * and returns strlen(binary_filename).
654  * it is NUL terminated.
655  */
656 #if defined(__linux__)
657 ssize_t
658 main_exe_path(void)
659 {
660 # define PROC_SELF_EXE "/proc/self/exe"
661  ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
662  binary_filename[len] = 0;
663  return len;
664 }
665 #elif defined(__FreeBSD__)
666 ssize_t
667 main_exe_path(void)
668 {
669  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
670  size_t len = PATH_MAX;
671  int err = sysctl(mib, 4, binary_filename, &len, NULL, 0);
672  if (err) {
673  kprintf("Can't get the path of ruby");
674  return -1;
675  }
676  len--; /* sysctl sets strlen+1 */
677  return len;
678 }
679 #else
680 #undef HAVE_MAIN_EXE_PATH
681 #endif
682 
683 void
684 rb_dump_backtrace_with_lines(int num_traces, void **traces)
685 {
686  int i;
687  /* async-signal unsafe */
688  line_info_t *lines = (line_info_t *)calloc(num_traces, sizeof(line_info_t));
689  obj_info_t *obj = NULL;
690  /* 2 is NULL + main executable */
691  void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
692 #ifdef HAVE_MAIN_EXE_PATH
693  char *main_path = NULL; /* used on printing backtrace */
694  ssize_t len;
695  if ((len = main_exe_path()) > 0) {
696  main_path = (char *)alloca(len + 1);
697  if (main_path) {
698  uintptr_t addr;
699  memcpy(main_path, binary_filename, len+1);
700  append_obj(&obj);
701  obj->path = main_path;
702  addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
703  if (addr != (uintptr_t)-1) {
704  dladdr_fbases[0] = (void *)addr;
705  }
706  }
707  }
708 #endif
709 
710  /* fill source lines by reading dwarf */
711  for (i = 0; i < num_traces; i++) {
712  Dl_info info;
713  if (lines[i].line) continue;
714  if (dladdr(traces[i], &info)) {
715  const char *path;
716  void **p;
717 
718  /* skip symbols which is in already checked objects */
719  /* if the binary is strip-ed, this may effect */
720  for (p=dladdr_fbases; *p; p++) {
721  if (*p == info.dli_fbase) {
722  lines[i].path = info.dli_fname;
723  lines[i].sname = info.dli_sname;
724  goto next_line;
725  }
726  }
727  *p = info.dli_fbase;
728 
729  append_obj(&obj);
730  obj->base_addr = (uintptr_t)info.dli_fbase;
731  path = info.dli_fname;
732  obj->path = path;
733  lines[i].path = path;
734  strlcpy(binary_filename, path, PATH_MAX);
735  if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
736  break;
737  }
738 next_line:
739  continue;
740  }
741 
742  /* output */
743  for (i = 0; i < num_traces; i++) {
744  line_info_t *line = &lines[i];
745  uintptr_t addr = (uintptr_t)traces[i];
746  uintptr_t d = addr - line->saddr;
747  if (!line->path) {
748  kprintf("[0x%lx]\n", addr);
749  }
750  else if (!line->saddr || !line->sname) {
751  kprintf("%s [0x%lx]\n", line->path, addr);
752  }
753  else if (line->line <= 0) {
754  kprintf("%s(%s+0x%lx) [0x%lx]\n", line->path, line->sname,
755  d, addr);
756  }
757  else if (!line->filename) {
758  kprintf("%s(%s+0x%lx) [0x%lx] ???:%d\n", line->path, line->sname,
759  d, addr, line->line);
760  }
761  else if (line->dirname && line->dirname[0]) {
762  kprintf("%s(%s+0x%lx) [0x%lx] %s/%s:%d\n", line->path, line->sname,
763  d, addr, line->dirname, line->filename, line->line);
764  }
765  else {
766  kprintf("%s(%s+0x%lx) [0x%lx] %s:%d\n", line->path, line->sname,
767  d, addr, line->filename, line->line);
768  }
769  /* FreeBSD's backtrace may show _start and so on */
770  if (line->sname && strcmp("main", line->sname) == 0)
771  break;
772  }
773 
774  /* free */
775  while (obj) {
776  obj_info_t *o = obj;
777  obj = o->next;
778  if (o->fd) {
779  munmap(o->mapped, o->mapped_size);
780  close(o->fd);
781  }
782  free(o);
783  }
784  free(lines);
785  free(dladdr_fbases);
786 }
787 
788 /* From FreeBSD's lib/libstand/printf.c */
789 /*-
790  * Copyright (c) 1986, 1988, 1991, 1993
791  * The Regents of the University of California. All rights reserved.
792  * (c) UNIX System Laboratories, Inc.
793  * All or some portions of this file are derived from material licensed
794  * to the University of California by American Telephone and Telegraph
795  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
796  * the permission of UNIX System Laboratories, Inc.
797  *
798  * Redistribution and use in source and binary forms, with or without
799  * modification, are permitted provided that the following conditions
800  * are met:
801  * 1. Redistributions of source code must retain the above copyright
802  * notice, this list of conditions and the following disclaimer.
803  * 2. Redistributions in binary form must reproduce the above copyright
804  * notice, this list of conditions and the following disclaimer in the
805  * documentation and/or other materials provided with the distribution.
806  * 4. Neither the name of the University nor the names of its contributors
807  * may be used to endorse or promote products derived from this software
808  * without specific prior written permission.
809  *
810  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
811  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
812  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
813  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
814  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
815  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
816  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
817  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
818  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
819  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
820  * SUCH DAMAGE.
821  *
822  * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
823  */
824 
825 #include <stdarg.h>
826 #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
827 static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; }
828 #define hex2ascii(hex) (hex2ascii_data[hex])
829 char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
830 static inline int imax(int a, int b) { return (a > b ? a : b); }
831 static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
832 
833 static void putce(int c)
834 {
835  char s[1];
836  ssize_t ret;
837 
838  s[0] = (char)c;
839  ret = write(2, s, 1);
840  (void)ret;
841 }
842 
843 int
844 kprintf(const char *fmt, ...)
845 {
846  va_list ap;
847  int retval;
848 
849  va_start(ap, fmt);
850  retval = kvprintf(fmt, putce, NULL, 10, ap);
851  va_end(ap);
852  return retval;
853 }
854 
855 /*
856  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
857  * order; return an optional length and a pointer to the last character
858  * written in the buffer (i.e., the first character of the string).
859  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
860  */
861 static char *
862 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
863 {
864  char *p, c;
865 
866  p = nbuf;
867  *p = '\0';
868  do {
869  c = hex2ascii(num % base);
870  *++p = upper ? toupper(c) : c;
871  } while (num /= base);
872  if (lenp)
873  *lenp = (int)(p - nbuf);
874  return (p);
875 }
876 
877 /*
878  * Scaled down version of printf(3).
879  *
880  * Two additional formats:
881  *
882  * The format %b is supported to decode error registers.
883  * Its usage is:
884  *
885  * printf("reg=%b\n", regval, "<base><arg>*");
886  *
887  * where <base> is the output base expressed as a control character, e.g.
888  * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
889  * the first of which gives the bit number to be inspected (origin 1), and
890  * the next characters (up to a control character, i.e. a character <= 32),
891  * give the name of the register. Thus:
892  *
893  * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
894  *
895  * would produce output:
896  *
897  * reg=3<BITTWO,BITONE>
898  *
899  * XXX: %D -- Hexdump, takes pointer and separator string:
900  * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
901  * ("%*D", len, ptr, " " -> XX XX XX XX ...
902  */
903 static int
904 kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
905 {
906 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
907  char nbuf[MAXNBUF];
908  char *d;
909  const char *p, *percent, *q;
910  unsigned char *up;
911  int ch, n;
912  uintmax_t num;
913  int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
914  int cflag, hflag, jflag, tflag, zflag;
915  int dwidth, upper;
916  char padc;
917  int stop = 0, retval = 0;
918 
919  num = 0;
920  if (!func)
921  d = (char *) arg;
922  else
923  d = NULL;
924 
925  if (fmt == NULL)
926  fmt = "(fmt null)\n";
927 
928  if (radix < 2 || radix > 36)
929  radix = 10;
930 
931  for (;;) {
932  padc = ' ';
933  width = 0;
934  while ((ch = (unsigned char)*fmt++) != '%' || stop) {
935  if (ch == '\0')
936  return (retval);
937  PCHAR(ch);
938  }
939  percent = fmt - 1;
940  qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
941  sign = 0; dot = 0; dwidth = 0; upper = 0;
942  cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
943 reswitch: switch (ch = (unsigned char)*fmt++) {
944  case '.':
945  dot = 1;
946  goto reswitch;
947  case '#':
948  sharpflag = 1;
949  goto reswitch;
950  case '+':
951  sign = 1;
952  goto reswitch;
953  case '-':
954  ladjust = 1;
955  goto reswitch;
956  case '%':
957  PCHAR(ch);
958  break;
959  case '*':
960  if (!dot) {
961  width = va_arg(ap, int);
962  if (width < 0) {
963  ladjust = !ladjust;
964  width = -width;
965  }
966  } else {
967  dwidth = va_arg(ap, int);
968  }
969  goto reswitch;
970  case '0':
971  if (!dot) {
972  padc = '0';
973  goto reswitch;
974  }
975  case '1': case '2': case '3': case '4':
976  case '5': case '6': case '7': case '8': case '9':
977  for (n = 0;; ++fmt) {
978  n = n * 10 + ch - '0';
979  ch = *fmt;
980  if (ch < '0' || ch > '9')
981  break;
982  }
983  if (dot)
984  dwidth = n;
985  else
986  width = n;
987  goto reswitch;
988  case 'b':
989  num = (unsigned int)va_arg(ap, int);
990  p = va_arg(ap, char *);
991  for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
992  PCHAR(*q--);
993 
994  if (num == 0)
995  break;
996 
997  for (tmp = 0; *p;) {
998  n = *p++;
999  if (num & (1 << (n - 1))) {
1000  PCHAR(tmp ? ',' : '<');
1001  for (; (n = *p) > ' '; ++p)
1002  PCHAR(n);
1003  tmp = 1;
1004  } else
1005  for (; *p > ' '; ++p)
1006  continue;
1007  }
1008  if (tmp)
1009  PCHAR('>');
1010  break;
1011  case 'c':
1012  PCHAR(va_arg(ap, int));
1013  break;
1014  case 'D':
1015  up = va_arg(ap, unsigned char *);
1016  p = va_arg(ap, char *);
1017  if (!width)
1018  width = 16;
1019  while(width--) {
1020  PCHAR(hex2ascii(*up >> 4));
1021  PCHAR(hex2ascii(*up & 0x0f));
1022  up++;
1023  if (width)
1024  for (q=p;*q;q++)
1025  PCHAR(*q);
1026  }
1027  break;
1028  case 'd':
1029  case 'i':
1030  base = 10;
1031  sign = 1;
1032  goto handle_sign;
1033  case 'h':
1034  if (hflag) {
1035  hflag = 0;
1036  cflag = 1;
1037  } else
1038  hflag = 1;
1039  goto reswitch;
1040  case 'j':
1041  jflag = 1;
1042  goto reswitch;
1043  case 'l':
1044  if (lflag) {
1045  lflag = 0;
1046  qflag = 1;
1047  } else
1048  lflag = 1;
1049  goto reswitch;
1050  case 'n':
1051  if (jflag)
1052  *(va_arg(ap, intmax_t *)) = retval;
1053  else if (qflag)
1054  *(va_arg(ap, int64_t *)) = retval;
1055  else if (lflag)
1056  *(va_arg(ap, long *)) = retval;
1057  else if (zflag)
1058  *(va_arg(ap, size_t *)) = retval;
1059  else if (hflag)
1060  *(va_arg(ap, short *)) = retval;
1061  else if (cflag)
1062  *(va_arg(ap, char *)) = retval;
1063  else
1064  *(va_arg(ap, int *)) = retval;
1065  break;
1066  case 'o':
1067  base = 8;
1068  goto handle_nosign;
1069  case 'p':
1070  base = 16;
1071  sharpflag = (width == 0);
1072  sign = 0;
1073  num = (uintptr_t)va_arg(ap, void *);
1074  goto number;
1075  case 'q':
1076  qflag = 1;
1077  goto reswitch;
1078  case 'r':
1079  base = radix;
1080  if (sign)
1081  goto handle_sign;
1082  goto handle_nosign;
1083  case 's':
1084  p = va_arg(ap, char *);
1085  if (p == NULL)
1086  p = "(null)";
1087  if (!dot)
1088  n = (int)strlen (p);
1089  else
1090  for (n = 0; n < dwidth && p[n]; n++)
1091  continue;
1092 
1093  width -= n;
1094 
1095  if (!ladjust && width > 0)
1096  while (width--)
1097  PCHAR(padc);
1098  while (n--)
1099  PCHAR(*p++);
1100  if (ladjust && width > 0)
1101  while (width--)
1102  PCHAR(padc);
1103  break;
1104  case 't':
1105  tflag = 1;
1106  goto reswitch;
1107  case 'u':
1108  base = 10;
1109  goto handle_nosign;
1110  case 'X':
1111  upper = 1;
1112  case 'x':
1113  base = 16;
1114  goto handle_nosign;
1115  case 'y':
1116  base = 16;
1117  sign = 1;
1118  goto handle_sign;
1119  case 'z':
1120  zflag = 1;
1121  goto reswitch;
1122 handle_nosign:
1123  sign = 0;
1124  if (jflag)
1125  num = va_arg(ap, uintmax_t);
1126  else if (qflag)
1127  num = va_arg(ap, uint64_t);
1128  else if (tflag)
1129  num = va_arg(ap, ptrdiff_t);
1130  else if (lflag)
1131  num = va_arg(ap, unsigned long);
1132  else if (zflag)
1133  num = va_arg(ap, size_t);
1134  else if (hflag)
1135  num = (unsigned short)va_arg(ap, int);
1136  else if (cflag)
1137  num = (unsigned char)va_arg(ap, int);
1138  else
1139  num = va_arg(ap, unsigned int);
1140  goto number;
1141 handle_sign:
1142  if (jflag)
1143  num = va_arg(ap, intmax_t);
1144  else if (qflag)
1145  num = va_arg(ap, int64_t);
1146  else if (tflag)
1147  num = va_arg(ap, ptrdiff_t);
1148  else if (lflag)
1149  num = va_arg(ap, long);
1150  else if (zflag)
1151  num = va_arg(ap, ssize_t);
1152  else if (hflag)
1153  num = (short)va_arg(ap, int);
1154  else if (cflag)
1155  num = (char)va_arg(ap, int);
1156  else
1157  num = va_arg(ap, int);
1158 number:
1159  if (sign && (intmax_t)num < 0) {
1160  neg = 1;
1161  num = -(intmax_t)num;
1162  }
1163  p = ksprintn(nbuf, num, base, &n, upper);
1164  tmp = 0;
1165  if (sharpflag && num != 0) {
1166  if (base == 8)
1167  tmp++;
1168  else if (base == 16)
1169  tmp += 2;
1170  }
1171  if (neg)
1172  tmp++;
1173 
1174  if (!ladjust && padc == '0')
1175  dwidth = width - tmp;
1176  width -= tmp + imax(dwidth, n);
1177  dwidth -= n;
1178  if (!ladjust)
1179  while (width-- > 0)
1180  PCHAR(' ');
1181  if (neg)
1182  PCHAR('-');
1183  if (sharpflag && num != 0) {
1184  if (base == 8) {
1185  PCHAR('0');
1186  } else if (base == 16) {
1187  PCHAR('0');
1188  PCHAR('x');
1189  }
1190  }
1191  while (dwidth-- > 0)
1192  PCHAR('0');
1193 
1194  while (*p)
1195  PCHAR(*p--);
1196 
1197  if (ladjust)
1198  while (width-- > 0)
1199  PCHAR(' ');
1200 
1201  break;
1202  default:
1203  while (percent < fmt)
1204  PCHAR(*percent++);
1205  /*
1206  * Since we ignore an formatting argument it is no
1207  * longer safe to obey the remaining formatting
1208  * arguments as the arguments will no longer match
1209  * the format specs.
1210  */
1211  stop = 1;
1212  break;
1213  }
1214  }
1215 #undef PCHAR
1216 }
1217 #else /* defined(USE_ELF) */
1218 #error not supported
1219 #endif
#define o2(b1, b2)
size_t strlen(const char *)
#define PATH_MAX
ssize_t readlink(const char *, char *, size_t)
Definition: win32.c:5090
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
Definition: zonetab.h:883
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
#define sym(x)
Definition: date_core.c:3721
#define fail()
#define neg(x)
Definition: time.c:131
unsigned long long uint64_t
Definition: sha2.h:102
#define calloc
Definition: ripper.c:360
int err
Definition: win32.c:135
int errno
#define off_t
Definition: io.c:61
unsigned int uintptr_t
Definition: win32.h:106
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
Definition: strlcpy.c:29
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
register unsigned int len
Definition: zonetab.h:51
#define o1(b1)
#define SEEK_END
Definition: io.c:792
int size
Definition: encoding.c:57
#define SIZE_MAX
Definition: ruby.h:276
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
RUBY_SYMBOL_EXPORT_BEGIN void * alloca()
#define NULL
Definition: _sdbm.c:102
free(psz)
#define SEEK_SET
Definition: io.c:790
char * strrchr(const char *, const char)