1 /* pecoff.c -- Get debug data from a PE/COFFF file for backtraces.
2 Copyright (C) 2015-2019 Free Software Foundation, Inc.
3 Adapted from elf.c by Tristan Gingold, AdaCore.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
9 (1) Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
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
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.
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. */
37 #include <sys/types.h>
39 #include "backtrace.h"
42 /* Coff file header. */
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
;
54 /* Coff optional header. */
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
;
67 uint32_t base_of_data
;
74 } b_coff_optional_header
;
76 /* Values of magic in optional header. */
78 #define PE_MAGIC 0x10b /* PE32 executable. */
79 #define PEP_MAGIC 0x20b /* PE32+ executable (for 64bit targets). */
81 /* Coff section header. */
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
;
96 /* Coff symbol name. */
101 unsigned char zeroes
[4];
102 unsigned char off
[4];
106 /* Coff symbol (external representation which is unaligned). */
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
;
119 #define N_TBSHFT 4 /* Shift for the derived type. */
120 #define IMAGE_SYM_DTYPE_FUNCTION 2 /* Function derived type. */
122 /* Size of a coff symbol. */
126 /* Coff symbol, internal representation (aligned). */
134 } b_coff_internal_symbol
;
136 /* Names of sections, indexed by enum dwarf_section in internal.h. */
138 static const char * const debug_section_names
[DEBUG_MAX
] =
147 /* Information we gather for the sections we care about. */
149 struct debug_section_info
151 /* Section file offset. */
157 /* Information we keep for an coff symbol. */
161 /* The name of the symbol. */
163 /* The address of the symbol. */
167 /* Information to pass to coff_syminfo. */
169 struct coff_syminfo_data
171 /* Symbols for the next module. */
172 struct coff_syminfo_data
*next
;
173 /* The COFF symbols, sorted by address. */
174 struct coff_symbol
*symbols
;
175 /* The number of symbols. */
179 /* A dummy callback function used when we can't find any debug info. */
182 coff_nodebug (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
183 uintptr_t pc ATTRIBUTE_UNUSED
,
184 backtrace_full_callback callback ATTRIBUTE_UNUSED
,
185 backtrace_error_callback error_callback
, void *data
)
187 error_callback (data
, "no debug info in PE/COFF executable", -1);
191 /* A dummy callback function used when we can't find a symbol
195 coff_nosyms (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
196 uintptr_t addr ATTRIBUTE_UNUSED
,
197 backtrace_syminfo_callback callback ATTRIBUTE_UNUSED
,
198 backtrace_error_callback error_callback
, void *data
)
200 error_callback (data
, "no symbol table in PE/COFF executable", -1);
203 /* Read a potentially unaligned 4 byte word at P, using native endianness. */
206 coff_read4 (const unsigned char *p
)
214 /* Read a potentially unaligned 2 byte word at P, using native endianness.
215 All 2 byte word in symbols are always aligned, but for coherency all
216 fields are declared as char arrays. */
219 coff_read2 (const unsigned char *p
)
223 memcpy (&res
, p
, sizeof (res
));
227 /* Return the length (without the trailing 0) of a COFF short name. */
230 coff_short_name_len (const char *name
)
234 for (i
= 0; i
< 8; i
++)
240 /* Return true iff COFF short name CNAME is the same as NAME (a NUL-terminated
244 coff_short_name_eq (const char *name
, const char *cname
)
248 for (i
= 0; i
< 8; i
++)
250 if (name
[i
] != cname
[i
])
258 /* Return true iff NAME is the same as string at offset OFF. */
261 coff_long_name_eq (const char *name
, unsigned int off
,
262 struct backtrace_view
*str_view
)
264 if (off
>= str_view
->len
)
266 return strcmp (name
, (const char *)str_view
->data
+ off
) == 0;
269 /* Compare struct coff_symbol for qsort. */
272 coff_symbol_compare (const void *v1
, const void *v2
)
274 const struct coff_symbol
*e1
= (const struct coff_symbol
*) v1
;
275 const struct coff_symbol
*e2
= (const struct coff_symbol
*) v2
;
277 if (e1
->address
< e2
->address
)
279 else if (e1
->address
> e2
->address
)
285 /* Convert SYM to internal (and aligned) format ISYM, using string table
286 from STRTAB and STRTAB_SIZE, and number of sections SECTS_NUM.
287 Return -1 in case of error (invalid section number or string index). */
290 coff_expand_symbol (b_coff_internal_symbol
*isym
,
291 const b_coff_external_symbol
*sym
,
293 const unsigned char *strtab
, size_t strtab_size
)
295 isym
->type
= coff_read2 (sym
->type
);
296 isym
->sec
= coff_read2 (sym
->section_number
);
297 isym
->sc
= sym
->storage_class
;
299 if (isym
->sec
> 0 && (uint16_t) isym
->sec
> sects_num
)
301 if (sym
->name
.short_name
[0] != 0)
302 isym
->name
= sym
->name
.short_name
;
305 uint32_t off
= coff_read4 (sym
->name
.long_name
.off
);
307 if (off
>= strtab_size
)
309 isym
->name
= (const char *) strtab
+ off
;
314 /* Return true iff SYM is a defined symbol for a function. Data symbols
315 aren't considered because they aren't easily identified (same type as
316 section names, presence of symbols defined by the linker script). */
319 coff_is_function_symbol (const b_coff_internal_symbol
*isym
)
321 return (isym
->type
>> N_TBSHFT
) == IMAGE_SYM_DTYPE_FUNCTION
325 /* Initialize the symbol table info for coff_syminfo. */
328 coff_initialize_syminfo (struct backtrace_state
*state
,
329 uintptr_t base_address
,
330 const b_coff_section_header
*sects
, size_t sects_num
,
331 const b_coff_external_symbol
*syms
, size_t syms_size
,
332 const unsigned char *strtab
, size_t strtab_size
,
333 backtrace_error_callback error_callback
,
334 void *data
, struct coff_syminfo_data
*sdata
)
338 size_t coff_symstr_len
;
339 size_t coff_symbol_count
;
340 size_t coff_symbol_size
;
341 struct coff_symbol
*coff_symbols
;
342 struct coff_symbol
*coff_sym
;
346 syms_count
= syms_size
/ SYM_SZ
;
348 /* We only care about function symbols. Count them. Also count size of
349 strings for in-symbol names. */
350 coff_symbol_count
= 0;
352 for (i
= 0; i
< syms_count
; ++i
)
354 const b_coff_external_symbol
*asym
= &syms
[i
];
355 b_coff_internal_symbol isym
;
357 if (coff_expand_symbol (&isym
, asym
, sects_num
, strtab
, strtab_size
) < 0)
359 error_callback (data
, "invalid section or offset in coff symbol", 0);
362 if (coff_is_function_symbol (&isym
))
365 if (asym
->name
.short_name
[0] != 0)
366 coff_symstr_len
+= coff_short_name_len (asym
->name
.short_name
) + 1;
369 i
+= asym
->number_of_aux_symbols
;
372 coff_symbol_size
= (coff_symbol_count
+ 1) * sizeof (struct coff_symbol
);
373 coff_symbols
= ((struct coff_symbol
*)
374 backtrace_alloc (state
, coff_symbol_size
, error_callback
,
376 if (coff_symbols
== NULL
)
379 /* Allocate memory for symbols strings. */
380 if (coff_symstr_len
> 0)
382 coff_symstr
= ((char *)
383 backtrace_alloc (state
, coff_symstr_len
, error_callback
,
385 if (coff_symstr
== NULL
)
387 backtrace_free (state
, coff_symbols
, coff_symbol_size
,
388 error_callback
, data
);
396 coff_sym
= coff_symbols
;
397 coff_str
= coff_symstr
;
398 for (i
= 0; i
< syms_count
; ++i
)
400 const b_coff_external_symbol
*asym
= &syms
[i
];
401 b_coff_internal_symbol isym
;
403 if (coff_expand_symbol (&isym
, asym
, sects_num
, strtab
, strtab_size
))
405 /* Should not fail, as it was already tested in the previous
409 if (coff_is_function_symbol (&isym
))
414 if (asym
->name
.short_name
[0] != 0)
416 size_t len
= coff_short_name_len (isym
.name
);
418 memcpy (coff_str
, isym
.name
, len
);
425 /* Strip leading '_'. */
429 /* Symbol value is section relative, so we need to read the address
431 secnum
= coff_read2 (asym
->section_number
);
433 coff_sym
->name
= name
;
434 coff_sym
->address
= (coff_read4 (asym
->value
)
435 + sects
[secnum
- 1].virtual_address
440 i
+= asym
->number_of_aux_symbols
;
443 /* End of symbols marker. */
444 coff_sym
->name
= NULL
;
445 coff_sym
->address
= -1;
447 backtrace_qsort (coff_symbols
, coff_symbol_count
,
448 sizeof (struct coff_symbol
), coff_symbol_compare
);
451 sdata
->symbols
= coff_symbols
;
452 sdata
->count
= coff_symbol_count
;
457 /* Add EDATA to the list in STATE. */
460 coff_add_syminfo_data (struct backtrace_state
*state
,
461 struct coff_syminfo_data
*sdata
)
463 if (!state
->threaded
)
465 struct coff_syminfo_data
**pp
;
467 for (pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
477 struct coff_syminfo_data
**pp
;
479 pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
483 struct coff_syminfo_data
*p
;
485 p
= backtrace_atomic_load_pointer (pp
);
493 if (__sync_bool_compare_and_swap (pp
, NULL
, sdata
))
499 /* Compare an ADDR against an elf_symbol for bsearch. We allocate one
500 extra entry in the array so that this can look safely at the next
504 coff_symbol_search (const void *vkey
, const void *ventry
)
506 const uintptr_t *key
= (const uintptr_t *) vkey
;
507 const struct coff_symbol
*entry
= (const struct coff_symbol
*) ventry
;
511 if (addr
< entry
->address
)
513 else if (addr
>= entry
[1].address
)
519 /* Return the symbol name and value for an ADDR. */
522 coff_syminfo (struct backtrace_state
*state
, uintptr_t addr
,
523 backtrace_syminfo_callback callback
,
524 backtrace_error_callback error_callback ATTRIBUTE_UNUSED
,
527 struct coff_syminfo_data
*sdata
;
528 struct coff_symbol
*sym
= NULL
;
530 if (!state
->threaded
)
532 for (sdata
= (struct coff_syminfo_data
*) state
->syminfo_data
;
536 sym
= ((struct coff_symbol
*)
537 bsearch (&addr
, sdata
->symbols
, sdata
->count
,
538 sizeof (struct coff_symbol
), coff_symbol_search
));
545 struct coff_syminfo_data
**pp
;
547 pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
550 sdata
= backtrace_atomic_load_pointer (pp
);
554 sym
= ((struct coff_symbol
*)
555 bsearch (&addr
, sdata
->symbols
, sdata
->count
,
556 sizeof (struct coff_symbol
), coff_symbol_search
));
565 callback (data
, addr
, NULL
, 0, 0);
567 callback (data
, addr
, sym
->name
, sym
->address
, 0);
570 /* Add the backtrace data for one PE/COFF file. Returns 1 on success,
571 0 on failure (in both cases descriptor is closed). */
574 coff_add (struct backtrace_state
*state
, int descriptor
,
575 backtrace_error_callback error_callback
, void *data
,
576 fileline
*fileline_fn
, int *found_sym
, int *found_dwarf
)
578 struct backtrace_view fhdr_view
;
581 b_coff_file_header fhdr
;
583 size_t opt_sects_size
;
584 unsigned int sects_num
;
585 struct backtrace_view sects_view
;
586 int sects_view_valid
;
587 const b_coff_optional_header
*opt_hdr
;
588 const b_coff_section_header
*sects
;
589 struct backtrace_view str_view
;
593 struct backtrace_view syms_view
;
597 unsigned int syms_num
;
599 struct debug_section_info sections
[DEBUG_MAX
];
602 struct backtrace_view debug_view
;
603 int debug_view_valid
;
604 uintptr_t image_base
;
605 struct dwarf_sections dwarf_sections
;
610 sects_view_valid
= 0;
613 debug_view_valid
= 0;
615 /* Map the MS-DOS stub (if any) and extract file header offset. */
616 if (!backtrace_get_view (state
, descriptor
, 0, 0x40, error_callback
,
621 const unsigned char *vptr
= fhdr_view
.data
;
623 if (vptr
[0] == 'M' && vptr
[1] == 'Z')
624 fhdr_off
= coff_read4 (vptr
+ 0x3c);
629 backtrace_release_view (state
, &fhdr_view
, error_callback
, data
);
631 /* Map the coff file header. */
632 if (!backtrace_get_view (state
, descriptor
, fhdr_off
,
633 sizeof (b_coff_file_header
) + 4,
634 error_callback
, data
, &fhdr_view
))
639 const char *magic
= (const char *) fhdr_view
.data
;
640 magic_ok
= memcmp (magic
, "PE\0", 4) == 0;
643 memcpy (&fhdr
, fhdr_view
.data
+ 4, sizeof fhdr
);
647 memcpy (&fhdr
, fhdr_view
.data
, sizeof fhdr
);
648 /* TODO: test fhdr.machine for coff but non-PE platforms. */
651 backtrace_release_view (state
, &fhdr_view
, error_callback
, data
);
655 error_callback (data
, "executable file is not COFF", 0);
659 sects_num
= fhdr
.number_of_sections
;
660 syms_num
= fhdr
.number_of_symbols
;
662 opt_sects_off
= fhdr_off
+ sizeof (fhdr
);
663 opt_sects_size
= (fhdr
.size_of_optional_header
664 + sects_num
* sizeof (b_coff_section_header
));
666 /* To translate PC to file/line when using DWARF, we need to find
667 the .debug_info and .debug_line sections. */
669 /* Read the optional header and the section headers. */
671 if (!backtrace_get_view (state
, descriptor
, opt_sects_off
, opt_sects_size
,
672 error_callback
, data
, §s_view
))
674 sects_view_valid
= 1;
675 opt_hdr
= (const b_coff_optional_header
*) sects_view
.data
;
676 sects
= (const b_coff_section_header
*)
677 (sects_view
.data
+ fhdr
.size_of_optional_header
);
679 if (fhdr
.size_of_optional_header
> sizeof (*opt_hdr
))
681 if (opt_hdr
->magic
== PE_MAGIC
)
682 image_base
= opt_hdr
->u
.pe
.image_base
;
683 else if (opt_hdr
->magic
== PEP_MAGIC
)
684 image_base
= opt_hdr
->u
.pep
.image_base
;
687 error_callback (data
, "bad magic in PE optional header", 0);
694 /* Read the symbol table and the string table. */
696 if (fhdr
.pointer_to_symbol_table
== 0)
698 /* No symbol table, no string table. */
706 /* Symbol table is followed by the string table. The string table
707 starts with its length (on 4 bytes).
708 Map the symbol table and the length of the string table. */
709 syms_off
= fhdr
.pointer_to_symbol_table
;
710 syms_size
= syms_num
* SYM_SZ
;
712 if (!backtrace_get_view (state
, descriptor
, syms_off
, syms_size
+ 4,
713 error_callback
, data
, &syms_view
))
717 str_size
= coff_read4 (syms_view
.data
+ syms_size
);
719 str_off
= syms_off
+ syms_size
;
723 /* Map string table (including the length word). */
725 if (!backtrace_get_view (state
, descriptor
, str_off
, str_size
,
726 error_callback
, data
, &str_view
))
732 memset (sections
, 0, sizeof sections
);
734 /* Look for the symbol table. */
735 for (i
= 0; i
< sects_num
; ++i
)
737 const b_coff_section_header
*s
= sects
+ i
;
738 unsigned int str_off
;
741 if (s
->name
[0] == '/')
743 /* Extended section name. */
744 str_off
= atoi (s
->name
+ 1);
749 for (j
= 0; j
< (int) DEBUG_MAX
; ++j
)
751 const char *dbg_name
= debug_section_names
[j
];
755 match
= coff_long_name_eq (dbg_name
, str_off
, &str_view
);
757 match
= coff_short_name_eq (dbg_name
, s
->name
);
760 sections
[j
].offset
= s
->pointer_to_raw_data
;
761 sections
[j
].size
= s
->virtual_size
<= s
->size_of_raw_data
?
762 s
->virtual_size
: s
->size_of_raw_data
;
770 struct coff_syminfo_data
*sdata
;
772 sdata
= ((struct coff_syminfo_data
*)
773 backtrace_alloc (state
, sizeof *sdata
, error_callback
, data
));
777 if (!coff_initialize_syminfo (state
, image_base
,
779 syms_view
.data
, syms_size
,
780 str_view
.data
, str_size
,
781 error_callback
, data
, sdata
))
783 backtrace_free (state
, sdata
, sizeof *sdata
, error_callback
, data
);
789 coff_add_syminfo_data (state
, sdata
);
792 backtrace_release_view (state
, §s_view
, error_callback
, data
);
793 sects_view_valid
= 0;
796 backtrace_release_view (state
, &syms_view
, error_callback
, data
);
800 /* Read all the debug sections in a single view, since they are
801 probably adjacent in the file. We never release this view. */
805 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
809 if (sections
[i
].size
== 0)
811 if (min_offset
== 0 || sections
[i
].offset
< min_offset
)
812 min_offset
= sections
[i
].offset
;
813 end
= sections
[i
].offset
+ sections
[i
].size
;
814 if (end
> max_offset
)
817 if (min_offset
== 0 || max_offset
== 0)
819 if (!backtrace_close (descriptor
, error_callback
, data
))
821 *fileline_fn
= coff_nodebug
;
825 if (!backtrace_get_view (state
, descriptor
, min_offset
,
826 max_offset
- min_offset
,
827 error_callback
, data
, &debug_view
))
829 debug_view_valid
= 1;
831 /* We've read all we need from the executable. */
832 if (!backtrace_close (descriptor
, error_callback
, data
))
836 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
838 size_t size
= sections
[i
].size
;
839 dwarf_sections
.size
[i
] = size
;
841 dwarf_sections
.data
[i
] = NULL
;
843 dwarf_sections
.data
[i
] = ((const unsigned char *) debug_view
.data
844 + (sections
[i
].offset
- min_offset
));
847 if (!backtrace_dwarf_add (state
, /* base_address */ 0, &dwarf_sections
,
848 0, /* FIXME: is_bigendian */
850 error_callback
, data
, fileline_fn
,
851 NULL
/* returned fileline_entry */))
859 if (sects_view_valid
)
860 backtrace_release_view (state
, §s_view
, error_callback
, data
);
862 backtrace_release_view (state
, &str_view
, error_callback
, data
);
864 backtrace_release_view (state
, &syms_view
, error_callback
, data
);
865 if (debug_view_valid
)
866 backtrace_release_view (state
, &debug_view
, error_callback
, data
);
867 if (descriptor
!= -1)
868 backtrace_close (descriptor
, error_callback
, data
);
872 /* Initialize the backtrace data we need from an ELF executable. At
873 the ELF level, all we need to do is find the debug info
877 backtrace_initialize (struct backtrace_state
*state
,
878 const char *filename ATTRIBUTE_UNUSED
, int descriptor
,
879 backtrace_error_callback error_callback
,
880 void *data
, fileline
*fileline_fn
)
885 fileline coff_fileline_fn
;
887 ret
= coff_add (state
, descriptor
, error_callback
, data
,
888 &coff_fileline_fn
, &found_sym
, &found_dwarf
);
892 if (!state
->threaded
)
895 state
->syminfo_fn
= coff_syminfo
;
896 else if (state
->syminfo_fn
== NULL
)
897 state
->syminfo_fn
= coff_nosyms
;
902 backtrace_atomic_store_pointer (&state
->syminfo_fn
, coff_syminfo
);
904 (void) __sync_bool_compare_and_swap (&state
->syminfo_fn
, NULL
,
908 if (!state
->threaded
)
910 if (state
->fileline_fn
== NULL
|| state
->fileline_fn
== coff_nodebug
)
911 *fileline_fn
= coff_fileline_fn
;
917 current_fn
= backtrace_atomic_load_pointer (&state
->fileline_fn
);
918 if (current_fn
== NULL
|| current_fn
== coff_nodebug
)
919 *fileline_fn
= coff_fileline_fn
;