1 /* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
2    Copyright (C) 2015-2020 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 /* Names of sections, indexed by enum dwarf_section in internal.h.  */
137 
138 static const char * const debug_section_names[DEBUG_MAX] =
139 {
140   ".debug_info",
141   ".debug_line",
142   ".debug_abbrev",
143   ".debug_ranges",
144   ".debug_str",
145   ".debug_addr",
146   ".debug_str_offsets",
147   ".debug_line_str",
148   ".debug_rnglists"
149 };
150 
151 /* Information we gather for the sections we care about.  */
152 
153 struct debug_section_info
154 {
155   /* Section file offset.  */
156   off_t offset;
157   /* Section size.  */
158   size_t size;
159 };
160 
161 /* Information we keep for an coff symbol.  */
162 
163 struct coff_symbol
164 {
165   /* The name of the symbol.  */
166   const char *name;
167   /* The address of the symbol.  */
168   uintptr_t address;
169 };
170 
171 /* Information to pass to coff_syminfo.  */
172 
173 struct coff_syminfo_data
174 {
175   /* Symbols for the next module.  */
176   struct coff_syminfo_data *next;
177   /* The COFF symbols, sorted by address.  */
178   struct coff_symbol *symbols;
179   /* The number of symbols.  */
180   size_t count;
181 };
182 
183 /* A dummy callback function used when we can't find any debug info.  */
184 
185 static int
186 coff_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
187 	      uintptr_t pc ATTRIBUTE_UNUSED,
188 	      backtrace_full_callback callback ATTRIBUTE_UNUSED,
189 	      backtrace_error_callback error_callback, void *data)
190 {
191   error_callback (data, "no debug info in PE/COFF executable", -1);
192   return 0;
193 }
194 
195 /* A dummy callback function used when we can't find a symbol
196    table.  */
197 
198 static void
199 coff_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
200 	     uintptr_t addr ATTRIBUTE_UNUSED,
201 	     backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
202 	     backtrace_error_callback error_callback, void *data)
203 {
204   error_callback (data, "no symbol table in PE/COFF executable", -1);
205 }
206 
207 /* Read a potentially unaligned 4 byte word at P, using native endianness.  */
208 
209 static uint32_t
210 coff_read4 (const unsigned char *p)
211 {
212   uint32_t res;
213 
214   memcpy (&res, p, 4);
215   return res;
216 }
217 
218 /* Read a potentially unaligned 2 byte word at P, using native endianness.
219    All 2 byte word in symbols are always aligned, but for coherency all
220    fields are declared as char arrays.  */
221 
222 static uint16_t
223 coff_read2 (const unsigned char *p)
224 {
225   uint16_t res;
226 
227   memcpy (&res, p, sizeof (res));
228   return res;
229 }
230 
231 /* Return the length (without the trailing 0) of a COFF short name.  */
232 
233 static size_t
234 coff_short_name_len (const char *name)
235 {
236   int i;
237 
238   for (i = 0; i < 8; i++)
239     if (name[i] == 0)
240       return i;
241   return 8;
242 }
243 
244 /* Return true iff COFF short name CNAME is the same as NAME (a NUL-terminated
245    string).  */
246 
247 static int
248 coff_short_name_eq (const char *name, const char *cname)
249 {
250   int i;
251 
252   for (i = 0; i < 8; i++)
253     {
254       if (name[i] != cname[i])
255 	return 0;
256       if (name[i] == 0)
257 	return 1;
258     }
259   return name[8] == 0;
260 }
261 
262 /* Return true iff NAME is the same as string at offset OFF.  */
263 
264 static int
265 coff_long_name_eq (const char *name, unsigned int off,
266 		   struct backtrace_view *str_view)
267 {
268   if (off >= str_view->len)
269     return 0;
270   return strcmp (name, (const char *)str_view->data + off) == 0;
271 }
272 
273 /* Compare struct coff_symbol for qsort.  */
274 
275 static int
276 coff_symbol_compare (const void *v1, const void *v2)
277 {
278   const struct coff_symbol *e1 = (const struct coff_symbol *) v1;
279   const struct coff_symbol *e2 = (const struct coff_symbol *) v2;
280 
281   if (e1->address < e2->address)
282     return -1;
283   else if (e1->address > e2->address)
284     return 1;
285   else
286     return 0;
287 }
288 
289 /* Convert SYM to internal (and aligned) format ISYM, using string table
290    from STRTAB and STRTAB_SIZE, and number of sections SECTS_NUM.
291    Return -1 in case of error (invalid section number or string index).  */
292 
293 static int
294 coff_expand_symbol (b_coff_internal_symbol *isym,
295 		    const b_coff_external_symbol *sym,
296 		    uint16_t sects_num,
297 		    const unsigned char *strtab, size_t strtab_size)
298 {
299   isym->type = coff_read2 (sym->type);
300   isym->sec = coff_read2 (sym->section_number);
301   isym->sc = sym->storage_class;
302 
303   if (isym->sec > 0 && (uint16_t) isym->sec > sects_num)
304     return -1;
305   if (sym->name.short_name[0] != 0)
306     isym->name = sym->name.short_name;
307   else
308     {
309       uint32_t off = coff_read4 (sym->name.long_name.off);
310 
311       if (off >= strtab_size)
312 	return -1;
313       isym->name = (const char *) strtab + off;
314     }
315   return 0;
316 }
317 
318 /* Return true iff SYM is a defined symbol for a function.  Data symbols
319    aren't considered because they aren't easily identified (same type as
320    section names, presence of symbols defined by the linker script).  */
321 
322 static int
323 coff_is_function_symbol (const b_coff_internal_symbol *isym)
324 {
325   return (isym->type >> N_TBSHFT) == IMAGE_SYM_DTYPE_FUNCTION
326     && isym->sec > 0;
327 }
328 
329 /* Initialize the symbol table info for coff_syminfo.  */
330 
331 static int
332 coff_initialize_syminfo (struct backtrace_state *state,
333 			 uintptr_t base_address,
334 			 const b_coff_section_header *sects, size_t sects_num,
335 			 const b_coff_external_symbol *syms, size_t syms_size,
336 			 const unsigned char *strtab, size_t strtab_size,
337 			 backtrace_error_callback error_callback,
338 			 void *data, struct coff_syminfo_data *sdata)
339 {
340   size_t syms_count;
341   char *coff_symstr;
342   size_t coff_symstr_len;
343   size_t coff_symbol_count;
344   size_t coff_symbol_size;
345   struct coff_symbol *coff_symbols;
346   struct coff_symbol *coff_sym;
347   char *coff_str;
348   size_t i;
349 
350   syms_count = syms_size / SYM_SZ;
351 
352   /* We only care about function symbols.  Count them.  Also count size of
353      strings for in-symbol names.  */
354   coff_symbol_count = 0;
355   coff_symstr_len = 0;
356   for (i = 0; i < syms_count; ++i)
357     {
358       const b_coff_external_symbol *asym = &syms[i];
359       b_coff_internal_symbol isym;
360 
361       if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size) < 0)
362 	{
363 	  error_callback (data, "invalid section or offset in coff symbol", 0);
364 	  return 0;
365 	}
366       if (coff_is_function_symbol (&isym))
367 	{
368 	  ++coff_symbol_count;
369 	  if (asym->name.short_name[0] != 0)
370 	    coff_symstr_len += coff_short_name_len (asym->name.short_name) + 1;
371 	}
372 
373       i += asym->number_of_aux_symbols;
374     }
375 
376   coff_symbol_size = (coff_symbol_count + 1) * sizeof (struct coff_symbol);
377   coff_symbols = ((struct coff_symbol *)
378 		  backtrace_alloc (state, coff_symbol_size, error_callback,
379 				   data));
380   if (coff_symbols == NULL)
381     return 0;
382 
383   /* Allocate memory for symbols strings.  */
384   if (coff_symstr_len > 0)
385     {
386       coff_symstr = ((char *)
387 		     backtrace_alloc (state, coff_symstr_len, error_callback,
388 				      data));
389       if (coff_symstr == NULL)
390 	{
391 	  backtrace_free (state, coff_symbols, coff_symbol_size,
392 			  error_callback, data);
393 	  return 0;
394 	}
395     }
396   else
397     coff_symstr = NULL;
398 
399   /* Copy symbols.  */
400   coff_sym = coff_symbols;
401   coff_str = coff_symstr;
402   for (i = 0; i < syms_count; ++i)
403     {
404       const b_coff_external_symbol *asym = &syms[i];
405       b_coff_internal_symbol isym;
406 
407       if (coff_expand_symbol (&isym, asym, sects_num, strtab, strtab_size))
408 	{
409 	  /* Should not fail, as it was already tested in the previous
410 	     loop.  */
411 	  abort ();
412 	}
413       if (coff_is_function_symbol (&isym))
414 	{
415 	  const char *name;
416 	  int16_t secnum;
417 
418 	  if (asym->name.short_name[0] != 0)
419 	    {
420 	      size_t len = coff_short_name_len (isym.name);
421 	      name = coff_str;
422 	      memcpy (coff_str, isym.name, len);
423 	      coff_str[len] = 0;
424 	      coff_str += len + 1;
425 	    }
426 	  else
427 	    name = isym.name;
428 
429 	  /* Strip leading '_'.  */
430 	  if (name[0] == '_')
431 	    name++;
432 
433 	  /* Symbol value is section relative, so we need to read the address
434 	     of its section.  */
435 	  secnum = coff_read2 (asym->section_number);
436 
437 	  coff_sym->name = name;
438 	  coff_sym->address = (coff_read4 (asym->value)
439 			       + sects[secnum - 1].virtual_address
440 			       + base_address);
441 	  coff_sym++;
442 	}
443 
444       i += asym->number_of_aux_symbols;
445     }
446 
447   /* End of symbols marker.  */
448   coff_sym->name = NULL;
449   coff_sym->address = -1;
450 
451   backtrace_qsort (coff_symbols, coff_symbol_count,
452 		   sizeof (struct coff_symbol), coff_symbol_compare);
453 
454   sdata->next = NULL;
455   sdata->symbols = coff_symbols;
456   sdata->count = coff_symbol_count;
457 
458   return 1;
459 }
460 
461 /* Add EDATA to the list in STATE.  */
462 
463 static void
464 coff_add_syminfo_data (struct backtrace_state *state,
465 		       struct coff_syminfo_data *sdata)
466 {
467   if (!state->threaded)
468     {
469       struct coff_syminfo_data **pp;
470 
471       for (pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
472 	   *pp != NULL;
473 	   pp = &(*pp)->next)
474 	;
475       *pp = sdata;
476     }
477   else
478     {
479       while (1)
480 	{
481 	  struct coff_syminfo_data **pp;
482 
483 	  pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
484 
485 	  while (1)
486 	    {
487 	      struct coff_syminfo_data *p;
488 
489 	      p = backtrace_atomic_load_pointer (pp);
490 
491 	      if (p == NULL)
492 		break;
493 
494 	      pp = &p->next;
495 	    }
496 
497 	  if (__sync_bool_compare_and_swap (pp, NULL, sdata))
498 	    break;
499 	}
500     }
501 }
502 
503 /* Compare an ADDR against an elf_symbol for bsearch.  We allocate one
504    extra entry in the array so that this can look safely at the next
505    entry.  */
506 
507 static int
508 coff_symbol_search (const void *vkey, const void *ventry)
509 {
510   const uintptr_t *key = (const uintptr_t *) vkey;
511   const struct coff_symbol *entry = (const struct coff_symbol *) ventry;
512   uintptr_t addr;
513 
514   addr = *key;
515   if (addr < entry->address)
516     return -1;
517   else if (addr >= entry[1].address)
518     return 1;
519   else
520     return 0;
521 }
522 
523 /* Return the symbol name and value for an ADDR.  */
524 
525 static void
526 coff_syminfo (struct backtrace_state *state, uintptr_t addr,
527 	      backtrace_syminfo_callback callback,
528 	      backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
529 	      void *data)
530 {
531   struct coff_syminfo_data *sdata;
532   struct coff_symbol *sym = NULL;
533 
534   if (!state->threaded)
535     {
536       for (sdata = (struct coff_syminfo_data *) state->syminfo_data;
537 	   sdata != NULL;
538 	   sdata = sdata->next)
539 	{
540 	  sym = ((struct coff_symbol *)
541 		 bsearch (&addr, sdata->symbols, sdata->count,
542 			  sizeof (struct coff_symbol), coff_symbol_search));
543 	  if (sym != NULL)
544 	    break;
545 	}
546     }
547   else
548     {
549       struct coff_syminfo_data **pp;
550 
551       pp = (struct coff_syminfo_data **) (void *) &state->syminfo_data;
552       while (1)
553 	{
554 	  sdata = backtrace_atomic_load_pointer (pp);
555 	  if (sdata == NULL)
556 	    break;
557 
558 	  sym = ((struct coff_symbol *)
559 		 bsearch (&addr, sdata->symbols, sdata->count,
560 			  sizeof (struct coff_symbol), coff_symbol_search));
561 	  if (sym != NULL)
562 	    break;
563 
564 	  pp = &sdata->next;
565 	}
566     }
567 
568   if (sym == NULL)
569     callback (data, addr, NULL, 0, 0);
570   else
571     callback (data, addr, sym->name, sym->address, 0);
572 }
573 
574 /* Add the backtrace data for one PE/COFF file.  Returns 1 on success,
575    0 on failure (in both cases descriptor is closed).  */
576 
577 static int
578 coff_add (struct backtrace_state *state, int descriptor,
579 	  backtrace_error_callback error_callback, void *data,
580 	  fileline *fileline_fn, int *found_sym, int *found_dwarf)
581 {
582   struct backtrace_view fhdr_view;
583   off_t fhdr_off;
584   int magic_ok;
585   b_coff_file_header fhdr;
586   off_t opt_sects_off;
587   size_t opt_sects_size;
588   unsigned int sects_num;
589   struct backtrace_view sects_view;
590   int sects_view_valid;
591   const b_coff_optional_header *opt_hdr;
592   const b_coff_section_header *sects;
593   struct backtrace_view str_view;
594   int str_view_valid;
595   uint32_t str_size;
596   off_t str_off;
597   // NOTE: upstream doesn't have `{0}`, this is a fix for Rust issue #39468.
598   //       If syms_view is not initialized, then `free(syms_view.base)` may segfault later.
599   struct backtrace_view syms_view = {0};
600   off_t syms_off;
601   size_t syms_size;
602   int syms_view_valid;
603   unsigned int syms_num;
604   unsigned int i;
605   struct debug_section_info sections[DEBUG_MAX];
606   off_t min_offset;
607   off_t max_offset;
608   struct backtrace_view debug_view;
609   int debug_view_valid;
610   uintptr_t image_base;
611   struct dwarf_sections dwarf_sections;
612 
613   *found_sym = 0;
614   *found_dwarf = 0;
615 
616   sects_view_valid = 0;
617   syms_view_valid = 0;
618   str_view_valid = 0;
619   debug_view_valid = 0;
620 
621   /* Map the MS-DOS stub (if any) and extract file header offset.  */
622   if (!backtrace_get_view (state, descriptor, 0, 0x40, error_callback,
623 			   data, &fhdr_view))
624     goto fail;
625 
626   {
627     const unsigned char *vptr = fhdr_view.data;
628 
629     if (vptr[0] == 'M' && vptr[1] == 'Z')
630       fhdr_off = coff_read4 (vptr + 0x3c);
631     else
632       fhdr_off = 0;
633   }
634 
635   backtrace_release_view (state, &fhdr_view, error_callback, data);
636 
637   /* Map the coff file header.  */
638   if (!backtrace_get_view (state, descriptor, fhdr_off,
639 			   sizeof (b_coff_file_header) + 4,
640 			   error_callback, data, &fhdr_view))
641     goto fail;
642 
643   if (fhdr_off != 0)
644     {
645       const char *magic = (const char *) fhdr_view.data;
646       magic_ok = memcmp (magic, "PE\0", 4) == 0;
647       fhdr_off += 4;
648 
649       memcpy (&fhdr, fhdr_view.data + 4, sizeof fhdr);
650     }
651   else
652     {
653       memcpy (&fhdr, fhdr_view.data, sizeof fhdr);
654       /* TODO: test fhdr.machine for coff but non-PE platforms.  */
655       magic_ok = 0;
656     }
657   backtrace_release_view (state, &fhdr_view, error_callback, data);
658 
659   if (!magic_ok)
660     {
661       error_callback (data, "executable file is not COFF", 0);
662       goto fail;
663     }
664 
665   sects_num = fhdr.number_of_sections;
666   syms_num = fhdr.number_of_symbols;
667 
668   opt_sects_off = fhdr_off + sizeof (fhdr);
669   opt_sects_size = (fhdr.size_of_optional_header
670 		    + sects_num * sizeof (b_coff_section_header));
671 
672   /* To translate PC to file/line when using DWARF, we need to find
673      the .debug_info and .debug_line sections.  */
674 
675   /* Read the optional header and the section headers.  */
676 
677   if (!backtrace_get_view (state, descriptor, opt_sects_off, opt_sects_size,
678 			   error_callback, data, &sects_view))
679     goto fail;
680   sects_view_valid = 1;
681   opt_hdr = (const b_coff_optional_header *) sects_view.data;
682   sects = (const b_coff_section_header *)
683     (sects_view.data + fhdr.size_of_optional_header);
684 
685   if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
686     {
687       if (opt_hdr->magic == PE_MAGIC)
688 	image_base = opt_hdr->u.pe.image_base;
689       else if (opt_hdr->magic == PEP_MAGIC)
690 	image_base = opt_hdr->u.pep.image_base;
691       else
692 	{
693 	  error_callback (data, "bad magic in PE optional header", 0);
694 	  goto fail;
695 	}
696     }
697   else
698     image_base = 0;
699 
700   /* Read the symbol table and the string table.  */
701 
702   if (fhdr.pointer_to_symbol_table == 0)
703     {
704       /* No symbol table, no string table.  */
705       str_off = 0;
706       str_size = 0;
707       syms_num = 0;
708       syms_size = 0;
709     }
710   else
711     {
712       /* Symbol table is followed by the string table.  The string table
713 	 starts with its length (on 4 bytes).
714 	 Map the symbol table and the length of the string table.  */
715       syms_off = fhdr.pointer_to_symbol_table;
716       syms_size = syms_num * SYM_SZ;
717 
718       if (!backtrace_get_view (state, descriptor, syms_off, syms_size + 4,
719 			       error_callback, data, &syms_view))
720 	goto fail;
721       syms_view_valid = 1;
722 
723       str_size = coff_read4 (syms_view.data + syms_size);
724 
725       str_off = syms_off + syms_size;
726 
727       if (str_size > 4)
728 	{
729 	  /* Map string table (including the length word).  */
730 
731 	  if (!backtrace_get_view (state, descriptor, str_off, str_size,
732 				   error_callback, data, &str_view))
733 	    goto fail;
734 	  str_view_valid = 1;
735 	}
736     }
737 
738   memset (sections, 0, sizeof sections);
739 
740   /* Look for the symbol table.  */
741   for (i = 0; i < sects_num; ++i)
742     {
743       const b_coff_section_header *s = sects + i;
744       unsigned int str_off;
745       int j;
746 
747       if (s->name[0] == '/')
748 	{
749 	  /* Extended section name.  */
750 	  str_off = atoi (s->name + 1);
751 	}
752       else
753 	str_off = 0;
754 
755       for (j = 0; j < (int) DEBUG_MAX; ++j)
756 	{
757 	  const char *dbg_name = debug_section_names[j];
758 	  int match;
759 
760 	  if (str_off != 0)
761 	    match = coff_long_name_eq (dbg_name, str_off, &str_view);
762 	  else
763 	    match = coff_short_name_eq (dbg_name, s->name);
764 	  if (match)
765 	    {
766 	      sections[j].offset = s->pointer_to_raw_data;
767 	      sections[j].size = s->virtual_size <= s->size_of_raw_data ?
768 		s->virtual_size : s->size_of_raw_data;
769 	      break;
770 	    }
771 	}
772     }
773 
774   if (syms_num != 0)
775     {
776       struct coff_syminfo_data *sdata;
777 
778       sdata = ((struct coff_syminfo_data *)
779 	       backtrace_alloc (state, sizeof *sdata, error_callback, data));
780       if (sdata == NULL)
781 	goto fail;
782 
783       if (!coff_initialize_syminfo (state, image_base,
784 				    sects, sects_num,
785 				    syms_view.data, syms_size,
786 				    str_view.data, str_size,
787 				    error_callback, data, sdata))
788 	{
789 	  backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
790 	  goto fail;
791 	}
792 
793       *found_sym = 1;
794 
795       coff_add_syminfo_data (state, sdata);
796     }
797 
798   backtrace_release_view (state, &sects_view, error_callback, data);
799   sects_view_valid = 0;
800   if (syms_view_valid)
801     {
802       backtrace_release_view (state, &syms_view, error_callback, data);
803       syms_view_valid = 0;
804     }
805 
806   /* Read all the debug sections in a single view, since they are
807      probably adjacent in the file.  We never release this view.  */
808 
809   min_offset = 0;
810   max_offset = 0;
811   for (i = 0; i < (int) DEBUG_MAX; ++i)
812     {
813       off_t end;
814 
815       if (sections[i].size == 0)
816 	continue;
817       if (min_offset == 0 || sections[i].offset < min_offset)
818 	min_offset = sections[i].offset;
819       end = sections[i].offset + sections[i].size;
820       if (end > max_offset)
821 	max_offset = end;
822     }
823   if (min_offset == 0 || max_offset == 0)
824     {
825       if (!backtrace_close (descriptor, error_callback, data))
826 	goto fail;
827       *fileline_fn = coff_nodebug;
828       return 1;
829     }
830 
831   if (!backtrace_get_view (state, descriptor, min_offset,
832 			   max_offset - min_offset,
833 			   error_callback, data, &debug_view))
834     goto fail;
835   debug_view_valid = 1;
836 
837   /* We've read all we need from the executable.  */
838   if (!backtrace_close (descriptor, error_callback, data))
839     goto fail;
840   descriptor = -1;
841 
842   for (i = 0; i < (int) DEBUG_MAX; ++i)
843     {
844       size_t size = sections[i].size;
845       dwarf_sections.size[i] = size;
846       if (size == 0)
847 	dwarf_sections.data[i] = NULL;
848       else
849 	dwarf_sections.data[i] = ((const unsigned char *) debug_view.data
850 				  + (sections[i].offset - min_offset));
851     }
852 
853   if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
854 			    0, /* FIXME: is_bigendian */
855 			    NULL, /* altlink */
856 			    error_callback, data, fileline_fn,
857 			    NULL /* returned fileline_entry */))
858     goto fail;
859 
860   *found_dwarf = 1;
861 
862   return 1;
863 
864  fail:
865   if (sects_view_valid)
866     backtrace_release_view (state, &sects_view, error_callback, data);
867   if (str_view_valid)
868     backtrace_release_view (state, &str_view, error_callback, data);
869   if (syms_view_valid)
870     backtrace_release_view (state, &syms_view, error_callback, data);
871   if (debug_view_valid)
872     backtrace_release_view (state, &debug_view, error_callback, data);
873   if (descriptor != -1)
874     backtrace_close (descriptor, error_callback, data);
875   return 0;
876 }
877 
878 /* Initialize the backtrace data we need from an ELF executable.  At
879    the ELF level, all we need to do is find the debug info
880    sections.  */
881 
882 int
883 backtrace_initialize (struct backtrace_state *state,
884 		      const char *filename ATTRIBUTE_UNUSED, int descriptor,
885 		      backtrace_error_callback error_callback,
886 		      void *data, fileline *fileline_fn)
887 {
888   int ret;
889   int found_sym;
890   int found_dwarf;
891   fileline coff_fileline_fn;
892 
893   ret = coff_add (state, descriptor, error_callback, data,
894 		  &coff_fileline_fn, &found_sym, &found_dwarf);
895   if (!ret)
896     return 0;
897 
898   if (!state->threaded)
899     {
900       if (found_sym)
901 	state->syminfo_fn = coff_syminfo;
902       else if (state->syminfo_fn == NULL)
903 	state->syminfo_fn = coff_nosyms;
904     }
905   else
906     {
907       if (found_sym)
908 	backtrace_atomic_store_pointer (&state->syminfo_fn, coff_syminfo);
909       else
910 	(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
911 					     coff_nosyms);
912     }
913 
914   if (!state->threaded)
915     {
916       if (state->fileline_fn == NULL || state->fileline_fn == coff_nodebug)
917 	*fileline_fn = coff_fileline_fn;
918     }
919   else
920     {
921       fileline current_fn;
922 
923       current_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
924       if (current_fn == NULL || current_fn == coff_nodebug)
925 	*fileline_fn = coff_fileline_fn;
926     }
927 
928   return 1;
929 }
930