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 unsigned long func_rva,
159 char *qualified_name, *bare_name;
167 if (sym_name == NULL || *sym_name ==
'\0')
170 bare_name = xstrdup (sym_name);
172 qualified_name =
xstrprintf (
"%s!%s", dll_name, bare_name);
176 " for entry \"%s\" in dll \"%s\"\n"),
181 section_data->
index, objfile);
185 section_data->
index, objfile);
188 " in dll \"%s\"\n"), sym_name, dll_name);
189 xfree (qualified_name);
204 const char *forward_func_name,
int ordinal,
210 char *qualified_name, *bare_name;
211 int forward_dll_name_len = strlen (forward_dll_name);
212 int forward_func_name_len = strlen (forward_func_name);
213 int forward_len = forward_dll_name_len + forward_func_name_len + 2;
214 char *forward_qualified_name = alloca (forward_len);
217 xsnprintf (forward_qualified_name, forward_len,
"%s!%s", forward_dll_name,
227 for (i = 0; i < forward_dll_name_len; i++)
228 forward_qualified_name[i] = tolower (forward_qualified_name[i]);
236 " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"),
237 forward_func_name, forward_dll_name, sym_name,
244 " \"%s\" in dll \"%s\", pointing to \"%s\"\n"),
245 sym_name, dll_name, forward_qualified_name);
255 if (sym_name == NULL || *sym_name ==
'\0')
258 bare_name = xstrdup (sym_name);
260 qualified_name =
xstrprintf (
"%s!%s", dll_name, bare_name);
270 msymtype, section, objfile);
275 xfree (qualified_name);
286 char *last_point = strrchr (dll_name,
'.');
288 if (last_point != NULL)
298 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
299 bfd_bread (b, (bfd_size_type) 2, abfd);
300 return b[0] + (b[1] << 8);
308 bfd_seek (abfd, (file_ptr) where,
SEEK_SET);
309 bfd_bread (b, (bfd_size_type) 4, abfd);
310 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
316 unsigned char *b = ptr;
318 return b[0] + (b[1] << 8);
324 unsigned char *b = ptr;
326 return b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
336 bfd *dll = objfile->
obfd;
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);
366 section_data[i].vma_offset = 0;
367 section_data[i].rva_start = 1;
368 section_data[i].rva_end = 0;
377 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
378 || strcmp (target,
"pei-x86-64") == 0);
379 is_pe32 = (strcmp (target,
"pe-i386") == 0
380 || strcmp (target,
"pei-i386") == 0
381 || strcmp (target,
"pe-arm-wince-little") == 0
382 || strcmp (target,
"pei-arm-wince-little") == 0);
383 if (!is_pe32 && !is_pe64)
393 pe_header_offset =
pe_get32 (dll, 0x3c);
394 opthdr_ofs = pe_header_offset + 4 + 20;
396 num_entries =
pe_get32 (dll, opthdr_ofs + 108);
398 num_entries =
pe_get32 (dll, opthdr_ofs + 92);
407 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 112);
408 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 116);
412 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 96);
413 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 100);
415 nsections =
pe_get16 (dll, pe_header_offset + 4 + 2);
416 secptr = (pe_header_offset + 4 + 20 +
417 pe_get16 (dll, pe_header_offset + 4 + 16));
422 for (i = 0; i < nsections; i++)
425 unsigned long secptr1 = secptr + 40 * i;
426 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
427 unsigned long vsize =
pe_get32 (dll, secptr1 + 16);
428 unsigned long fptr =
pe_get32 (dll, secptr1 + 20);
430 bfd_seek (dll, (file_ptr) secptr1,
SEEK_SET);
431 bfd_bread (sname, (bfd_size_type)
sizeof (sname), dll);
433 if ((strcmp (sname,
".edata") == 0)
434 || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
436 if (strcmp (sname,
".edata") != 0)
440 "\"%s\" is in section \"%s\"\n"),
445 " for dll \"%s\": 0x%lx instead of 0x%lx\n"),
446 dll_name, export_opthdrrva, vaddr);
447 expptr = fptr + (export_opthdrrva - vaddr);
452 export_rva = export_opthdrrva;
453 export_size = export_opthdrsize;
455 if (export_size == 0)
464 for (i = 0; i < nsections; i++)
466 unsigned long secptr1 = secptr + 40 * i;
467 unsigned long vsize =
pe_get32 (dll, secptr1 + 8);
468 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12);
469 unsigned long characteristics =
pe_get32 (dll, secptr1 + 36);
470 char sec_name[SCNNMLEN + 1];
472 unsigned int bfd_section_index;
475 bfd_seek (dll, (file_ptr) secptr1 + 0,
SEEK_SET);
476 bfd_bread (sec_name, (bfd_size_type) SCNNMLEN, dll);
477 sec_name[SCNNMLEN] =
'\0';
480 section = bfd_get_section_by_name (dll, sec_name);
482 bfd_section_index = section->index;
484 bfd_section_index = -1;
488 section_data[sectix].rva_start = vaddr;
489 section_data[sectix].rva_end = vaddr + vsize;
490 section_data[sectix].index = bfd_section_index;
496 section_data =
xrealloc (section_data, (otherix + 1)
498 name = xstrdup (sec_name);
499 section_data[otherix].section_name =
name;
501 section_data[otherix].rva_start = vaddr;
502 section_data[otherix].rva_end = vaddr + vsize;
503 section_data[otherix].vma_offset = 0;
504 section_data[otherix].index = bfd_section_index;
506 section_data[otherix].ms_type =
mst_text;
508 section_data[otherix].ms_type =
mst_data;
510 section_data[otherix].ms_type =
mst_bss;
517 expdata = (
unsigned char *)
xmalloc (export_size);
520 bfd_seek (dll, (file_ptr) expptr,
SEEK_SET);
521 bfd_bread (expdata, (bfd_size_type) export_size, dll);
522 erva = expdata - export_rva;
525 name_rvas =
pe_as32 (expdata + 32);
526 ordinals =
pe_as32 (expdata + 36);
527 ordbase =
pe_as32 (expdata + 16);
528 exp_funcbase =
pe_as32 (expdata + 28);
531 dll_name = (
char *) (
pe_as32 (expdata + 12) + erva);
544 " base=%ld\n"), dll_name, nexp, ordbase);
548 for (i = 0; i < nexp; i++)
551 unsigned long name_rva =
pe_as32 (erva + name_rvas + i * 4);
554 unsigned long ordinal =
pe_as16 (erva + ordinals + i * 2);
559 unsigned long func_rva =
pe_as32 (erva + exp_funcbase +
564 int section_found = 0;
567 if (func_rva >= export_rva && func_rva < export_rva + export_size)
569 char *forward_name = (
char *) (erva + func_rva);
570 char *funcname = (
char *) (erva + name_rva);
571 char *forward_dll_name = forward_name;
572 char *forward_func_name = forward_name;
573 char *sep = strrchr (forward_name,
'.');
577 int len = (
int) (sep - forward_name);
579 forward_dll_name = alloca (len + 1);
580 strncpy (forward_dll_name, forward_name, len);
581 forward_dll_name[
len] =
'\0';
582 forward_func_name = ++sep;
585 forward_func_name, ordinal,
586 dll_name, objfile) != 0)
591 for (sectix = 0; sectix < otherix; ++sectix)
593 if ((func_rva >= section_data[sectix].rva_start)
594 && (func_rva < section_data[sectix].rva_end))
596 char *sym_name = (
char *) (erva + name_rva);
600 section_data + sectix, dll_name, objfile);
607 char *funcname = (
char *) (erva + name_rva);
612 section_data, dll_name, objfile);
617 " RVA 0x%lx in dll \"%s\" not handled\n"),
618 funcname, ordinal, func_rva, dll_name);
624 " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,
625 nbforward, nbnormal + nbforward, nexp);
638 #define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000
644 unsigned long pe_header_offset, i;
645 unsigned long nsections, secptr;
653 target = bfd_get_target (abfd);
655 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
656 || strcmp (target,
"pei-x86-64") == 0);
657 is_pe32 = (strcmp (target,
"pe-i386") == 0
658 || strcmp (target,
"pei-i386") == 0
659 || strcmp (target,
"pe-arm-wince-little") == 0
660 || strcmp (target,
"pei-arm-wince-little") == 0);
662 if (!is_pe32 && !is_pe64)
671 pe_header_offset =
pe_get32 (abfd, 0x3c);
672 nsections =
pe_get16 (abfd, pe_header_offset + 4 + 2);
673 secptr = (pe_header_offset + 4 + 20 +
674 pe_get16 (abfd, pe_header_offset + 4 + 16));
677 for (i = 0; i < nsections; i++)
679 char sname[SCNNMLEN + 1];
680 unsigned long secptr1 = secptr + 40 * i;
681 unsigned long vaddr =
pe_get32 (abfd, secptr1 + 12);
683 bfd_seek (abfd, (file_ptr) secptr1,
SEEK_SET);
684 bfd_bread (sname, (bfd_size_type) SCNNMLEN, abfd);
685 sname[SCNNMLEN] =
'\0';
686 if (strcmp (sname,
".text") == 0)
713 _(
"Set coff PE read debugging."),
714 _(
"Show coff PE read debugging."),
715 _(
"When set, debugging messages for coff reading "
716 "of exported symbols are displayed."),
CORE_ADDR pe_text_section_offset(struct bfd *abfd)
#define SECT_OFF_TEXT(objfile)
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_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
#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
#define PE_SECTION_TABLE_SIZE
static unsigned int pe_as32(void *ptr)
struct minimal_symbol * prim_record_minimal_symbol_and_info(const char *name, CORE_ADDR address, enum minimal_symbol_type ms_type, int section, struct objfile *objfile)
#define PE_SECTION_INDEX_DATA
static int add_pe_forwarded_sym(const char *sym_name, const char *forward_dll_name, const char *forward_func_name, int ordinal, const char *dll_name, struct objfile *objfile)
void null_cleanup(void *arg)
void fprintf_filtered(struct ui_file *stream, const char *format,...)
void * xzalloc(size_t size)
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
static void add_pe_exported_sym(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)
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
struct ui_file * gdb_stdlog
enum minimal_symbol_type ms_type
void read_pe_exported_syms(struct objfile *objfile)
PTR xrealloc(PTR ptr, size_t size)
static unsigned int pe_as16(void *ptr)
void _initialize_coff_pe_read(void)
const char const char int
#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 * 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)
const ULONGEST const LONGEST len