36#include "gdbsupport/common-utils.h"
37#include "coff/internal.h"
60#define IMAGE_SCN_CNT_CODE 0x20
61#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x40
62#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x80
63#define PE_SECTION_INDEX_TEXT 0
64#define PE_SECTION_INDEX_DATA 1
65#define PE_SECTION_INDEX_BSS 2
66#define PE_SECTION_TABLE_SIZE 3
67#define PE_SECTION_INDEX_INVALID -1
76 if (strcmp (section_name,
".text") == 0)
81 else if (strcmp (section_name,
".data") == 0)
86 else if (strcmp (section_name,
".bss") == 0)
103 const std::vector<read_pe_section_data> §ions)
105 for (
int i = 0; i < sections.size (); i++)
106 if (sections[i].section_name == section_name)
123 const char *sym_name,
124 unsigned long func_rva,
130 CORE_ADDR vma = func_rva + section_data->
vma_offset;
136 std::string bare_name;
137 if (sym_name == NULL || *sym_name ==
'\0')
138 bare_name = string_printf (
"#%d", ordinal);
140 bare_name = sym_name;
142 std::string qualified_name
143 = string_printf (
"%s!%s", dll_name, bare_name.c_str ());
147 " for entry \"%s\" in dll \"%s\"\n"),
152 section_data->
index);
156 section_data->
index);
159 " in dll \"%s\"\n"), sym_name, dll_name);
173 const char *sym_name,
const char *forward_dll_name,
174 const char *forward_func_name,
int ordinal,
177 CORE_ADDR vma, baseaddr;
180 int forward_dll_name_len = strlen (forward_dll_name);
183 std::string forward_qualified_name = string_printf (
"%s!%s",
193 for (i = 0; i < forward_dll_name_len; i++)
194 forward_qualified_name[i] = tolower (forward_qualified_name[i]);
202 " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"),
203 forward_func_name, forward_dll_name, sym_name,
210 " \"%s\" in dll \"%s\", pointing to \"%s\"\n"),
211 sym_name, dll_name, forward_qualified_name.c_str ());
221 std::string bare_name;
222 if (sym_name == NULL || *sym_name ==
'\0')
223 bare_name = string_printf (
"#%d", ordinal);
225 bare_name = sym_name;
227 std::string qualified_name
228 = string_printf (
"%s!%s", dll_name, bare_name.c_str ());
252 char *last_point = strrchr (dll_name,
'.');
254 if (last_point != NULL)
264 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
265 bfd_bread (b, (bfd_size_type) 2, abfd);
266 return b[0] + (b[1] << 8);
274 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
275 bfd_bread (b, (bfd_size_type) 4, abfd);
276 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
282 unsigned char *b = (
unsigned char *) ptr;
284 return b[0] + (b[1] << 8);
290 unsigned char *b = (
unsigned char *) ptr;
292 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
304 unsigned long nbnormal, nbforward;
305 unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
306 unsigned long export_opthdrrva, export_opthdrsize;
307 unsigned long export_rva, export_size, nsections, secptr, expptr;
308 unsigned long exp_funcbase;
309 unsigned char *expdata, *erva;
310 unsigned long name_rvas, ordinals, nexp, ordbase;
315 char const *target = bfd_get_target (
objfile->
obfd.get ());
317 std::vector<struct read_pe_section_data> section_data
322 section_data[i].vma_offset = 0;
323 section_data[i].rva_start = 1;
324 section_data[i].rva_end = 0;
333 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
334 || strcmp (target,
"pei-x86-64") == 0
335 || strcmp (target,
"pe-aarch64") == 0
336 || strcmp (target,
"pei-aarch64") == 0);
337 is_pe32 = (strcmp (target,
"pe-i386") == 0
338 || strcmp (target,
"pei-i386") == 0
339 || strcmp (target,
"pe-arm-wince-little") == 0
340 || strcmp (target,
"pei-arm-wince-little") == 0);
341 if (!is_pe32 && !is_pe64)
350 pe_header_offset =
pe_get32 (dll, 0x3c);
351 opthdr_ofs = pe_header_offset + 4 + 20;
353 num_entries =
pe_get32 (dll, opthdr_ofs + 108);
355 num_entries =
pe_get32 (dll, opthdr_ofs + 92);
361 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 112);
362 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 116);
366 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 96);
367 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 100);
369 nsections =
pe_get16 (dll, pe_header_offset + 4 + 2);
370 secptr = (pe_header_offset + 4 + 20 +
371 pe_get16 (dll, pe_header_offset + 4 + 16));
376 for (i = 0; i < nsections; i++)
379 unsigned long secptr1 = secptr + 40 * i;
380 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
381 unsigned long vsize =
pe_get32 (dll, secptr1 + 16);
382 unsigned long fptr =
pe_get32 (dll, secptr1 + 20);
384 bfd_seek (dll, (file_ptr) secptr1,
SEEK_SET);
385 bfd_bread (sname, (bfd_size_type)
sizeof (sname), dll);
387 if ((strcmp (sname,
".edata") == 0)
388 || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
390 if (strcmp (sname,
".edata") != 0)
394 "\"%s\" is in section \"%s\"\n"),
395 bfd_get_filename (dll), sname);
399 " for dll \"%s\": 0x%lx instead of 0x%lx\n"),
400 bfd_get_filename (dll), export_opthdrrva, vaddr);
401 expptr = fptr + (export_opthdrrva - vaddr);
412 export_rva = export_opthdrrva;
413 export_size = export_opthdrsize;
415 if (export_size == 0)
423 for (i = 0; i < nsections; i++)
425 unsigned long secptr1 = secptr + 40 * i;
426 unsigned long vsize =
pe_get32 (dll, secptr1 + 8);
427 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
428 unsigned long characteristics =
pe_get32 (dll, secptr1 + 36);
429 char sec_name[SCNNMLEN + 1];
431 unsigned int bfd_section_index;
434 bfd_seek (dll, (file_ptr) secptr1 + 0,
SEEK_SET);
435 bfd_bread (sec_name, (bfd_size_type) SCNNMLEN, dll);
436 sec_name[SCNNMLEN] =
'\0';
439 section = bfd_get_section_by_name (dll, sec_name);
441 bfd_section_index = section->index;
443 bfd_section_index = -1;
447 section_data[sectix].rva_start = vaddr;
448 section_data[sectix].rva_end = vaddr + vsize;
449 section_data[sectix].index = bfd_section_index;
453 section_data.resize (otherix + 1);
454 section_data[otherix].section_name = sec_name;
455 section_data[otherix].rva_start = vaddr;
456 section_data[otherix].rva_end = vaddr + vsize;
457 section_data[otherix].vma_offset = 0;
458 section_data[otherix].index = bfd_section_index;
460 section_data[otherix].ms_type =
mst_text;
462 section_data[otherix].ms_type =
mst_data;
464 section_data[otherix].ms_type =
mst_bss;
471 gdb::def_vector<unsigned char> expdata_storage (export_size);
472 expdata = expdata_storage.data ();
474 bfd_seek (dll, (file_ptr) expptr,
SEEK_SET);
475 bfd_bread (expdata, (bfd_size_type) export_size, dll);
476 erva = expdata - export_rva;
479 name_rvas =
pe_as32 (expdata + 32);
480 ordinals =
pe_as32 (expdata + 36);
481 ordbase =
pe_as32 (expdata + 16);
482 exp_funcbase =
pe_as32 (expdata + 28);
485 char *dll_name = (
char *) (
pe_as32 (expdata + 12) + erva);
494 section_data[sectix].vma_offset
495 = bfd_section_vma (sectp) - section_data[sectix].rva_start;
505 " base=%ld\n"), dll_name, nexp, ordbase);
509 for (i = 0; i < nexp; i++)
512 unsigned long name_rva =
pe_as32 (erva + name_rvas + i * 4);
515 unsigned long ordinal =
pe_as16 (erva + ordinals + i * 2);
520 unsigned long func_rva =
pe_as32 (erva + exp_funcbase +
525 int section_found = 0;
528 if (func_rva >= export_rva && func_rva < export_rva + export_size)
530 const char *forward_name = (
const char *) (erva + func_rva);
531 const char *funcname = (
const char *) (erva + name_rva);
532 const char *forward_dll_name = forward_name;
533 const char *forward_func_name = forward_name;
534 const char *sep = strrchr (forward_name,
'.');
536 std::string name_storage;
539 int len = (int) (sep - forward_name);
541 name_storage = std::string (forward_name, len);
542 forward_dll_name = name_storage.c_str ();
543 forward_func_name = sep + 1;
546 forward_func_name, ordinal,
552 for (sectix = 0; sectix < otherix; ++sectix)
554 if ((func_rva >= section_data[sectix].rva_start)
555 && (func_rva < section_data[sectix].rva_end))
557 const char *sym_name = (
const char *) (erva + name_rva);
561 §ion_data[sectix], dll_name,
objfile);
568 const char *funcname = (
const char *) (erva + name_rva);
573 §ion_data[0], dll_name,
objfile);
578 " RVA 0x%lx in dll \"%s\" not handled\n"),
579 funcname, ordinal, func_rva, dll_name);
585 " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,
586 nbforward, nbnormal + nbforward, nexp);
597#define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000
603 unsigned long pe_header_offset, i;
604 unsigned long nsections, secptr;
612 target = bfd_get_target (abfd);
614 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
615 || strcmp (target,
"pei-x86-64") == 0
616 || strcmp (target,
"pe-aarch64") == 0
617 || strcmp (target,
"pei-aarch64") == 0);
618 is_pe32 = (strcmp (target,
"pe-i386") == 0
619 || strcmp (target,
"pei-i386") == 0
620 || strcmp (target,
"pe-arm-wince-little") == 0
621 || strcmp (target,
"pei-arm-wince-little") == 0);
623 if (!is_pe32 && !is_pe64)
632 pe_header_offset =
pe_get32 (abfd, 0x3c);
633 nsections =
pe_get16 (abfd, pe_header_offset + 4 + 2);
634 secptr = (pe_header_offset + 4 + 20 +
635 pe_get16 (abfd, pe_header_offset + 4 + 16));
638 for (i = 0; i < nsections; i++)
640 char sname[SCNNMLEN + 1];
641 unsigned long secptr1 = secptr + 40 * i;
642 unsigned long vaddr =
pe_get32 (abfd, secptr1 + 12);
644 bfd_seek (abfd, (file_ptr) secptr1,
SEEK_SET);
645 bfd_bread (sname, (bfd_size_type) SCNNMLEN, abfd);
646 sname[SCNNMLEN] =
'\0';
647 if (strcmp (sname,
".text") == 0)
671 _(
"Set coff PE read debugging."),
672 _(
"Show coff PE read debugging."),
673 _(
"When set, debugging messages for coff reading "
674 "of exported symbols are displayed."),
void record_with_info(const char *name, CORE_ADDR address, enum minimal_symbol_type ms_type, int section)
struct cmd_list_element * showdebuglist
struct cmd_list_element * setdebuglist
set_show_commands add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static void read_pe_truncate_name(char *dll_name)
static unsigned int pe_as32(void *ptr)
static int get_pe_section_index(const char *section_name, const std::vector< read_pe_section_data > §ions)
void _initialize_coff_pe_read()
static int read_pe_section_index(const char *section_name)
static void add_pe_exported_sym(minimal_symbol_reader &reader, const char *sym_name, unsigned long func_rva, int ordinal, const struct read_pe_section_data *section_data, const char *dll_name, struct objfile *objfile)
#define PE_SECTION_INDEX_TEXT
#define IMAGE_SCN_CNT_INITIALIZED_DATA
#define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET
#define IMAGE_SCN_CNT_CODE
static void show_debug_coff_pe_read(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
static unsigned int pe_get32(bfd *abfd, int where)
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA
static unsigned int debug_coff_pe_read
void read_pe_exported_syms(minimal_symbol_reader &reader, struct objfile *objfile)
#define PE_SECTION_INDEX_INVALID
#define PE_SECTION_TABLE_SIZE
static int add_pe_forwarded_sym(minimal_symbol_reader &reader, const char *sym_name, const char *forward_dll_name, const char *forward_func_name, int ordinal, const char *dll_name, struct objfile *objfile)
#define PE_SECTION_INDEX_BSS
static unsigned int pe_as16(void *ptr)
static unsigned int pe_get16(bfd *abfd, int where)
#define PE_SECTION_INDEX_DATA
CORE_ADDR pe_text_section_offset(struct bfd *abfd)
static gdb_bfd_section_range gdb_bfd_sections(bfd *abfd)
struct bound_minimal_symbol lookup_bound_minimal_symbol(const char *name)
CORE_ADDR value_address() const
struct minimal_symbol * minsym
short section_index() const
minimal_symbol_type type() const
CORE_ADDR text_section_offset() const
enum minimal_symbol_type ms_type
void gdb_printf(struct ui_file *stream, const char *format,...)