309 unsigned long nbnormal, nbforward;
310 unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
311 unsigned long export_opthdrrva, export_opthdrsize;
312 unsigned long export_rva, export_size, nsections, secptr, expptr;
313 unsigned long exp_funcbase;
314 unsigned char *expdata, *erva;
315 unsigned long name_rvas, ordinals, nexp, ordbase;
320 char const *target = bfd_get_target (
objfile->
obfd.get ());
322 std::vector<struct read_pe_section_data> section_data
327 section_data[i].vma_offset = 0;
328 section_data[i].rva_start = 1;
329 section_data[i].rva_end = 0;
338 is_pe64 = (strcmp (target,
"pe-x86-64") == 0
339 || strcmp (target,
"pei-x86-64") == 0
340 || strcmp (target,
"pe-aarch64") == 0
341 || strcmp (target,
"pei-aarch64") == 0);
342 is_pe32 = (strcmp (target,
"pe-i386") == 0
343 || strcmp (target,
"pei-i386") == 0
344 || strcmp (target,
"pe-arm-wince-little") == 0
345 || strcmp (target,
"pei-arm-wince-little") == 0);
348 auto maybe_print_debug_msg = [&] () ->
void {
351 bfd_get_filename (dll));
354 if (!is_pe32 && !is_pe64)
355 return maybe_print_debug_msg ();
359 pe_header_offset =
pe_get32 (dll, 0x3c, &fail);
361 return maybe_print_debug_msg ();
362 opthdr_ofs = pe_header_offset + 4 + 20;
364 num_entries =
pe_get32 (dll, opthdr_ofs + 108, &fail);
366 num_entries =
pe_get32 (dll, opthdr_ofs + 92, &fail);
368 return maybe_print_debug_msg ();
374 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 112, &fail);
375 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 116, &fail);
379 export_opthdrrva =
pe_get32 (dll, opthdr_ofs + 96, &fail);
380 export_opthdrsize =
pe_get32 (dll, opthdr_ofs + 100, &fail);
383 return maybe_print_debug_msg ();
385 nsections =
pe_get16 (dll, pe_header_offset + 4 + 2, &fail);
386 secptr = (pe_header_offset + 4 + 20 +
387 pe_get16 (dll, pe_header_offset + 4 + 16, &fail));
389 return maybe_print_debug_msg ();
394 for (i = 0; i < nsections; i++)
397 unsigned long secptr1 = secptr + 40 * i;
398 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12, &fail);
399 unsigned long vsize =
pe_get32 (dll, secptr1 + 16, &fail);
400 unsigned long fptr =
pe_get32 (dll, secptr1 + 20, &fail);
403 || bfd_seek (dll, secptr1,
SEEK_SET) != 0
404 || bfd_read (sname,
sizeof (sname), dll) !=
sizeof (sname))
405 return maybe_print_debug_msg ();
407 if ((strcmp (sname,
".edata") == 0)
408 || (vaddr <= export_opthdrrva && export_opthdrrva < vaddr + vsize))
410 if (strcmp (sname,
".edata") != 0)
414 "\"%s\" is in section \"%s\"\n"),
415 bfd_get_filename (dll), sname);
419 " for dll \"%s\": 0x%lx instead of 0x%lx\n"),
420 bfd_get_filename (dll), export_opthdrrva, vaddr);
421 expptr = fptr + (export_opthdrrva - vaddr);
432 export_rva = export_opthdrrva;
433 export_size = export_opthdrsize;
435 if (export_size == 0)
443 for (i = 0; i < nsections; i++)
445 unsigned long secptr1 = secptr + 40 * i;
446 unsigned long vsize =
pe_get32 (dll, secptr1 + 8, &fail);
447 unsigned long vaddr =
pe_get32 (dll, secptr1 + 12, &fail);
448 unsigned long characteristics =
pe_get32 (dll, secptr1 + 36, &fail);
449 char sec_name[SCNNMLEN + 1];
451 unsigned int bfd_section_index;
455 || bfd_seek (dll, secptr1 + 0,
SEEK_SET) != 0
456 || bfd_read (sec_name, SCNNMLEN, dll) != SCNNMLEN)
457 return maybe_print_debug_msg ();
458 sec_name[SCNNMLEN] =
'\0';
461 section = bfd_get_section_by_name (dll, sec_name);
463 bfd_section_index = section->index;
465 bfd_section_index = -1;
469 section_data[sectix].rva_start = vaddr;
470 section_data[sectix].rva_end = vaddr + vsize;
471 section_data[sectix].index = bfd_section_index;
475 section_data.resize (otherix + 1);
476 section_data[otherix].section_name = sec_name;
477 section_data[otherix].rva_start = vaddr;
478 section_data[otherix].rva_end = vaddr + vsize;
479 section_data[otherix].vma_offset = 0;
480 section_data[otherix].index = bfd_section_index;
482 section_data[otherix].ms_type =
mst_text;
484 section_data[otherix].ms_type =
mst_data;
486 section_data[otherix].ms_type =
mst_bss;
493 gdb::def_vector<unsigned char> expdata_storage (export_size);
494 expdata = expdata_storage.data ();
496 if (bfd_seek (dll, expptr,
SEEK_SET) != 0
497 || bfd_read (expdata, export_size, dll) != export_size)
498 return maybe_print_debug_msg ();
499 erva = expdata - export_rva;
502 name_rvas =
pe_as32 (expdata + 32);
503 ordinals =
pe_as32 (expdata + 36);
504 ordbase =
pe_as32 (expdata + 16);
505 exp_funcbase =
pe_as32 (expdata + 28);
508 char *dll_name = (
char *) (
pe_as32 (expdata + 12) + erva);
517 section_data[sectix].vma_offset
518 = bfd_section_vma (sectp) - section_data[sectix].rva_start;
528 " base=%ld\n"), dll_name, nexp, ordbase);
532 for (i = 0; i < nexp; i++)
535 unsigned long name_rva =
pe_as32 (erva + name_rvas + i * 4);
538 unsigned long ordinal =
pe_as16 (erva + ordinals + i * 2);
543 unsigned long func_rva =
pe_as32 (erva + exp_funcbase +
548 int section_found = 0;
551 if (func_rva >= export_rva && func_rva < export_rva + export_size)
553 const char *forward_name = (
const char *) (erva + func_rva);
554 const char *funcname = (
const char *) (erva + name_rva);
555 const char *forward_dll_name = forward_name;
556 const char *forward_func_name = forward_name;
557 const char *sep = strrchr (forward_name,
'.');
559 std::string name_storage;
562 int len = (int) (sep - forward_name);
564 name_storage = std::string (forward_name, len);
565 forward_dll_name = name_storage.c_str ();
566 forward_func_name = sep + 1;
569 forward_func_name, ordinal,
575 for (sectix = 0; sectix < otherix; ++sectix)
577 if ((func_rva >= section_data[sectix].rva_start)
578 && (func_rva < section_data[sectix].rva_end))
580 const char *sym_name = (
const char *) (erva + name_rva);
584 §ion_data[sectix], dll_name,
objfile);
591 const char *funcname = (
const char *) (erva + name_rva);
596 §ion_data[0], dll_name,
objfile);
601 " RVA 0x%lx in dll \"%s\" not handled\n"),
602 funcname, ordinal, func_rva, dll_name);
608 " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,
609 nbforward, nbnormal + nbforward, nexp);