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.
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 /* An index of sections we care about. */
148 /* Names of sections, indexed by enum debug_section. */
150 static const char * const debug_section_names
[DEBUG_MAX
] =
159 /* Information we gather for the sections we care about. */
161 struct debug_section_info
163 /* Section file offset. */
167 /* Section contents, after read from file. */
168 const unsigned char *data
;
171 /* Information we keep for an coff symbol. */
175 /* The name of the symbol. */
177 /* The address of the symbol. */
181 /* Information to pass to coff_syminfo. */
183 struct coff_syminfo_data
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. */
193 /* A dummy callback function used when we can't find any debug info. */
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
)
201 error_callback (data
, "no debug info in PE/COFF executable", -1);
205 /* A dummy callback function used when we can't find a symbol
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
)
214 error_callback (data
, "no symbol table in PE/COFF executable", -1);
217 /* Read a potentially unaligned 4 byte word at P, using native endianness. */
220 coff_read4 (const unsigned char *p
)
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. */
233 coff_read2 (const unsigned char *p
)
237 memcpy (&res
, p
, sizeof (res
));
241 /* Return the length (without the trailing 0) of a COFF short name. */
244 coff_short_name_len (const char *name
)
248 for (i
= 0; i
< 8; i
++)
254 /* Return true iff COFF short name CNAME is the same as NAME (a NUL-terminated
258 coff_short_name_eq (const char *name
, const char *cname
)
262 for (i
= 0; i
< 8; i
++)
264 if (name
[i
] != cname
[i
])
272 /* Return true iff NAME is the same as string at offset OFF. */
275 coff_long_name_eq (const char *name
, unsigned int off
,
276 struct backtrace_view
*str_view
)
278 if (off
>= str_view
->len
)
280 return strcmp (name
, (const char *)str_view
->data
+ off
) == 0;
283 /* Compare struct coff_symbol for qsort. */
286 coff_symbol_compare (const void *v1
, const void *v2
)
288 const struct coff_symbol
*e1
= (const struct coff_symbol
*) v1
;
289 const struct coff_symbol
*e2
= (const struct coff_symbol
*) v2
;
291 if (e1
->address
< e2
->address
)
293 else if (e1
->address
> e2
->address
)
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). */
304 coff_expand_symbol (b_coff_internal_symbol
*isym
,
305 const b_coff_external_symbol
*sym
,
307 const unsigned char *strtab
, size_t strtab_size
)
309 isym
->type
= coff_read2 (sym
->type
);
310 isym
->sec
= coff_read2 (sym
->section_number
);
311 isym
->sc
= sym
->storage_class
;
313 if (isym
->sec
> 0 && (uint16_t) isym
->sec
> sects_num
)
315 if (sym
->name
.short_name
[0] != 0)
316 isym
->name
= sym
->name
.short_name
;
319 uint32_t off
= coff_read4 (sym
->name
.long_name
.off
);
321 if (off
>= strtab_size
)
323 isym
->name
= (const char *) strtab
+ off
;
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). */
333 coff_is_function_symbol (const b_coff_internal_symbol
*isym
)
335 return (isym
->type
>> N_TBSHFT
) == IMAGE_SYM_DTYPE_FUNCTION
339 /* Initialize the symbol table info for coff_syminfo. */
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
)
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
;
360 syms_count
= syms_size
/ SYM_SZ
;
362 /* We only care about function symbols. Count them. Also count size of
363 strings for in-symbol names. */
364 coff_symbol_count
= 0;
366 for (i
= 0; i
< syms_count
; ++i
)
368 const b_coff_external_symbol
*asym
= &syms
[i
];
369 b_coff_internal_symbol isym
;
371 if (coff_expand_symbol (&isym
, asym
, sects_num
, strtab
, strtab_size
) < 0)
373 error_callback (data
, "invalid section or offset in coff symbol", 0);
376 if (coff_is_function_symbol (&isym
))
379 if (asym
->name
.short_name
[0] != 0)
380 coff_symstr_len
+= coff_short_name_len (asym
->name
.short_name
) + 1;
383 i
+= asym
->number_of_aux_symbols
;
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
,
390 if (coff_symbols
== NULL
)
393 /* Allocate memory for symbols strings. */
394 if (coff_symstr_len
> 0)
396 coff_symstr
= ((char *)
397 backtrace_alloc (state
, coff_symstr_len
, error_callback
,
399 if (coff_symstr
== NULL
)
401 backtrace_free (state
, coff_symbols
, coff_symbol_size
,
402 error_callback
, data
);
410 coff_sym
= coff_symbols
;
411 coff_str
= coff_symstr
;
412 for (i
= 0; i
< syms_count
; ++i
)
414 const b_coff_external_symbol
*asym
= &syms
[i
];
415 b_coff_internal_symbol isym
;
417 if (coff_expand_symbol (&isym
, asym
, sects_num
, strtab
, strtab_size
))
419 /* Should not fail, as it was already tested in the previous
423 if (coff_is_function_symbol (&isym
))
428 if (asym
->name
.short_name
[0] != 0)
430 size_t len
= coff_short_name_len (isym
.name
);
432 memcpy (coff_str
, isym
.name
, len
);
439 /* Strip leading '_'. */
443 /* Symbol value is section relative, so we need to read the address
445 secnum
= coff_read2 (asym
->section_number
);
447 coff_sym
->name
= name
;
448 coff_sym
->address
= (coff_read4 (asym
->value
)
449 + sects
[secnum
- 1].virtual_address
454 i
+= asym
->number_of_aux_symbols
;
457 /* End of symbols marker. */
458 coff_sym
->name
= NULL
;
459 coff_sym
->address
= -1;
461 backtrace_qsort (coff_symbols
, coff_symbol_count
,
462 sizeof (struct coff_symbol
), coff_symbol_compare
);
465 sdata
->symbols
= coff_symbols
;
466 sdata
->count
= coff_symbol_count
;
471 /* Add EDATA to the list in STATE. */
474 coff_add_syminfo_data (struct backtrace_state
*state
,
475 struct coff_syminfo_data
*sdata
)
477 if (!state
->threaded
)
479 struct coff_syminfo_data
**pp
;
481 for (pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
491 struct coff_syminfo_data
**pp
;
493 pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
497 struct coff_syminfo_data
*p
;
499 p
= backtrace_atomic_load_pointer (pp
);
507 if (__sync_bool_compare_and_swap (pp
, NULL
, sdata
))
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
518 coff_symbol_search (const void *vkey
, const void *ventry
)
520 const uintptr_t *key
= (const uintptr_t *) vkey
;
521 const struct coff_symbol
*entry
= (const struct coff_symbol
*) ventry
;
525 if (addr
< entry
->address
)
527 else if (addr
>= entry
[1].address
)
533 /* Return the symbol name and value for an ADDR. */
536 coff_syminfo (struct backtrace_state
*state
, uintptr_t addr
,
537 backtrace_syminfo_callback callback
,
538 backtrace_error_callback error_callback ATTRIBUTE_UNUSED
,
541 struct coff_syminfo_data
*sdata
;
542 struct coff_symbol
*sym
= NULL
;
544 if (!state
->threaded
)
546 for (sdata
= (struct coff_syminfo_data
*) state
->syminfo_data
;
550 sym
= ((struct coff_symbol
*)
551 bsearch (&addr
, sdata
->symbols
, sdata
->count
,
552 sizeof (struct coff_symbol
), coff_symbol_search
));
559 struct coff_syminfo_data
**pp
;
561 pp
= (struct coff_syminfo_data
**) (void *) &state
->syminfo_data
;
564 sdata
= backtrace_atomic_load_pointer (pp
);
568 sym
= ((struct coff_symbol
*)
569 bsearch (&addr
, sdata
->symbols
, sdata
->count
,
570 sizeof (struct coff_symbol
), coff_symbol_search
));
579 callback (data
, addr
, NULL
, 0, 0);
581 callback (data
, addr
, sym
->name
, sym
->address
, 0);
584 /* Add the backtrace data for one PE/COFF file. Returns 1 on success,
585 0 on failure (in both cases descriptor is closed). */
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
)
592 struct backtrace_view fhdr_view
;
595 b_coff_file_header fhdr
;
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
;
607 struct backtrace_view syms_view
;
611 unsigned int syms_num
;
613 struct debug_section_info sections
[DEBUG_MAX
];
616 struct backtrace_view debug_view
;
617 int debug_view_valid
;
618 uintptr_t image_base
;
623 sects_view_valid
= 0;
626 debug_view_valid
= 0;
628 /* Map the MS-DOS stub (if any) and extract file header offset. */
629 if (!backtrace_get_view (state
, descriptor
, 0, 0x40, error_callback
,
634 const char *vptr
= (const char *)fhdr_view
.data
;
636 if (vptr
[0] == 'M' && vptr
[1] == 'Z')
637 memcpy (&fhdr_off
, vptr
+ 0x3c, 4);
642 backtrace_release_view (state
, &fhdr_view
, error_callback
, data
);
644 /* Map the coff file header. */
645 if (!backtrace_get_view (state
, descriptor
, fhdr_off
,
646 sizeof (b_coff_file_header
) + 4,
647 error_callback
, data
, &fhdr_view
))
652 const char *magic
= (const char *) fhdr_view
.data
;
653 magic_ok
= memcmp (magic
, "PE\0", 4) == 0;
656 memcpy (&fhdr
, fhdr_view
.data
+ 4, sizeof fhdr
);
660 memcpy (&fhdr
, fhdr_view
.data
, sizeof fhdr
);
661 /* TODO: test fhdr.machine for coff but non-PE platforms. */
664 backtrace_release_view (state
, &fhdr_view
, error_callback
, data
);
668 error_callback (data
, "executable file is not COFF", 0);
672 sects_num
= fhdr
.number_of_sections
;
673 syms_num
= fhdr
.number_of_symbols
;
675 opt_sects_off
= fhdr_off
+ sizeof (fhdr
);
676 opt_sects_size
= (fhdr
.size_of_optional_header
677 + sects_num
* sizeof (b_coff_section_header
));
679 /* To translate PC to file/line when using DWARF, we need to find
680 the .debug_info and .debug_line sections. */
682 /* Read the optional header and the section headers. */
684 if (!backtrace_get_view (state
, descriptor
, opt_sects_off
, opt_sects_size
,
685 error_callback
, data
, §s_view
))
687 sects_view_valid
= 1;
688 opt_hdr
= (const b_coff_optional_header
*) sects_view
.data
;
689 sects
= (const b_coff_section_header
*)
690 (sects_view
.data
+ fhdr
.size_of_optional_header
);
692 if (fhdr
.size_of_optional_header
> sizeof (*opt_hdr
))
694 if (opt_hdr
->magic
== PE_MAGIC
)
695 image_base
= opt_hdr
->u
.pe
.image_base
;
696 else if (opt_hdr
->magic
== PEP_MAGIC
)
697 image_base
= opt_hdr
->u
.pep
.image_base
;
700 error_callback (data
, "bad magic in PE optional header", 0);
707 /* Read the symbol table and the string table. */
709 if (fhdr
.pointer_to_symbol_table
== 0)
711 /* No symbol table, no string table. */
719 /* Symbol table is followed by the string table. The string table
720 starts with its length (on 4 bytes).
721 Map the symbol table and the length of the string table. */
722 syms_off
= fhdr
.pointer_to_symbol_table
;
723 syms_size
= syms_num
* SYM_SZ
;
725 if (!backtrace_get_view (state
, descriptor
, syms_off
, syms_size
+ 4,
726 error_callback
, data
, &syms_view
))
730 memcpy (&str_size
, syms_view
.data
+ syms_size
, 4);
732 str_off
= syms_off
+ syms_size
;
736 /* Map string table (including the length word). */
738 if (!backtrace_get_view (state
, descriptor
, str_off
, str_size
,
739 error_callback
, data
, &str_view
))
745 memset (sections
, 0, sizeof sections
);
747 /* Look for the symbol table. */
748 for (i
= 0; i
< sects_num
; ++i
)
750 const b_coff_section_header
*s
= sects
+ i
;
751 unsigned int str_off
;
754 if (s
->name
[0] == '/')
756 /* Extended section name. */
757 str_off
= atoi (s
->name
+ 1);
762 for (j
= 0; j
< (int) DEBUG_MAX
; ++j
)
764 const char *dbg_name
= debug_section_names
[j
];
768 match
= coff_long_name_eq (dbg_name
, str_off
, &str_view
);
770 match
= coff_short_name_eq (dbg_name
, s
->name
);
773 sections
[j
].offset
= s
->pointer_to_raw_data
;
774 sections
[j
].size
= s
->virtual_size
<= s
->size_of_raw_data
?
775 s
->virtual_size
: s
->size_of_raw_data
;
783 struct coff_syminfo_data
*sdata
;
785 sdata
= ((struct coff_syminfo_data
*)
786 backtrace_alloc (state
, sizeof *sdata
, error_callback
, data
));
790 if (!coff_initialize_syminfo (state
, image_base
,
792 syms_view
.data
, syms_size
,
793 str_view
.data
, str_size
,
794 error_callback
, data
, sdata
))
796 backtrace_free (state
, sdata
, sizeof *sdata
, error_callback
, data
);
802 coff_add_syminfo_data (state
, sdata
);
805 backtrace_release_view (state
, §s_view
, error_callback
, data
);
806 sects_view_valid
= 0;
807 backtrace_release_view (state
, &syms_view
, error_callback
, data
);
810 /* Read all the debug sections in a single view, since they are
811 probably adjacent in the file. We never release this view. */
815 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
819 if (sections
[i
].size
== 0)
821 if (min_offset
== 0 || sections
[i
].offset
< min_offset
)
822 min_offset
= sections
[i
].offset
;
823 end
= sections
[i
].offset
+ sections
[i
].size
;
824 if (end
> max_offset
)
827 if (min_offset
== 0 || max_offset
== 0)
829 if (!backtrace_close (descriptor
, error_callback
, data
))
831 *fileline_fn
= coff_nodebug
;
835 if (!backtrace_get_view (state
, descriptor
, min_offset
,
836 max_offset
- min_offset
,
837 error_callback
, data
, &debug_view
))
839 debug_view_valid
= 1;
841 /* We've read all we need from the executable. */
842 if (!backtrace_close (descriptor
, error_callback
, data
))
846 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
848 if (sections
[i
].size
== 0)
849 sections
[i
].data
= NULL
;
851 sections
[i
].data
= ((const unsigned char *) debug_view
.data
852 + (sections
[i
].offset
- min_offset
));
855 if (!backtrace_dwarf_add (state
, /* base_address */ 0,
856 sections
[DEBUG_INFO
].data
,
857 sections
[DEBUG_INFO
].size
,
858 sections
[DEBUG_LINE
].data
,
859 sections
[DEBUG_LINE
].size
,
860 sections
[DEBUG_ABBREV
].data
,
861 sections
[DEBUG_ABBREV
].size
,
862 sections
[DEBUG_RANGES
].data
,
863 sections
[DEBUG_RANGES
].size
,
864 sections
[DEBUG_STR
].data
,
865 sections
[DEBUG_STR
].size
,
867 error_callback
, data
, fileline_fn
))
875 if (sects_view_valid
)
876 backtrace_release_view (state
, §s_view
, error_callback
, data
);
878 backtrace_release_view (state
, &str_view
, error_callback
, data
);
880 backtrace_release_view (state
, &syms_view
, error_callback
, data
);
881 if (debug_view_valid
)
882 backtrace_release_view (state
, &debug_view
, error_callback
, data
);
883 if (descriptor
!= -1)
884 backtrace_close (descriptor
, error_callback
, data
);
888 /* Initialize the backtrace data we need from an ELF executable. At
889 the ELF level, all we need to do is find the debug info
893 backtrace_initialize (struct backtrace_state
*state
,
894 const char *filename ATTRIBUTE_UNUSED
, int descriptor
,
895 backtrace_error_callback error_callback
,
896 void *data
, fileline
*fileline_fn
)
901 fileline coff_fileline_fn
;
903 ret
= coff_add (state
, descriptor
, error_callback
, data
,
904 &coff_fileline_fn
, &found_sym
, &found_dwarf
);
908 if (!state
->threaded
)
911 state
->syminfo_fn
= coff_syminfo
;
912 else if (state
->syminfo_fn
== NULL
)
913 state
->syminfo_fn
= coff_nosyms
;
918 backtrace_atomic_store_pointer (&state
->syminfo_fn
, coff_syminfo
);
920 __sync_bool_compare_and_swap (&state
->syminfo_fn
, NULL
, coff_nosyms
);
923 if (!state
->threaded
)
925 if (state
->fileline_fn
== NULL
|| state
->fileline_fn
== coff_nodebug
)
926 *fileline_fn
= coff_fileline_fn
;
932 current_fn
= backtrace_atomic_load_pointer (&state
->fileline_fn
);
933 if (current_fn
== NULL
|| current_fn
== coff_nodebug
)
934 *fileline_fn
= coff_fileline_fn
;