1 /* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
2    Copyright (C) 2015-2018 Free Software Foundation, Inc.
3    Adapted from elf.c by Tristan Gingold, AdaCore.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9     (1) Redistributions of source code must retain the above copyright
10     notice, this list of conditions and the following disclaimer.
11 
12     (2) Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions and the following disclaimer in
14     the documentation and/or other materials provided with the
15     distribution.
16 
17     (3) The name of the author may not be used to
18     endorse or promote products derived from this software without
19     specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.  */
32 
33 #include "config.h"
34 
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 
39 #include "backtrace.h"
40 #include "internal.h"
41 
42 /* Coff file header.  */
43 
44 typedef struct {
45   uint16_t machine;
46   uint16_t number_of_sections;
47   uint32_t time_date_stamp;
48   uint32_t pointer_to_symbol_table;
49   uint32_t number_of_symbols;
50   uint16_t size_of_optional_header;
51   uint16_t characteristics;
52 } b_coff_file_header;
53 
54 /* Coff optional header.  */
55 
56 typedef struct {
57   uint16_t magic;
58   uint8_t  major_linker_version;
59   uint8_t  minor_linker_version;
60   uint32_t size_of_code;
61   uint32_t size_of_initialized_data;
62   uint32_t size_of_uninitialized_data;
63   uint32_t address_of_entry_point;
64   uint32_t base_of_code;
65   union {
66     struct {
67       uint32_t base_of_data;
68       uint32_t image_base;
69     } pe;
70     struct {
71       uint64_t image_base;
72     } pep;
73   } u;
74 } b_coff_optional_header;
75 
76 /* Values of magic in optional header.  */
77 
78 #define PE_MAGIC 0x10b		/* PE32 executable.  */
79 #define PEP_MAGIC 0x20b		/* PE32+ executable (for 64bit targets).  */
80 
81 /* Coff section header.  */
82 
83 typedef struct {
84   char name[8];
85   uint32_t virtual_size;
86   uint32_t virtual_address;
87   uint32_t size_of_raw_data;
88   uint32_t pointer_to_raw_data;
89   uint32_t pointer_to_relocations;
90   uint32_t pointer_to_line_numbers;
91   uint16_t number_of_relocations;
92   uint16_t number_of_line_numbers;
93   uint32_t characteristics;
94 } b_coff_section_header;
95 
96 /* Coff symbol name.  */
97 
98 typedef union {
99   char short_name[8];
100   struct {
101     unsigned char zeroes[4];
102     unsigned char off[4];
103   } long_name;
104 } b_coff_name;
105 
106 /* Coff symbol (external representation which is unaligned).  */
107 
108 typedef struct {
109   b_coff_name name;
110   unsigned char value[4];
111   unsigned char section_number[2];
112   unsigned char type[2];
113   unsigned char storage_class;
114   unsigned char number_of_aux_symbols;
115 } b_coff_external_symbol;
116 
117 /* Symbol types.  */
118 
119 #define N_TBSHFT 4			/* Shift for the derived type.  */
120 #define IMAGE_SYM_DTYPE_FUNCTION 2	/* Function derived type.  */
121 
122 /* Size of a coff symbol.  */
123 
124 #define SYM_SZ 18
125 
126 /* Coff symbol, internal representation (aligned).  */
127 
128 typedef struct {
129   const char *name;
130   uint32_t value;
131   int16_t sec;
132   uint16_t type;
133   uint16_t sc;
134 } b_coff_internal_symbol;
135 
136 /* An index of sections we care about.  */
137 
138 enum debug_section
139 {
140   DEBUG_INFO,
141   DEBUG_LINE,
142   DEBUG_ABBREV,
143   DEBUG_RANGES,
144   DEBUG_STR,
145   DEBUG_MAX
146 };
147 
148 /* Names of sections, indexed by enum debug_section.  */
149 
150 static const char * const debug_section_names[DEBUG_MAX] =
151 {
152   ".debug_info",
153   ".debug_line",
154   ".debug_abbrev",
155   ".debug_ranges",
156   ".debug_str"
157 };
158 
159 /* Information we gather for the sections we care about.  */
160 
161 struct debug_section_info
162 {
163   /* Section file offset.  */
164   off_t offset;
165   /* Section size.  */
166   size_t size;
167   /* Section contents, after read from file.  */
168   const unsigned char *data;
169 };
170 
171 /* Information we keep for an coff symbol.  */
172 
173 struct coff_symbol
174 {
175   /* The name of the symbol.  */
176   const char *name;
177   /* The address of the symbol.  */
178   uintptr_t address;
179 };
180 
181 /* Information to pass to coff_syminfo.  */
182 
183 struct coff_syminfo_data
184 {
185   /* Symbols for the next module.  */
186   struct coff_syminfo_data *next;
187   /* The COFF symbols, sorted by address.  */
188   struct coff_symbol *symbols;
189   /* The number of symbols.  */
190   size_t count;
191 };
192 
193 /* A dummy callback function used when we can't find any debug info.  */
194 
195 static int
196 coff_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
197 	      uintptr_t pc ATTRIBUTE_UNUSED,
198 	      backtrace_full_callback callback ATTRIBUTE_UNUSED,
199 	      backtrace_error_callback error_callback, void *data)
200 {
201   error_callback (data, "no debug info in PE/COFF executable", -1);
202   return 0;
203 }
204 
205 /* A dummy callback function used when we can't find a symbol
206    table.  */
207 
208 static void
209 coff_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
210 	     uintptr_t addr ATTRIBUTE_UNUSED,
211 	     backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
212 	     backtrace_error_callback error_callback, void *data)
213 {
214   error_callback (data, "no symbol table in PE/COFF executable", -1);
215 }
216 
217 /* Read a potentially unaligned 4 byte word at P, using native endianness.  */
218 
219 static uint32_t
220 coff_read4 (const unsigned char *p)
221 {
222   uint32_t res;
223 
224   memcpy (&res, p, 4);
225   return res;
226 }
227 
228 /* Read a potentially unaligned 2 byte word at P, using native endianness.
229    All 2 byte word in symbols are always aligned, but for coherency all
230    fields are declared as char arrays.  */
231 
232 static uint16_t
233 coff_read2 (const unsigned char *p)
234 {
235   uint16_t res;
236 
237   memcpy (&res, p, sizeof (res));
238   return res;
239 }
240 
241 /* Return the length (without the trailing 0) of a COFF short name.  */
242 
243 static size_t
244 coff_short_name_len (const char *name)
245 {
246   int i;
247 
248   for (i = 0; i < 8; i++)
249     if (name[i] == 0)
250       return i;
251   return 8;
252 }
253 
254 /* Return true iff COFF short name CNAME is the same as NAME (a NUL-terminated
255    string).  */
256 
257 static int
258 coff_short_name_eq (const char *name, const char *cname)
259 {
260   int i;
261 
262   for (i = 0; i < 8; i++)
263     {
264       if (name[i] != cname[i])
265 	return 0;
266       if (name[i] == 0)
267 	return 1;
268     }
269   return name[8] == 0;
270 }
271 
272 /* Return true iff NAME is the same as string at offset OFF.  */
273 
274 static int
275 coff_long_name_eq (const char *name, unsigned int off,
276 		   struct backtrace_view *str_view)
277 {
278   if (off >= str_view->len)
279     return 0;
280   return strcmp (name, (const char *)str_view->data + off) == 0;
281 }
282 
283 /* Compare struct coff_symbol for qsort.  */
284 
285 static int
286 coff_symbol_compare (const void *v1, const void *v2)
287 {
288   const struct coff_symbol *e1 = (const struct coff_symbol *) v1;
289   const struct coff_symbol *e2 = (const struct coff_symbol *) v2;
290 
291   if (e1->address < e2->address)
292     return -1;
293   else if (e1->address > e2->address)
294     return 1;
295   else
296     return 0;
297 }
298 
299 /* Convert SYM to internal (and aligned) format ISYM, using string table
300    from STRTAB and STRTAB_SIZE, and number of sections SECTS_NUM.
301    Return -1 in case of error (invalid section number or string index).  */
302 
303 static int
304 coff_expand_symbol (b_coff_internal_symbol *isym,
305 		    const b_coff_external_symbol *sym,
306 		    uint16_t sects_num,
307 		    const unsigned char *strtab, size_t strtab_size)
308 {
309   isym->type = coff_read2 (sym->type);
310   isym->sec = coff_read2 (sym->section_number);
311   isym->sc = sym->storage_class;
312 
313   if (isym->sec > 0 && (uint16_t) isym->sec > sects_num)
314     return -1;
315   if (sym->name.short_name[0] != 0)
316     isym->name = sym->name.short_name;
317   else
318     {
319       uint32_t off = coff_read4 (sym->name.long_name.off);
320 
321       if (off >= strtab_size)
322 	return -1;
323       isym->name = (const char *) strtab + off;
324     }
325   return 0;
326 }
327 
328 /* Return true iff SYM is a defined symbol for a function.  Data symbols
329    aren't considered because they aren't easily identified (same type as
330    section names, presence of symbols defined by the linker script).  */
331 
332 static int
333 coff_is_function_symbol (const b_coff_internal_symbol *isym)
334 {
335   return (isym->type >> N_TBSHFT) == IMAGE_SYM_DTYPE_FUNCTION
336     && isym->sec > 0;
337 }
338 
339 /* Initialize the symbol table info for coff_syminfo.  */
340 
341 static int
342 coff_initialize_syminfo (struct backtrace_state *state,
343 			 uintptr_t base_address,
344 			 const b_coff_section_header *sects, size_t sects_num,
345 			 const b_coff_external_symbol *syms, size_t syms_size,
346 			 const unsigned char *strtab, size_t strtab_size,
347 			 backtrace_error_callback error_callback,
348 			 void *data, struct coff_syminfo_data *sdata)
349 {
350   size_t syms_count;
351   char *coff_symstr;
352   size_t coff_symstr_len;
353   size_t coff_symbol_count;
354   size_t coff_symbol_size;
355   struct coff_symbol *coff_symbols;
356   struct coff_symbol *coff_sym;
357   char *coff_str;
358   size_t i;
359 
360   syms_count = syms_size / SYM_SZ;
361 
362   /* We only care about function symbols.  Count them.  Also count size of
363      strings for in-symbol names.  */
364   coff_symbol_count = 0;
365   coff_symstr_len = 0;
366   for (i = 0; i < syms_count; ++i)
367     {
368       const b_coff_external_symbol *asym = &syms[i];
369       b_coff_internal_symbol isym;
370 
371       if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size) < 0)
372 	{
373 	  error_callback (data, "invalid section or offset in coff symbol", 0);
374 	  return 0;
375 	}
376       if (coff_is_function_symbol (&isym))
377 	{
378 	  ++coff_symbol_count;
379 	  if (asym->name.short_name[0] != 0)
380 	    coff_symstr_len += coff_short_name_len (asym->name.short_name) + 1;
381 	}
382 
383       i += asym->number_of_aux_symbols;
384     }
385 
386   coff_symbol_size = (coff_symbol_count + 1) * sizeof (struct coff_symbol);
387   coff_symbols = ((struct coff_symbol *)
388 		  backtrace_alloc (state, coff_symbol_size, error_callback,
389 				   data));
390   if (coff_symbols == NULL)
391     return 0;
392 
393   /* Allocate memory for symbols strings.  */
394   if (coff_symstr_len > 0)
395     {
396       coff_symstr = ((char *)
397 		     backtrace_alloc (state, coff_symstr_len, error_callback,
398 				      data));
399       if (coff_symstr == NULL)
400 	{
401 	  backtrace_free (state, coff_symbols, coff_symbol_size,
402 			  error_callback, data);
403 	  return 0;
404 	}
405     }
406   else
407     coff_symstr = NULL;
408 
409   /* Copy symbols.  */
410   coff_sym = coff_symbols;
411   coff_str = coff_symstr;
412   for (i = 0; i < syms_count; ++i)
413     {
414       const b_coff_external_symbol *asym = &syms[i];
415       b_coff_internal_symbol isym;
416 
417       if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size))
418 	{
419 	  /* Should not fail, as it was already tested in the previous
420 	     loop.  */
421 	  abort ();
422 	}
423       if (coff_is_function_symbol (&isym))
424 	{
425 	  const char *name;
426 	  int16_t secnum;
427 
428 	  if (asym->name.short_name[0] != 0)
429 	    {
430 	      size_t len = coff_short_name_len (isym.name);
431 	      name = coff_str;
432 	      memcpy (coff_str, isym.name, len);
433 	      coff_str[len] = 0;
434 	      coff_str += len + 1;
435 	    }
436 	  else
437 	    name = isym.name;
438 
439 	  /* Strip leading '_'.  */
440 	  if (name[0] == '_')
441 	    name++;
442 
443 	  /* Symbol value is section relative, so we need to read the address
444 	     of its section.  */
445 	  secnum = coff_read2 (asym->section_number);
446 
447 	  coff_sym->name = name;
448 	  coff_sym->address = (coff_read4 (asym->value)
449 			       + sects[secnum - 1].virtual_address
450 			       + base_address);
451 	  coff_sym++;
452 	}
453 
454       i += asym->number_of_aux_symbols;
455     }
456 
457   /* End of symbols marker.  */
458   coff_sym->name = NULL;
459   coff_sym->address = -1;
460 
461   backtrace_qsort (coff_symbols, coff_symbol_count,
462 		   sizeof (struct coff_symbol), coff_symbol_compare);
463 
464   sdata->next = NULL;
465   sdata->symbols = coff_symbols;
466   sdata->count = coff_symbol_count;
467 
468   return 1;
469 }
470 
471 /* Add EDATA to the list in STATE.  */
472 
473 static void
474 coff_add_syminfo_data (struct backtrace_state *state,
475 		       struct coff_syminfo_data *sdata)
476 {
477   if (!state->threaded)
478     {
479       struct coff_syminfo_data **pp;
480 
481       for (pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
482 	   *pp != NULL;
483 	   pp = &(*pp)->next)
484 	;
485       *pp = sdata;
486     }
487   else
488     {
489       while (1)
490 	{
491 	  struct coff_syminfo_data **pp;
492 
493 	  pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
494 
495 	  while (1)
496 	    {
497 	      struct coff_syminfo_data *p;
498 
499 	      p = backtrace_atomic_load_pointer (pp);
500 
501 	      if (p == NULL)
502 		break;
503 
504 	      pp = &p->next;
505 	    }
506 
507 	  if (__sync_bool_compare_and_swap (pp, NULL, sdata))
508 	    break;
509 	}
510     }
511 }
512 
513 /* Compare an ADDR against an elf_symbol for bsearch.  We allocate one
514    extra entry in the array so that this can look safely at the next
515    entry.  */
516 
517 static int
518 coff_symbol_search (const void *vkey, const void *ventry)
519 {
520   const uintptr_t *key = (const uintptr_t *) vkey;
521   const struct coff_symbol *entry = (const struct coff_symbol *) ventry;
522   uintptr_t addr;
523 
524   addr = *key;
525   if (addr < entry->address)
526     return -1;
527   else if (addr >= entry[1].address)
528     return 1;
529   else
530     return 0;
531 }
532 
533 /* Return the symbol name and value for an ADDR.  */
534 
535 static void
536 coff_syminfo (struct backtrace_state *state, uintptr_t addr,
537 	      backtrace_syminfo_callback callback,
538 	      backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
539 	      void *data)
540 {
541   struct coff_syminfo_data *sdata;
542   struct coff_symbol *sym = NULL;
543 
544   if (!state->threaded)
545     {
546       for (sdata = (struct coff_syminfo_data *) state->syminfo_data;
547 	   sdata != NULL;
548 	   sdata = sdata->next)
549 	{
550 	  sym = ((struct coff_symbol *)
551 		 bsearch (&addr, sdata->symbols, sdata->count,
552 			  sizeof (struct coff_symbol), coff_symbol_search));
553 	  if (sym != NULL)
554 	    break;
555 	}
556     }
557   else
558     {
559       struct coff_syminfo_data **pp;
560 
561       pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
562       while (1)
563 	{
564 	  sdata = backtrace_atomic_load_pointer (pp);
565 	  if (sdata == NULL)
566 	    break;
567 
568 	  sym = ((struct coff_symbol *)
569 		 bsearch (&addr, sdata->symbols, sdata->count,
570 			  sizeof (struct coff_symbol), coff_symbol_search));
571 	  if (sym != NULL)
572 	    break;
573 
574 	  pp = &sdata->next;
575 	}
576     }
577 
578   if (sym == NULL)
579     callback (data, addr, NULL, 0, 0);
580   else
581     callback (data, addr, sym->name, sym->address, 0);
582 }
583 
584 /* Add the backtrace data for one PE/COFF file.  Returns 1 on success,
585    0 on failure (in both cases descriptor is closed).  */
586 
587 static int
588 coff_add (struct backtrace_state *state, int descriptor,
589 	  backtrace_error_callback error_callback, void *data,
590 	  fileline *fileline_fn, int *found_sym, int *found_dwarf)
591 {
592   struct backtrace_view fhdr_view;
593   off_t fhdr_off;
594   int magic_ok;
595   b_coff_file_header fhdr;
596   off_t opt_sects_off;
597   size_t opt_sects_size;
598   unsigned int sects_num;
599   struct backtrace_view sects_view;
600   int sects_view_valid;
601   const b_coff_optional_header *opt_hdr;
602   const b_coff_section_header *sects;
603   struct backtrace_view str_view;
604   int str_view_valid;
605   uint32_t str_size;
606   off_t str_off;
607   // NOTE: upstream doesn't have `{0}`, this is a fix for Rust issue #39468.
608   //       If syms_view is not initialized, then `free(syms_view.base)` may segfault later.
609   struct backtrace_view syms_view = {0};
610   off_t syms_off;
611   size_t syms_size;
612   int syms_view_valid;
613   unsigned int syms_num;
614   unsigned int i;
615   struct debug_section_info sections[DEBUG_MAX];
616   off_t min_offset;
617   off_t max_offset;
618   struct backtrace_view debug_view;
619   int debug_view_valid;
620   uintptr_t image_base;
621 
622   *found_sym = 0;
623   *found_dwarf = 0;
624 
625   sects_view_valid = 0;
626   syms_view_valid = 0;
627   str_view_valid = 0;
628   debug_view_valid = 0;
629 
630   /* Map the MS-DOS stub (if any) and extract file header offset.  */
631   if (!backtrace_get_view (state, descriptor, 0, 0x40, error_callback,
632 			   data, &fhdr_view))
633     goto fail;
634 
635   {
636     const unsigned char *vptr = fhdr_view.data;
637 
638     if (vptr[0] == 'M' && vptr[1] == 'Z')
639       fhdr_off = coff_read4 (vptr + 0x3c);
640     else
641       fhdr_off = 0;
642   }
643 
644   backtrace_release_view (state, &fhdr_view, error_callback, data);
645 
646   /* Map the coff file header.  */
647   if (!backtrace_get_view (state, descriptor, fhdr_off,
648 			   sizeof (b_coff_file_header) + 4,
649 			   error_callback, data, &fhdr_view))
650     goto fail;
651 
652   if (fhdr_off != 0)
653     {
654       const char *magic = (const char *) fhdr_view.data;
655       magic_ok = memcmp (magic, "PE\0", 4) == 0;
656       fhdr_off += 4;
657 
658       memcpy (&fhdr, fhdr_view.data + 4, sizeof fhdr);
659     }
660   else
661     {
662       memcpy (&fhdr, fhdr_view.data, sizeof fhdr);
663       /* TODO: test fhdr.machine for coff but non-PE platforms.  */
664       magic_ok = 0;
665     }
666   backtrace_release_view (state, &fhdr_view, error_callback, data);
667 
668   if (!magic_ok)
669     {
670       error_callback (data, "executable file is not COFF", 0);
671       goto fail;
672     }
673 
674   sects_num = fhdr.number_of_sections;
675   syms_num = fhdr.number_of_symbols;
676 
677   opt_sects_off = fhdr_off + sizeof (fhdr);
678   opt_sects_size = (fhdr.size_of_optional_header
679 		    + sects_num * sizeof (b_coff_section_header));
680 
681   /* To translate PC to file/line when using DWARF, we need to find
682      the .debug_info and .debug_line sections.  */
683 
684   /* Read the optional header and the section headers.  */
685 
686   if (!backtrace_get_view (state, descriptor, opt_sects_off, opt_sects_size,
687 			   error_callback, data, &sects_view))
688     goto fail;
689   sects_view_valid = 1;
690   opt_hdr = (const b_coff_optional_header *) sects_view.data;
691   sects = (const b_coff_section_header *)
692     (sects_view.data + fhdr.size_of_optional_header);
693 
694   if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
695     {
696       if (opt_hdr->magic == PE_MAGIC)
697 	image_base = opt_hdr->u.pe.image_base;
698       else if (opt_hdr->magic == PEP_MAGIC)
699 	image_base = opt_hdr->u.pep.image_base;
700       else
701 	{
702 	  error_callback (data, "bad magic in PE optional header", 0);
703 	  goto fail;
704 	}
705     }
706   else
707     image_base = 0;
708 
709   /* Read the symbol table and the string table.  */
710 
711   if (fhdr.pointer_to_symbol_table == 0)
712     {
713       /* No symbol table, no string table.  */
714       str_off = 0;
715       str_size = 0;
716       syms_num = 0;
717       syms_size = 0;
718     }
719   else
720     {
721       /* Symbol table is followed by the string table.  The string table
722 	 starts with its length (on 4 bytes).
723 	 Map the symbol table and the length of the string table.  */
724       syms_off = fhdr.pointer_to_symbol_table;
725       syms_size = syms_num * SYM_SZ;
726 
727       if (!backtrace_get_view (state, descriptor, syms_off, syms_size + 4,
728 			       error_callback, data, &syms_view))
729 	goto fail;
730       syms_view_valid = 1;
731 
732       str_size = coff_read4 (syms_view.data + syms_size);
733 
734       str_off = syms_off + syms_size;
735 
736       if (str_size > 4)
737 	{
738 	  /* Map string table (including the length word).  */
739 
740 	  if (!backtrace_get_view (state, descriptor, str_off, str_size,
741 				   error_callback, data, &str_view))
742 	    goto fail;
743 	  str_view_valid = 1;
744 	}
745     }
746 
747   memset (sections, 0, sizeof sections);
748 
749   /* Look for the symbol table.  */
750   for (i = 0; i < sects_num; ++i)
751     {
752       const b_coff_section_header *s = sects + i;
753       unsigned int str_off;
754       int j;
755 
756       if (s->name[0] == '/')
757 	{
758 	  /* Extended section name.  */
759 	  str_off = atoi (s->name + 1);
760 	}
761       else
762 	str_off = 0;
763 
764       for (j = 0; j < (int) DEBUG_MAX; ++j)
765 	{
766 	  const char *dbg_name = debug_section_names[j];
767 	  int match;
768 
769 	  if (str_off != 0)
770 	    match = coff_long_name_eq (dbg_name, str_off, &str_view);
771 	  else
772 	    match = coff_short_name_eq (dbg_name, s->name);
773 	  if (match)
774 	    {
775 	      sections[j].offset = s->pointer_to_raw_data;
776 	      sections[j].size = s->virtual_size <= s->size_of_raw_data ?
777 		s->virtual_size : s->size_of_raw_data;
778 	      break;
779 	    }
780 	}
781     }
782 
783   if (syms_num != 0)
784     {
785       struct coff_syminfo_data *sdata;
786 
787       sdata = ((struct coff_syminfo_data *)
788 	       backtrace_alloc (state, sizeof *sdata, error_callback, data));
789       if (sdata == NULL)
790 	goto fail;
791 
792       if (!coff_initialize_syminfo (state, image_base,
793 				    sects, sects_num,
794 				    syms_view.data, syms_size,
795 				    str_view.data, str_size,
796 				    error_callback, data, sdata))
797 	{
798 	  backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
799 	  goto fail;
800 	}
801 
802       *found_sym = 1;
803 
804       coff_add_syminfo_data (state, sdata);
805     }
806 
807   backtrace_release_view (state, &sects_view, error_callback, data);
808   sects_view_valid = 0;
809   if (syms_view_valid)
810     {
811       backtrace_release_view (state, &syms_view, error_callback, data);
812       syms_view_valid = 0;
813     }
814 
815   /* Read all the debug sections in a single view, since they are
816      probably adjacent in the file.  We never release this view.  */
817 
818   min_offset = 0;
819   max_offset = 0;
820   for (i = 0; i < (int) DEBUG_MAX; ++i)
821     {
822       off_t end;
823 
824       if (sections[i].size == 0)
825 	continue;
826       if (min_offset == 0 || sections[i].offset < min_offset)
827 	min_offset = sections[i].offset;
828       end = sections[i].offset + sections[i].size;
829       if (end > max_offset)
830 	max_offset = end;
831     }
832   if (min_offset == 0 || max_offset == 0)
833     {
834       if (!backtrace_close (descriptor, error_callback, data))
835 	goto fail;
836       *fileline_fn = coff_nodebug;
837       return 1;
838     }
839 
840   if (!backtrace_get_view (state, descriptor, min_offset,
841 			   max_offset - min_offset,
842 			   error_callback, data, &debug_view))
843     goto fail;
844   debug_view_valid = 1;
845 
846   /* We've read all we need from the executable.  */
847   if (!backtrace_close (descriptor, error_callback, data))
848     goto fail;
849   descriptor = -1;
850 
851   for (i = 0; i < (int) DEBUG_MAX; ++i)
852     {
853       if (sections[i].size == 0)
854 	sections[i].data = NULL;
855       else
856 	sections[i].data = ((const unsigned char *) debug_view.data
857 			    + (sections[i].offset - min_offset));
858     }
859 
860   if (!backtrace_dwarf_add (state, /* base_address */ 0,
861 			    sections[DEBUG_INFO].data,
862 			    sections[DEBUG_INFO].size,
863 			    sections[DEBUG_LINE].data,
864 			    sections[DEBUG_LINE].size,
865 			    sections[DEBUG_ABBREV].data,
866 			    sections[DEBUG_ABBREV].size,
867 			    sections[DEBUG_RANGES].data,
868 			    sections[DEBUG_RANGES].size,
869 			    sections[DEBUG_STR].data,
870 			    sections[DEBUG_STR].size,
871 			    0, /* FIXME */
872 			    error_callback, data, fileline_fn))
873     goto fail;
874 
875   *found_dwarf = 1;
876 
877   return 1;
878 
879  fail:
880   if (sects_view_valid)
881     backtrace_release_view (state, &sects_view, error_callback, data);
882   if (str_view_valid)
883     backtrace_release_view (state, &str_view, error_callback, data);
884   if (syms_view_valid)
885     backtrace_release_view (state, &syms_view, error_callback, data);
886   if (debug_view_valid)
887     backtrace_release_view (state, &debug_view, error_callback, data);
888   if (descriptor != -1)
889     backtrace_close (descriptor, error_callback, data);
890   return 0;
891 }
892 
893 /* Initialize the backtrace data we need from an ELF executable.  At
894    the ELF level, all we need to do is find the debug info
895    sections.  */
896 
897 int
898 backtrace_initialize (struct backtrace_state *state,
899 		      const char *filename ATTRIBUTE_UNUSED, int descriptor,
900 		      backtrace_error_callback error_callback,
901 		      void *data, fileline *fileline_fn)
902 {
903   int ret;
904   int found_sym;
905   int found_dwarf;
906   fileline coff_fileline_fn;
907 
908   ret = coff_add (state, descriptor, error_callback, data,
909 		  &coff_fileline_fn, &found_sym, &found_dwarf);
910   if (!ret)
911     return 0;
912 
913   if (!state->threaded)
914     {
915       if (found_sym)
916 	state->syminfo_fn = coff_syminfo;
917       else if (state->syminfo_fn == NULL)
918 	state->syminfo_fn = coff_nosyms;
919     }
920   else
921     {
922       if (found_sym)
923 	backtrace_atomic_store_pointer (&state->syminfo_fn, coff_syminfo);
924       else
925 	__sync_bool_compare_and_swap (&state->syminfo_fn, NULL, coff_nosyms);
926     }
927 
928   if (!state->threaded)
929     {
930       if (state->fileline_fn == NULL || state->fileline_fn == coff_nodebug)
931 	*fileline_fn = coff_fileline_fn;
932     }
933   else
934     {
935       fileline current_fn;
936 
937       current_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
938       if (current_fn == NULL || current_fn == coff_nodebug)
939 	*fileline_fn = coff_fileline_fn;
940     }
941 
942   return 1;
943 }
944