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)
108 for (i = 0; i < nb_sections; i++)
109 if (strcmp (sections[i].section_name, section_name) == 0)
139 = bfd_get_section_vma (abfd, sectp) - sections[sectix].
rva_start;
154 const char *sym_name,
155 unsigned long func_rva,
160 char *qualified_name, *bare_name;
168 if (sym_name == NULL || *sym_name ==
'\0')
171 bare_name = xstrdup (sym_name);
173 qualified_name =
xstrprintf (
"%s!%s", dll_name, bare_name);
177 " for entry \"%s\" in dll \"%s\"\n"),
181 section_data->
index);
185 section_data->
index);
188 " in dll \"%s\"\n"), sym_name, dll_name);
189 xfree (qualified_name);
204 const char *sym_name,
const char *forward_dll_name,
205 const char *forward_func_name,
int ordinal,
211 char *qualified_name, *bare_name;
212 int forward_dll_name_len = strlen (forward_dll_name);
213 int forward_func_name_len = strlen (forward_func_name);
214 int forward_len = forward_dll_name_len + forward_func_name_len + 2;
215 char *forward_qualified_name = (
char *) alloca (forward_len);
218 xsnprintf (forward_qualified_name, forward_len,
"%s!%s", forward_dll_name,
228 for (i = 0; i < forward_dll_name_len; i++)
229 forward_qualified_name[i] = tolower (forward_qualified_name[i]);
237 " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"),
238 forward_func_name, forward_dll_name, sym_name,
245 " \"%s\" in dll \"%s\", pointing to \"%s\"\n"),
246 sym_name, dll_name, forward_qualified_name);
256 if (sym_name == NULL || *sym_name ==
'\0')
259 bare_name = xstrdup (sym_name);
261 qualified_name =
xstrprintf (
"%s!%s", dll_name, bare_name);
270 reader.
record_with_info (qualified_name, vma - baseaddr, msymtype, section);
274 xfree (qualified_name);
285 char *last_point = strrchr (dll_name,
'.');
287 if (last_point != NULL)
297 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
298 bfd_bread (b, (bfd_size_type) 2, abfd);
299 return b[0] + (b[1] << 8);
307 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
308 bfd_bread (b, (bfd_size_type) 4, abfd);
309 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
315 unsigned char *b = (
unsigned char *) ptr;
317 return b[0] + (b[1] << 8);
323 unsigned char *b = (
unsigned char *) ptr;
325 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
337 unsigned long nbnormal, nbforward;
338 unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
339 unsigned long export_opthdrrva, export_opthdrsize;
340 unsigned long export_rva, export_size, nsections, secptr, expptr;
341 unsigned long exp_funcbase;
342 unsigned char *expdata, *erva;
343 unsigned long name_rvas, ordinals, nexp, ordbase;
344 char *dll_name = (
char *) dll->filename;
357 char const *target = bfd_get_target (
objfile->
obfd);
365 section_data[i].vma_offset = 0;
366 section_data[i].rva_start = 1;
367 section_data[i].rva_end = 0;
376 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
377 || strcmp (target,
"pei-x86-64") == 0);
378 is_pe32 = (strcmp (target,
"pe-i386") == 0
379 || strcmp (target,
"pei-i386") == 0
380 || strcmp (target,
"pe-arm-wince-little") == 0
381 || strcmp (target,
"pei-arm-wince-little") == 0);
382 if (!is_pe32 && !is_pe64)
392 pe_header_offset =
pe_get32 (dll, 0x3c);
393 opthdr_ofs = pe_header_offset + 4 + 20;
395 num_entries =
pe_get32 (dll, opthdr_ofs + 108);
397 num_entries =
pe_get32 (dll, opthdr_ofs + 92);
406 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 112);
407 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 116);
411 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 96);
412 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 100);
414 nsections =
pe_get16 (dll, pe_header_offset + 4 + 2);
415 secptr = (pe_header_offset + 4 + 20 +
416 pe_get16 (dll, pe_header_offset + 4 + 16));
421 for (i = 0; i < nsections; i++)
424 unsigned long secptr1 = secptr + 40 * i;
425 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
426 unsigned long vsize =
pe_get32 (dll, secptr1 + 16);
427 unsigned long fptr =
pe_get32 (dll, secptr1 + 20);
429 bfd_seek (dll, (file_ptr) secptr1,
SEEK_SET);
430 bfd_bread (sname, (bfd_size_type)
sizeof (sname), dll);
432 if ((strcmp (sname,
".edata") == 0)
433 || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
435 if (strcmp (sname,
".edata") != 0)
439 "\"%s\" is in section \"%s\"\n"),
444 " for dll \"%s\": 0x%lx instead of 0x%lx\n"),
445 dll_name, export_opthdrrva, vaddr);
446 expptr = fptr + (export_opthdrrva - vaddr);
451 export_rva = export_opthdrrva;
452 export_size = export_opthdrsize;
454 if (export_size == 0)
463 for (i = 0; i < nsections; i++)
465 unsigned long secptr1 = secptr + 40 * i;
466 unsigned long vsize =
pe_get32 (dll, secptr1 + 8);
467 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
468 unsigned long characteristics =
pe_get32 (dll, secptr1 + 36);
469 char sec_name[SCNNMLEN + 1];
471 unsigned int bfd_section_index;
474 bfd_seek (dll, (file_ptr) secptr1 + 0,
SEEK_SET);
475 bfd_bread (sec_name, (bfd_size_type) SCNNMLEN, dll);
476 sec_name[SCNNMLEN] =
'\0';
479 section = bfd_get_section_by_name (dll, sec_name);
481 bfd_section_index = section->index;
483 bfd_section_index = -1;
487 section_data[sectix].rva_start = vaddr;
488 section_data[sectix].rva_end = vaddr + vsize;
489 section_data[sectix].index = bfd_section_index;
497 name = xstrdup (sec_name);
498 section_data[otherix].section_name =
name;
500 section_data[otherix].rva_start = vaddr;
501 section_data[otherix].rva_end = vaddr + vsize;
502 section_data[otherix].vma_offset = 0;
503 section_data[otherix].index = bfd_section_index;
505 section_data[otherix].ms_type =
mst_text;
507 section_data[otherix].ms_type =
mst_data;
509 section_data[otherix].ms_type =
mst_bss;
516 expdata = (
unsigned char *)
xmalloc (export_size);
519 bfd_seek (dll, (file_ptr) expptr,
SEEK_SET);
520 bfd_bread (expdata, (bfd_size_type) export_size, dll);
521 erva = expdata - export_rva;
524 name_rvas =
pe_as32 (expdata + 32);
525 ordinals =
pe_as32 (expdata + 36);
526 ordbase =
pe_as32 (expdata + 16);
527 exp_funcbase =
pe_as32 (expdata + 28);
530 dll_name = (
char *) (
pe_as32 (expdata + 12) + erva);
543 " base=%ld\n"), dll_name, nexp, ordbase);
547 for (i = 0; i < nexp; i++)
550 unsigned long name_rva =
pe_as32 (erva + name_rvas + i * 4);
553 unsigned long ordinal =
pe_as16 (erva + ordinals + i * 2);
558 unsigned long func_rva =
pe_as32 (erva + exp_funcbase +
563 int section_found = 0;
566 if (func_rva >= export_rva && func_rva < export_rva + export_size)
568 char *forward_name = (
char *) (erva + func_rva);
569 char *funcname = (
char *) (erva + name_rva);
570 char *forward_dll_name = forward_name;
571 char *forward_func_name = forward_name;
572 char *sep = strrchr (forward_name,
'.');
576 int len = (int) (sep - forward_name);
578 forward_dll_name = (
char *) alloca (len + 1);
579 strncpy (forward_dll_name, forward_name, len);
580 forward_dll_name[len] =
'\0';
581 forward_func_name = ++sep;
584 forward_func_name, ordinal,
590 for (sectix = 0; sectix < otherix; ++sectix)
592 if ((func_rva >= section_data[sectix].rva_start)
593 && (func_rva < section_data[sectix].rva_end))
595 char *sym_name = (
char *) (erva + name_rva);
599 section_data + sectix, dll_name,
objfile);
606 char *funcname = (
char *) (erva + name_rva);
611 section_data, dll_name,
objfile);
616 " RVA 0x%lx in dll \"%s\" not handled\n"),
617 funcname, ordinal, func_rva, dll_name);
623 " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,
624 nbforward, nbnormal + nbforward, nexp);
637 #define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000 643 unsigned long pe_header_offset, i;
644 unsigned long nsections, secptr;
652 target = bfd_get_target (abfd);
654 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
655 || strcmp (target,
"pei-x86-64") == 0);
656 is_pe32 = (strcmp (target,
"pe-i386") == 0
657 || strcmp (target,
"pei-i386") == 0
658 || strcmp (target,
"pe-arm-wince-little") == 0
659 || strcmp (target,
"pei-arm-wince-little") == 0);
661 if (!is_pe32 && !is_pe64)
670 pe_header_offset =
pe_get32 (abfd, 0x3c);
671 nsections =
pe_get16 (abfd, pe_header_offset + 4 + 2);
672 secptr = (pe_header_offset + 4 + 20 +
673 pe_get16 (abfd, pe_header_offset + 4 + 16));
676 for (i = 0; i < nsections; i++)
678 char sname[SCNNMLEN + 1];
679 unsigned long secptr1 = secptr + 40 * i;
680 unsigned long vaddr =
pe_get32 (abfd, secptr1 + 12);
682 bfd_seek (abfd, (file_ptr) secptr1,
SEEK_SET);
683 bfd_bread (sname, (bfd_size_type) SCNNMLEN, abfd);
684 sname[SCNNMLEN] =
'\0';
685 if (strcmp (sname,
".text") == 0)
708 _(
"Set coff PE read debugging."),
709 _(
"Show coff PE read debugging."),
710 _(
"When set, debugging messages for coff reading " 711 "of exported symbols are displayed."),
CORE_ADDR pe_text_section_offset(struct bfd *abfd)
#define SECT_OFF_TEXT(objfile)
#define BMSYMBOL_VALUE_ADDRESS(symbol)
static int get_pe_section_index(const char *section_name, struct read_pe_section_data *sections, int nb_sections)
static unsigned int pe_get16(bfd *abfd, int where)
#define IMAGE_SCN_CNT_INITIALIZED_DATA
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_TABLE_SIZE
static unsigned int pe_as32(void *ptr)
#define PE_SECTION_INDEX_DATA
void 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_const_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
void read_pe_exported_syms(minimal_symbol_reader &reader, struct objfile *objfile)
void null_cleanup(void *arg)
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)
void fprintf_filtered(struct ui_file *stream, const char *format,...)
struct bound_minimal_symbol lookup_minimal_symbol_and_objfile(const char *name)
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
void free_current_contents(void *ptr)
static void show_debug_coff_pe_read(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
#define ANOFFSET(secoff, whichone)
static void get_section_vmas(bfd *abfd, asection *sectp, void *context)
#define PE_SECTION_INDEX_BSS
const char * section_name
static unsigned int pe_get32(bfd *abfd, int where)
#define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET
char * xstrprintf(const char *format,...)
struct cmd_list_element * setdebuglist
#define XRESIZEVEC(T, P, N)
enum minimal_symbol_type ms_type
static unsigned int pe_as16(void *ptr)
void _initialize_coff_pe_read(void)
#define MSYMBOL_TYPE(msymbol)
#define PE_SECTION_INDEX_TEXT
#define PE_SECTION_INDEX_INVALID
int xsnprintf(char *str, size_t size, const char *format,...)
struct minimal_symbol * record_with_info(const char *name, CORE_ADDR address, enum minimal_symbol_type ms_type, int section)
struct minimal_symbol * minsym
#define MSYMBOL_SECTION(symbol)
struct read_pe_section_data * sections
static void read_pe_truncate_name(char *dll_name)
struct cmd_list_element * showdebuglist
static int read_pe_section_index(const char *section_name)
#define IMAGE_SCN_CNT_CODE
struct section_offsets * section_offsets
static unsigned int debug_coff_pe_read
void do_cleanups(struct cleanup *old_chain)