Ruby  2.4.2p198(2017-09-14revision59899)
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  obj_info_t *newobj = calloc(1, sizeof(obj_info_t));
432  if (*objp) (*objp)->next = newobj;
433  *objp = newobj;
434 }
435 
436 static void
437 follow_debuglink(char *debuglink, int num_traces, void **traces,
438  obj_info_t **objp, line_info_t *lines, int offset)
439 {
440  /* Ideally we should check 4 paths to follow gnu_debuglink,
441  but we handle only one case for now as this format is used
442  by some linux distributions. See GDB's info for detail. */
443  static const char global_debug_dir[] = "/usr/lib/debug";
444  char *p, *subdir;
445  obj_info_t *o1 = *objp, *o2;
446 
447  p = strrchr(binary_filename, '/');
448  if (!p) {
449  return;
450  }
451  p[1] = '\0';
452 
453  subdir = (char *)alloca(strlen(binary_filename) + 1);
454  strcpy(subdir, binary_filename);
455  strcpy(binary_filename, global_debug_dir);
456  strlcat(binary_filename, subdir, PATH_MAX);
457  strlcat(binary_filename, debuglink, PATH_MAX);
458 
459  append_obj(objp);
460  o2 = *objp;
461  o2->base_addr = o1->base_addr;
462  o2->path = o1->path;
463  fill_lines(num_traces, traces, 0, objp, lines, offset);
464 }
465 
466 /* read file and fill lines */
467 static uintptr_t
468 fill_lines(int num_traces, void **traces, int check_debuglink,
469  obj_info_t **objp, line_info_t *lines, int offset)
470 {
471  int i, j;
472  char *shstr;
473  char *section_name;
474  ElfW(Ehdr) *ehdr;
475  ElfW(Shdr) *shdr, *shstr_shdr;
476  ElfW(Shdr) *debug_line_shdr = NULL, *gnu_debuglink_shdr = NULL;
477  int fd;
478  off_t filesize;
479  char *file;
480  ElfW(Shdr) *symtab_shdr = NULL, *strtab_shdr = NULL;
481  ElfW(Shdr) *dynsym_shdr = NULL, *dynstr_shdr = NULL;
482  obj_info_t *obj = *objp;
483  uintptr_t dladdr_fbase = 0;
484 
485  fd = open(binary_filename, O_RDONLY);
486  if (fd < 0) {
487  goto fail;
488  }
489  filesize = lseek(fd, 0, SEEK_END);
490  if (filesize < 0) {
491  int e = errno;
492  close(fd);
493  kprintf("lseek: %s\n", strerror(e));
494  goto fail;
495  }
496 #if SIZEOF_OFF_T > SIZEOF_SIZE_T
497  if (filesize > (off_t)SIZE_MAX) {
498  close(fd);
499  kprintf("Too large file %s\n", binary_filename);
500  goto fail;
501  }
502 #endif
503  lseek(fd, 0, SEEK_SET);
504  /* async-signal unsafe */
505  file = (char *)mmap(NULL, (size_t)filesize, PROT_READ, MAP_SHARED, fd, 0);
506  if (file == MAP_FAILED) {
507  int e = errno;
508  close(fd);
509  kprintf("mmap: %s\n", strerror(e));
510  goto fail;
511  }
512 
513  ehdr = (ElfW(Ehdr) *)file;
514  if (memcmp(ehdr->e_ident, "\177ELF", 4) != 0) {
515  /*
516  * Huh? Maybe filename was overridden by setproctitle() and
517  * it match non-elf file.
518  */
519  close(fd);
520  goto fail;
521  }
522 
523  obj->fd = fd;
524  obj->mapped = file;
525  obj->mapped_size = (size_t)filesize;
526 
527  shdr = (ElfW(Shdr) *)(file + ehdr->e_shoff);
528 
529  shstr_shdr = shdr + ehdr->e_shstrndx;
530  shstr = file + shstr_shdr->sh_offset;
531 
532  for (i = 0; i < ehdr->e_shnum; i++) {
533  section_name = shstr + shdr[i].sh_name;
534  switch (shdr[i].sh_type) {
535  case SHT_STRTAB:
536  if (!strcmp(section_name, ".strtab")) {
537  strtab_shdr = shdr + i;
538  }
539  else if (!strcmp(section_name, ".dynstr")) {
540  dynstr_shdr = shdr + i;
541  }
542  break;
543  case SHT_SYMTAB:
544  /* if (!strcmp(section_name, ".symtab")) */
545  symtab_shdr = shdr + i;
546  break;
547  case SHT_DYNSYM:
548  /* if (!strcmp(section_name, ".dynsym")) */
549  dynsym_shdr = shdr + i;
550  break;
551  case SHT_PROGBITS:
552  if (!strcmp(section_name, ".debug_line")) {
553  debug_line_shdr = shdr + i;
554  }
555  else if (!strcmp(section_name, ".gnu_debuglink")) {
556  gnu_debuglink_shdr = shdr + i;
557  }
558  break;
559  }
560  }
561 
562  if (offset == -1) {
563  /* main executable */
564  offset = 0;
565  if (dynsym_shdr && dynstr_shdr) {
566  char *strtab = file + dynstr_shdr->sh_offset;
567  ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);
568  int symtab_count = (int)(dynsym_shdr->sh_size / sizeof(ElfW(Sym)));
569  for (j = 0; j < symtab_count; j++) {
570  ElfW(Sym) *sym = &symtab[j];
571  Dl_info info;
572  void *h, *s;
573  if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
574  h = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
575  if (!h) continue;
576  s = dlsym(h, strtab + sym->st_name);
577  if (!s) continue;
578  if (dladdr(s, &info)) {
579  dladdr_fbase = (uintptr_t)info.dli_fbase;
580  break;
581  }
582  }
583  if (ehdr->e_type == ET_EXEC) {
584  obj->base_addr = 0;
585  }
586  else {
587  /* PIE (position-independent executable) */
588  obj->base_addr = dladdr_fbase;
589  }
590  }
591  }
592 
593  if (!symtab_shdr) {
594  symtab_shdr = dynsym_shdr;
595  strtab_shdr = dynstr_shdr;
596  }
597 
598  if (symtab_shdr && strtab_shdr) {
599  char *strtab = file + strtab_shdr->sh_offset;
600  ElfW(Sym) *symtab = (ElfW(Sym) *)(file + symtab_shdr->sh_offset);
601  int symtab_count = (int)(symtab_shdr->sh_size / sizeof(ElfW(Sym)));
602  for (j = 0; j < symtab_count; j++) {
603  ElfW(Sym) *sym = &symtab[j];
604  uintptr_t saddr = (uintptr_t)sym->st_value + obj->base_addr;
605  if (ELF_ST_TYPE(sym->st_info) != STT_FUNC || sym->st_size <= 0) continue;
606  for (i = offset; i < num_traces; i++) {
607  uintptr_t d = (uintptr_t)traces[i] - saddr;
608  if (lines[i].line > 0 || d <= 0 || d > (uintptr_t)sym->st_size)
609  continue;
610  /* fill symbol name and addr from .symtab */
611  lines[i].sname = strtab + sym->st_name;
612  lines[i].saddr = saddr;
613  lines[i].path = obj->path;
614  lines[i].base_addr = obj->base_addr;
615  }
616  }
617  }
618 
619  if (!debug_line_shdr) {
620  /* This file doesn't have .debug_line section,
621  let's check .gnu_debuglink section instead. */
622  if (gnu_debuglink_shdr && check_debuglink) {
623  follow_debuglink(file + gnu_debuglink_shdr->sh_offset,
624  num_traces, traces,
625  objp, lines, offset);
626  }
627  goto finish;
628  }
629 
630  if (parse_debug_line(num_traces, traces,
631  file + debug_line_shdr->sh_offset,
632  debug_line_shdr->sh_size,
633  obj, lines, offset))
634  goto fail;
635 finish:
636  return dladdr_fbase;
637 fail:
638  return (uintptr_t)-1;
639 }
640 
641 #define HAVE_MAIN_EXE_PATH
642 #if defined(__FreeBSD__)
643 # include <sys/sysctl.h>
644 #endif
645 /* ssize_t main_exe_path(void)
646  *
647  * store the path of the main executable to `binary_filename`,
648  * and returns strlen(binary_filename).
649  * it is NUL terminated.
650  */
651 #if defined(__linux__)
652 ssize_t
653 main_exe_path(void)
654 {
655 # define PROC_SELF_EXE "/proc/self/exe"
656  ssize_t len = readlink(PROC_SELF_EXE, binary_filename, PATH_MAX);
657  binary_filename[len] = 0;
658  return len;
659 }
660 #elif defined(__FreeBSD__)
661 ssize_t
662 main_exe_path(void)
663 {
664  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
665  size_t len = PATH_MAX;
666  int err = sysctl(mib, 4, binary_filename, &len, NULL, 0);
667  if (err) {
668  kprintf("Can't get the path of ruby");
669  return -1;
670  }
671  len--; /* sysctl sets strlen+1 */
672  return len;
673 }
674 #else
675 #undef HAVE_MAIN_EXE_PATH
676 #endif
677 
678 void
679 rb_dump_backtrace_with_lines(int num_traces, void **traces)
680 {
681  int i;
682  /* async-signal unsafe */
683  line_info_t *lines = (line_info_t *)calloc(num_traces, sizeof(line_info_t));
684  obj_info_t *obj = NULL;
685  /* 2 is NULL + main executable */
686  void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
687 #ifdef HAVE_MAIN_EXE_PATH
688  char *main_path = NULL; /* used on printing backtrace */
689  ssize_t len;
690  if ((len = main_exe_path()) > 0) {
691  main_path = (char *)alloca(len + 1);
692  if (main_path) {
693  uintptr_t addr;
694  memcpy(main_path, binary_filename, len+1);
695  append_obj(&obj);
696  obj->path = main_path;
697  addr = fill_lines(num_traces, traces, 1, &obj, lines, -1);
698  if (addr != (uintptr_t)-1) {
699  dladdr_fbases[0] = (void *)addr;
700  }
701  }
702  }
703 #endif
704 
705  /* fill source lines by reading dwarf */
706  for (i = 0; i < num_traces; i++) {
707  Dl_info info;
708  if (lines[i].line) continue;
709  if (dladdr(traces[i], &info)) {
710  const char *path;
711  void **p;
712 
713  /* skip symbols which is in already checked objects */
714  /* if the binary is strip-ed, this may effect */
715  for (p=dladdr_fbases; *p; p++) {
716  if (*p == info.dli_fbase) {
717  lines[i].path = info.dli_fname;
718  lines[i].sname = info.dli_sname;
719  goto next_line;
720  }
721  }
722  *p = info.dli_fbase;
723 
724  append_obj(&obj);
725  obj->base_addr = (uintptr_t)info.dli_fbase;
726  path = info.dli_fname;
727  obj->path = path;
728  lines[i].path = path;
729  strcpy(binary_filename, path);
730  if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1)
731  break;
732  }
733 next_line:
734  continue;
735  }
736 
737  /* output */
738  for (i = 0; i < num_traces; i++) {
739  line_info_t *line = &lines[i];
740  uintptr_t addr = (uintptr_t)traces[i];
741  uintptr_t d = addr - line->saddr;
742  if (!line->path) {
743  kprintf("[0x%lx]\n", addr);
744  }
745  else if (!line->saddr || !line->sname) {
746  kprintf("%s [0x%lx]\n", line->path, addr);
747  }
748  else if (line->line <= 0) {
749  kprintf("%s(%s+0x%lx) [0x%lx]\n", line->path, line->sname,
750  d, addr);
751  }
752  else if (!line->filename) {
753  kprintf("%s(%s+0x%lx) [0x%lx] ???:%d\n", line->path, line->sname,
754  d, addr, line->line);
755  }
756  else if (line->dirname && line->dirname[0]) {
757  kprintf("%s(%s+0x%lx) [0x%lx] %s/%s:%d\n", line->path, line->sname,
758  d, addr, line->dirname, line->filename, line->line);
759  }
760  else {
761  kprintf("%s(%s+0x%lx) [0x%lx] %s:%d\n", line->path, line->sname,
762  d, addr, line->filename, line->line);
763  }
764  /* FreeBSD's backtrace may show _start and so on */
765  if (line->sname && strcmp("main", line->sname) == 0)
766  break;
767  }
768 
769  /* free */
770  while (obj) {
771  obj_info_t *o = obj;
772  obj = o->next;
773  if (o->fd) {
774  munmap(o->mapped, o->mapped_size);
775  close(o->fd);
776  }
777  free(o);
778  }
779  free(lines);
780  free(dladdr_fbases);
781 }
782 
783 /* From FreeBSD's lib/libstand/printf.c */
784 /*-
785  * Copyright (c) 1986, 1988, 1991, 1993
786  * The Regents of the University of California. All rights reserved.
787  * (c) UNIX System Laboratories, Inc.
788  * All or some portions of this file are derived from material licensed
789  * to the University of California by American Telephone and Telegraph
790  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
791  * the permission of UNIX System Laboratories, Inc.
792  *
793  * Redistribution and use in source and binary forms, with or without
794  * modification, are permitted provided that the following conditions
795  * are met:
796  * 1. Redistributions of source code must retain the above copyright
797  * notice, this list of conditions and the following disclaimer.
798  * 2. Redistributions in binary form must reproduce the above copyright
799  * notice, this list of conditions and the following disclaimer in the
800  * documentation and/or other materials provided with the distribution.
801  * 4. Neither the name of the University nor the names of its contributors
802  * may be used to endorse or promote products derived from this software
803  * without specific prior written permission.
804  *
805  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
806  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
807  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
808  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
809  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
810  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
811  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
812  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
813  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
814  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
815  * SUCH DAMAGE.
816  *
817  * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
818  */
819 
820 #include <stdarg.h>
821 #define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1)
822 static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; }
823 #define hex2ascii(hex) (hex2ascii_data[hex])
824 char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
825 static inline int imax(int a, int b) { return (a > b ? a : b); }
826 static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap);
827 
828 static void putce(int c)
829 {
830  char s[1];
831  ssize_t ret;
832 
833  s[0] = (char)c;
834  ret = write(2, s, 1);
835  (void)ret;
836 }
837 
838 int
839 kprintf(const char *fmt, ...)
840 {
841  va_list ap;
842  int retval;
843 
844  va_start(ap, fmt);
845  retval = kvprintf(fmt, putce, NULL, 10, ap);
846  va_end(ap);
847  return retval;
848 }
849 
850 /*
851  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
852  * order; return an optional length and a pointer to the last character
853  * written in the buffer (i.e., the first character of the string).
854  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
855  */
856 static char *
857 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
858 {
859  char *p, c;
860 
861  p = nbuf;
862  *p = '\0';
863  do {
864  c = hex2ascii(num % base);
865  *++p = upper ? toupper(c) : c;
866  } while (num /= base);
867  if (lenp)
868  *lenp = (int)(p - nbuf);
869  return (p);
870 }
871 
872 /*
873  * Scaled down version of printf(3).
874  *
875  * Two additional formats:
876  *
877  * The format %b is supported to decode error registers.
878  * Its usage is:
879  *
880  * printf("reg=%b\n", regval, "<base><arg>*");
881  *
882  * where <base> is the output base expressed as a control character, e.g.
883  * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
884  * the first of which gives the bit number to be inspected (origin 1), and
885  * the next characters (up to a control character, i.e. a character <= 32),
886  * give the name of the register. Thus:
887  *
888  * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
889  *
890  * would produce output:
891  *
892  * reg=3<BITTWO,BITONE>
893  *
894  * XXX: %D -- Hexdump, takes pointer and separator string:
895  * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
896  * ("%*D", len, ptr, " " -> XX XX XX XX ...
897  */
898 static int
899 kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap)
900 {
901 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; }
902  char nbuf[MAXNBUF];
903  char *d;
904  const char *p, *percent, *q;
905  unsigned char *up;
906  int ch, n;
907  uintmax_t num;
908  int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
909  int cflag, hflag, jflag, tflag, zflag;
910  int dwidth, upper;
911  char padc;
912  int stop = 0, retval = 0;
913 
914  num = 0;
915  if (!func)
916  d = (char *) arg;
917  else
918  d = NULL;
919 
920  if (fmt == NULL)
921  fmt = "(fmt null)\n";
922 
923  if (radix < 2 || radix > 36)
924  radix = 10;
925 
926  for (;;) {
927  padc = ' ';
928  width = 0;
929  while ((ch = (unsigned char)*fmt++) != '%' || stop) {
930  if (ch == '\0')
931  return (retval);
932  PCHAR(ch);
933  }
934  percent = fmt - 1;
935  qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
936  sign = 0; dot = 0; dwidth = 0; upper = 0;
937  cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
938 reswitch: switch (ch = (unsigned char)*fmt++) {
939  case '.':
940  dot = 1;
941  goto reswitch;
942  case '#':
943  sharpflag = 1;
944  goto reswitch;
945  case '+':
946  sign = 1;
947  goto reswitch;
948  case '-':
949  ladjust = 1;
950  goto reswitch;
951  case '%':
952  PCHAR(ch);
953  break;
954  case '*':
955  if (!dot) {
956  width = va_arg(ap, int);
957  if (width < 0) {
958  ladjust = !ladjust;
959  width = -width;
960  }
961  } else {
962  dwidth = va_arg(ap, int);
963  }
964  goto reswitch;
965  case '0':
966  if (!dot) {
967  padc = '0';
968  goto reswitch;
969  }
970  case '1': case '2': case '3': case '4':
971  case '5': case '6': case '7': case '8': case '9':
972  for (n = 0;; ++fmt) {
973  n = n * 10 + ch - '0';
974  ch = *fmt;
975  if (ch < '0' || ch > '9')
976  break;
977  }
978  if (dot)
979  dwidth = n;
980  else
981  width = n;
982  goto reswitch;
983  case 'b':
984  num = (unsigned int)va_arg(ap, int);
985  p = va_arg(ap, char *);
986  for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
987  PCHAR(*q--);
988 
989  if (num == 0)
990  break;
991 
992  for (tmp = 0; *p;) {
993  n = *p++;
994  if (num & (1 << (n - 1))) {
995  PCHAR(tmp ? ',' : '<');
996  for (; (n = *p) > ' '; ++p)
997  PCHAR(n);
998  tmp = 1;
999  } else
1000  for (; *p > ' '; ++p)
1001  continue;
1002  }
1003  if (tmp)
1004  PCHAR('>');
1005  break;
1006  case 'c':
1007  PCHAR(va_arg(ap, int));
1008  break;
1009  case 'D':
1010  up = va_arg(ap, unsigned char *);
1011  p = va_arg(ap, char *);
1012  if (!width)
1013  width = 16;
1014  while(width--) {
1015  PCHAR(hex2ascii(*up >> 4));
1016  PCHAR(hex2ascii(*up & 0x0f));
1017  up++;
1018  if (width)
1019  for (q=p;*q;q++)
1020  PCHAR(*q);
1021  }
1022  break;
1023  case 'd':
1024  case 'i':
1025  base = 10;
1026  sign = 1;
1027  goto handle_sign;
1028  case 'h':
1029  if (hflag) {
1030  hflag = 0;
1031  cflag = 1;
1032  } else
1033  hflag = 1;
1034  goto reswitch;
1035  case 'j':
1036  jflag = 1;
1037  goto reswitch;
1038  case 'l':
1039  if (lflag) {
1040  lflag = 0;
1041  qflag = 1;
1042  } else
1043  lflag = 1;
1044  goto reswitch;
1045  case 'n':
1046  if (jflag)
1047  *(va_arg(ap, intmax_t *)) = retval;
1048  else if (qflag)
1049  *(va_arg(ap, int64_t *)) = retval;
1050  else if (lflag)
1051  *(va_arg(ap, long *)) = retval;
1052  else if (zflag)
1053  *(va_arg(ap, size_t *)) = retval;
1054  else if (hflag)
1055  *(va_arg(ap, short *)) = retval;
1056  else if (cflag)
1057  *(va_arg(ap, char *)) = retval;
1058  else
1059  *(va_arg(ap, int *)) = retval;
1060  break;
1061  case 'o':
1062  base = 8;
1063  goto handle_nosign;
1064  case 'p':
1065  base = 16;
1066  sharpflag = (width == 0);
1067  sign = 0;
1068  num = (uintptr_t)va_arg(ap, void *);
1069  goto number;
1070  case 'q':
1071  qflag = 1;
1072  goto reswitch;
1073  case 'r':
1074  base = radix;
1075  if (sign)
1076  goto handle_sign;
1077  goto handle_nosign;
1078  case 's':
1079  p = va_arg(ap, char *);
1080  if (p == NULL)
1081  p = "(null)";
1082  if (!dot)
1083  n = (int)strlen (p);
1084  else
1085  for (n = 0; n < dwidth && p[n]; n++)
1086  continue;
1087 
1088  width -= n;
1089 
1090  if (!ladjust && width > 0)
1091  while (width--)
1092  PCHAR(padc);
1093  while (n--)
1094  PCHAR(*p++);
1095  if (ladjust && width > 0)
1096  while (width--)
1097  PCHAR(padc);
1098  break;
1099  case 't':
1100  tflag = 1;
1101  goto reswitch;
1102  case 'u':
1103  base = 10;
1104  goto handle_nosign;
1105  case 'X':
1106  upper = 1;
1107  case 'x':
1108  base = 16;
1109  goto handle_nosign;
1110  case 'y':
1111  base = 16;
1112  sign = 1;
1113  goto handle_sign;
1114  case 'z':
1115  zflag = 1;
1116  goto reswitch;
1117 handle_nosign:
1118  sign = 0;
1119  if (jflag)
1120  num = va_arg(ap, uintmax_t);
1121  else if (qflag)
1122  num = va_arg(ap, uint64_t);
1123  else if (tflag)
1124  num = va_arg(ap, ptrdiff_t);
1125  else if (lflag)
1126  num = va_arg(ap, unsigned long);
1127  else if (zflag)
1128  num = va_arg(ap, size_t);
1129  else if (hflag)
1130  num = (unsigned short)va_arg(ap, int);
1131  else if (cflag)
1132  num = (unsigned char)va_arg(ap, int);
1133  else
1134  num = va_arg(ap, unsigned int);
1135  goto number;
1136 handle_sign:
1137  if (jflag)
1138  num = va_arg(ap, intmax_t);
1139  else if (qflag)
1140  num = va_arg(ap, int64_t);
1141  else if (tflag)
1142  num = va_arg(ap, ptrdiff_t);
1143  else if (lflag)
1144  num = va_arg(ap, long);
1145  else if (zflag)
1146  num = va_arg(ap, ssize_t);
1147  else if (hflag)
1148  num = (short)va_arg(ap, int);
1149  else if (cflag)
1150  num = (char)va_arg(ap, int);
1151  else
1152  num = va_arg(ap, int);
1153 number:
1154  if (sign && (intmax_t)num < 0) {
1155  neg = 1;
1156  num = -(intmax_t)num;
1157  }
1158  p = ksprintn(nbuf, num, base, &n, upper);
1159  tmp = 0;
1160  if (sharpflag && num != 0) {
1161  if (base == 8)
1162  tmp++;
1163  else if (base == 16)
1164  tmp += 2;
1165  }
1166  if (neg)
1167  tmp++;
1168 
1169  if (!ladjust && padc == '0')
1170  dwidth = width - tmp;
1171  width -= tmp + imax(dwidth, n);
1172  dwidth -= n;
1173  if (!ladjust)
1174  while (width-- > 0)
1175  PCHAR(' ');
1176  if (neg)
1177  PCHAR('-');
1178  if (sharpflag && num != 0) {
1179  if (base == 8) {
1180  PCHAR('0');
1181  } else if (base == 16) {
1182  PCHAR('0');
1183  PCHAR('x');
1184  }
1185  }
1186  while (dwidth-- > 0)
1187  PCHAR('0');
1188 
1189  while (*p)
1190  PCHAR(*p--);
1191 
1192  if (ladjust)
1193  while (width-- > 0)
1194  PCHAR(' ');
1195 
1196  break;
1197  default:
1198  while (percent < fmt)
1199  PCHAR(*percent++);
1200  /*
1201  * Since we ignore an formatting argument it is no
1202  * longer safe to obey the remaining formatting
1203  * arguments as the arguments will no longer match
1204  * the format specs.
1205  */
1206  stop = 1;
1207  break;
1208  }
1209  }
1210 #undef PCHAR
1211 }
1212 #else /* defined(USE_ELF) */
1213 #error not supported
1214 #endif
#define o2(b1, b2)
size_t strlen(const char *)
#define PATH_MAX
ssize_t readlink(const char *, char *, size_t)
Definition: win32.c:5031
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
Definition: zonetab.h:883
#define sym(x)
Definition: date_core.c:3721
#define fail()
#define neg(x)
Definition: time.c:119
unsigned long long uint64_t
Definition: sha2.h:102
static const char * obj_info(VALUE obj)
Definition: gc.c:9362
#define calloc
Definition: ripper.c:118
int err
Definition: win32.c:135
int errno
#define off_t
Definition: io.c:61
unsigned int uintptr_t
Definition: win32.h:106
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
char * alloca()
register unsigned int len
Definition: zonetab.h:51
#define o1(b1)
#define SEEK_END
Definition: io.c:790
int size
Definition: encoding.c:57
#define SIZE_MAX
Definition: ruby.h:276
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
RUBY_EXTERN size_t strlcat(char *, const char *, size_t)
Definition: strlcat.c:31
#define memcpy(d, s, n)
Definition: ffi_common.h:55
#define NULL
Definition: _sdbm.c:102
free(psz)
#define SEEK_SET
Definition: io.c:788
char * strrchr(const char *, const char)