1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
26 #define TARGET_SYM x86_64_pei_vec
27 #define TARGET_NAME "pei-x86-64"
28 #define COFF_IMAGE_WITH_PE
30 #define COFF_WITH_pex64
31 #define PCRELOFFSET true
32 #if defined (USE_MINGW64_LEADING_UNDERSCORES)
33 #define TARGET_UNDERSCORE '_'
35 #define TARGET_UNDERSCORE 0
37 /* Long section names not allowed in executable images, only object files. */
38 #define COFF_LONG_SECTION_NAMES 0
39 #define COFF_SUPPORT_GNU_LINKONCE
40 #define COFF_LONG_FILENAMES
41 #define PDATA_ROW_SIZE (3 * 4)
43 #define COFF_SECTION_ALIGNMENT_ENTRIES \
44 { COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
45 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
46 { COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
47 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
48 { COFF_SECTION_NAME_PARTIAL_MATCH (".rdata"), \
49 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
50 { COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
51 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
52 { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
53 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
54 { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
55 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
56 { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
57 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
58 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
59 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
61 /* Note we have to make sure not to include headers twice.
62 Not all headers are wrapped in #ifdef guards, so we define
63 PEI_HEADERS to prevent double including in coff-x86_64.c */
68 #include "coff/x86_64.h"
69 #include "coff/internal.h"
73 #include "libiberty.h"
76 #define AOUTSZ PEPAOUTSZ
77 #define PEAOUTHDR PEPAOUTHDR
79 /* Name of registers according to SEH conventions. */
81 static const char * const pex_regs
[16] = {
82 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
86 /* Swap in a runtime function. */
89 pex64_get_runtime_function (bfd
*abfd
, struct pex64_runtime_function
*rf
,
92 const struct external_pex64_runtime_function
*ex_rf
=
93 (const struct external_pex64_runtime_function
*) data
;
94 rf
->rva_BeginAddress
= bfd_get_32 (abfd
, ex_rf
->rva_BeginAddress
);
95 rf
->rva_EndAddress
= bfd_get_32 (abfd
, ex_rf
->rva_EndAddress
);
96 rf
->rva_UnwindData
= bfd_get_32 (abfd
, ex_rf
->rva_UnwindData
);
99 /* Swap in unwind info header. */
102 pex64_get_unwind_info (bfd
*abfd
, struct pex64_unwind_info
*ui
,
103 void *data
, void *data_end
)
105 struct external_pex64_unwind_info
*ex_ui
=
106 (struct external_pex64_unwind_info
*) data
;
107 bfd_byte
*ex_dta
= (bfd_byte
*) data
;
108 bfd_byte
*ex_dta_end
= (bfd_byte
*) data_end
;
110 memset (ui
, 0, sizeof (struct pex64_unwind_info
));
112 if (ex_dta_end
- ex_dta
< 4)
115 ui
->Version
= PEX64_UWI_VERSION (ex_ui
->Version_Flags
);
116 ui
->Flags
= PEX64_UWI_FLAGS (ex_ui
->Version_Flags
);
117 ui
->SizeOfPrologue
= (bfd_vma
) ex_ui
->SizeOfPrologue
;
118 ui
->CountOfCodes
= (bfd_vma
) ex_ui
->CountOfCodes
;
119 ui
->FrameRegister
= PEX64_UWI_FRAMEREG (ex_ui
->FrameRegisterOffset
);
120 ui
->FrameOffset
= PEX64_UWI_FRAMEOFF (ex_ui
->FrameRegisterOffset
);
121 ui
->sizeofUnwindCodes
= PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui
->CountOfCodes
);
122 ui
->SizeOfBlock
= ui
->sizeofUnwindCodes
+ 4;
123 ui
->rawUnwindCodes
= ex_dta
+ 4;
124 ui
->rawUnwindCodesEnd
= ex_dta_end
;
126 if ((size_t) (ex_dta_end
- ex_dta
) < ui
->SizeOfBlock
)
128 ex_dta
+= ui
->SizeOfBlock
;
132 case UNW_FLAG_CHAININFO
:
133 if (ex_dta_end
- ex_dta
< 12)
135 ui
->rva_BeginAddress
= bfd_get_32 (abfd
, ex_dta
+ 0);
136 ui
->rva_EndAddress
= bfd_get_32 (abfd
, ex_dta
+ 4);
137 ui
->rva_UnwindData
= bfd_get_32 (abfd
, ex_dta
+ 8);
138 ui
->SizeOfBlock
+= 12;
140 case UNW_FLAG_EHANDLER
:
141 case UNW_FLAG_UHANDLER
:
142 case UNW_FLAG_FHANDLER
:
143 if (ex_dta_end
- ex_dta
< 4)
145 ui
->rva_ExceptionHandler
= bfd_get_32 (abfd
, ex_dta
);
146 ui
->SizeOfBlock
+= 4;
153 /* Display unwind codes. */
156 pex64_xdata_print_uwd_codes (FILE *file
, bfd
*abfd
,
157 struct pex64_unwind_info
*ui
,
158 struct pex64_runtime_function
*rf
)
161 unsigned int tmp
; /* At least 32 bits. */
164 if (ui
->CountOfCodes
== 0 || ui
->rawUnwindCodes
== NULL
)
167 /* According to UNWIND_CODE documentation:
168 If an FP reg is used, the any unwind code taking an offset must only be
169 used after the FP reg is established in the prolog.
170 But there are counter examples of that in system dlls... */
175 if ((size_t) (ui
->rawUnwindCodesEnd
- ui
->rawUnwindCodes
)
176 < ui
->CountOfCodes
* 2)
178 fprintf (file
, _("warning: corrupt unwind data\n"));
183 && PEX64_UNWCODE_CODE (ui
->rawUnwindCodes
[1]) == UWOP_EPILOG
)
185 /* Display epilog opcode (whose docoding is not fully documented).
186 Looks to be designed to speed-up unwinding, as there is no need
187 to decode instruction flow if outside an epilog. */
188 unsigned int func_size
= rf
->rva_EndAddress
- rf
->rva_BeginAddress
;
190 fprintf (file
, "\tv2 epilog (length: %02x) at pc+:",
191 ui
->rawUnwindCodes
[0]);
193 if (PEX64_UNWCODE_INFO (ui
->rawUnwindCodes
[1]))
194 fprintf (file
, " 0x%x", func_size
- ui
->rawUnwindCodes
[0]);
197 for (; i
< ui
->CountOfCodes
; i
++)
199 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
202 if (PEX64_UNWCODE_CODE (dta
[1]) != UWOP_EPILOG
)
204 off
= dta
[0] | (PEX64_UNWCODE_INFO (dta
[1]) << 8);
206 fprintf (file
, " [pad]");
208 fprintf (file
, " 0x%x", func_size
- off
);
213 for (; i
< ui
->CountOfCodes
; i
++)
215 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
216 unsigned int info
= PEX64_UNWCODE_INFO (dta
[1]);
217 int unexpected
= false;
219 fprintf (file
, "\t pc+0x%02x: ", (unsigned int) dta
[0]);
221 switch (PEX64_UNWCODE_CODE (dta
[1]))
223 case UWOP_PUSH_NONVOL
:
224 fprintf (file
, "push %s", pex_regs
[info
]);
227 case UWOP_ALLOC_LARGE
:
230 if (ui
->rawUnwindCodesEnd
- dta
< 4)
232 fprintf (file
, _("warning: corrupt unwind data\n"));
235 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
240 if (ui
->rawUnwindCodesEnd
- dta
< 6)
242 fprintf (file
, _("warning: corrupt unwind data\n"));
245 tmp
= bfd_get_32 (abfd
, dta
+ 2);
248 fprintf (file
, "alloc large area: rsp = rsp - 0x%x", tmp
);
251 case UWOP_ALLOC_SMALL
:
252 fprintf (file
, "alloc small area: rsp = rsp - 0x%x", (info
+ 1) * 8);
256 /* According to the documentation, info field is unused. */
257 fprintf (file
, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
258 pex_regs
[ui
->FrameRegister
],
259 (unsigned int) ui
->FrameOffset
* 16, info
);
260 unexpected
= ui
->FrameRegister
== 0;
261 save_allowed
= false;
264 case UWOP_SAVE_NONVOL
:
265 if (ui
->rawUnwindCodesEnd
- dta
< 4)
267 fprintf (file
, _("warning: corrupt unwind data\n"));
270 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
272 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
273 unexpected
= !save_allowed
;
276 case UWOP_SAVE_NONVOL_FAR
:
277 if (ui
->rawUnwindCodesEnd
- dta
< 6)
279 fprintf (file
, _("warning: corrupt unwind data\n"));
282 tmp
= bfd_get_32 (abfd
, dta
+ 2);
284 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
285 unexpected
= !save_allowed
;
289 if (ui
->Version
== 1)
291 if (ui
->rawUnwindCodesEnd
- dta
< 4)
293 fprintf (file
, _("warning: corrupt unwind data\n"));
296 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
298 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
299 unexpected
= !save_allowed
;
301 else if (ui
->Version
== 2)
303 fprintf (file
, "epilog %02x %01x", dta
[0], info
);
308 case UWOP_SAVE_XMM_FAR
:
309 if (ui
->rawUnwindCodesEnd
- dta
< 6)
311 fprintf (file
, _("warning: corrupt unwind data\n"));
314 tmp
= bfd_get_32 (abfd
, dta
+ 2) * 8;
316 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
317 unexpected
= !save_allowed
;
320 case UWOP_SAVE_XMM128
:
321 if (ui
->rawUnwindCodesEnd
- dta
< 4)
323 fprintf (file
, _("warning: corrupt unwind data\n"));
326 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 16;
328 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
329 unexpected
= !save_allowed
;
332 case UWOP_SAVE_XMM128_FAR
:
333 if (ui
->rawUnwindCodesEnd
- dta
< 6)
335 fprintf (file
, _("warning: corrupt unwind data\n"));
338 tmp
= bfd_get_32 (abfd
, dta
+ 2) * 16;
340 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
341 unexpected
= !save_allowed
;
344 case UWOP_PUSH_MACHFRAME
:
345 fprintf (file
, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
349 fprintf (file
, ",ErrorCode)");
351 fprintf (file
, ", unknown(%u))", info
);
355 /* PR 17512: file: 2245-7442-0.004. */
356 fprintf (file
, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta
[1]));
361 fprintf (file
, " [Unexpected!]");
366 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
369 pex64_get_section_by_rva (bfd
*abfd
, bfd_vma addr
, const char *sec_name
)
371 asection
*section
= bfd_get_section_by_name (abfd
, sec_name
);
373 bfd_size_type datasize
= 0;
376 || coff_section_data (abfd
, section
) == NULL
377 || pei_section_data (abfd
, section
) == NULL
)
379 vsize
= section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
380 datasize
= section
->size
;
381 if (!datasize
|| vsize
> addr
|| (vsize
+ datasize
) < addr
)
386 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
387 designate the bfd section containing the xdata, XDATA is its content,
388 and ENDX the size if known (or NULL). */
391 pex64_dump_xdata (FILE *file
, bfd
*abfd
,
392 asection
*xdata_section
, bfd_byte
*xdata
, bfd_vma
*endx
,
393 struct pex64_runtime_function
*rf
)
397 bfd_vma addr
= rf
->rva_UnwindData
;
398 bfd_size_type sec_size
= xdata_section
->rawsize
> 0 ? xdata_section
->rawsize
: xdata_section
->size
;
399 struct pex64_unwind_info ui
;
401 vaddr
= xdata_section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
404 /* PR 17512: file: 2245-7442-0.004. */
405 if (addr
>= sec_size
)
407 fprintf (file
, _("warning: xdata section corrupt\n"));
413 end_addr
= endx
[0] - vaddr
;
414 /* PR 17512: file: 2245-7442-0.004. */
415 if (end_addr
> sec_size
)
417 fprintf (file
, _("warning: xdata section corrupt\n"));
424 if (! pex64_get_unwind_info (abfd
, &ui
, xdata
+ addr
, xdata
+ end_addr
))
426 fprintf (file
, _("warning: xdata section corrupt\n"));
430 if (ui
.Version
!= 1 && ui
.Version
!= 2)
433 fprintf (file
, "\tVersion %u (unknown).\n",
434 (unsigned int) ui
.Version
);
435 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
438 fprintf (file
, "\t %03x:", i
);
439 fprintf (file
, " %02x", xdata
[addr
]);
441 fprintf (file
, "\n");
444 fprintf (file
, "\n");
448 fprintf (file
, "\tVersion: %d, Flags: ", ui
.Version
);
451 case UNW_FLAG_NHANDLER
:
452 fprintf (file
, "none");
454 case UNW_FLAG_EHANDLER
:
455 fprintf (file
, "UNW_FLAG_EHANDLER");
457 case UNW_FLAG_UHANDLER
:
458 fprintf (file
, "UNW_FLAG_UHANDLER");
460 case UNW_FLAG_FHANDLER
:
462 (file
, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
464 case UNW_FLAG_CHAININFO
:
465 fprintf (file
, "UNW_FLAG_CHAININFO");
468 fprintf (file
, "unknown flags value 0x%x", (unsigned int) ui
.Flags
);
472 fprintf (file
, "\tNbr codes: %u, ", (unsigned int) ui
.CountOfCodes
);
473 fprintf (file
, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
474 (unsigned int) ui
.SizeOfPrologue
, (unsigned int) ui
.FrameOffset
);
475 fprintf (file
, "Frame reg: %s\n",
476 ui
.FrameRegister
== 0 ? "none"
477 : pex_regs
[(unsigned int) ui
.FrameRegister
]);
479 /* PR 17512: file: 2245-7442-0.004. */
480 if (ui
.CountOfCodes
* 2 + ui
.rawUnwindCodes
> xdata
+ xdata_section
->size
)
481 fprintf (file
, _("Too many unwind codes (%ld)\n"), (long) ui
.CountOfCodes
);
483 pex64_xdata_print_uwd_codes (file
, abfd
, &ui
, rf
);
487 case UNW_FLAG_EHANDLER
:
488 case UNW_FLAG_UHANDLER
:
489 case UNW_FLAG_FHANDLER
:
490 fprintf (file
, "\tHandler: %016" PRIx64
".\n",
491 ui
.rva_ExceptionHandler
+ pe_data (abfd
)->pe_opthdr
.ImageBase
);
493 case UNW_FLAG_CHAININFO
:
494 fprintf (file
, "\tChain: start: %016" PRIx64
", end: %016" PRIx64
,
495 ui
.rva_BeginAddress
, ui
.rva_EndAddress
);
496 fprintf (file
, "\n\t unwind data: %016" PRIx64
".\n",
501 /* Now we need end of this xdata block. */
502 addr
+= ui
.SizeOfBlock
;
506 fprintf (file
,"\tUser data:\n");
507 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
510 fprintf (file
, "\t %03x:", i
);
511 fprintf (file
, " %02x", xdata
[addr
]);
513 fprintf (file
, "\n");
516 fprintf (file
, "\n");
520 /* Helper function to sort xdata. The entries of xdata are sorted to know
521 the size of each entry. */
524 sort_xdata_arr (const void *l
, const void *r
)
526 const bfd_vma
*lp
= (const bfd_vma
*) l
;
527 const bfd_vma
*rp
= (const bfd_vma
*) r
;
531 return (*lp
< *rp
? -1 : 1);
534 /* Display unwind tables for x86-64. */
537 pex64_bfd_print_pdata_section (bfd
*abfd
, void *vfile
, asection
*pdata_section
)
539 FILE *file
= (FILE *) vfile
;
540 bfd_byte
*pdata
= NULL
;
541 bfd_byte
*xdata
= NULL
;
542 asection
*xdata_section
= NULL
;
545 bfd_size_type datasize
;
547 bfd_vma prev_beginaddress
= (bfd_vma
) -1;
548 bfd_vma prev_unwinddata_rva
= (bfd_vma
) -1;
550 int onaline
= PDATA_ROW_SIZE
;
552 bfd_vma
*xdata_arr
= NULL
;
554 bool virt_size_is_zero
= false;
557 if (pdata_section
== NULL
558 || (pdata_section
->flags
& SEC_HAS_CONTENTS
) == 0
559 || coff_section_data (abfd
, pdata_section
) == NULL
560 || pei_section_data (abfd
, pdata_section
) == NULL
)
563 stop
= pei_section_data (abfd
, pdata_section
)->virt_size
;
564 if ((stop
% onaline
) != 0)
566 /* xgettext:c-format */
567 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
568 pdata_section
->name
, (long) stop
, onaline
);
570 datasize
= pdata_section
->size
;
574 fprintf (file
, _("Warning: %s section size is zero\n"),
575 pdata_section
->name
);
579 /* virt_size might be zero for objects. */
580 if (stop
== 0 && strcmp (abfd
->xvec
->name
, "pe-x86-64") == 0)
583 virt_size_is_zero
= true;
585 else if (datasize
< stop
)
588 /* xgettext:c-format */
589 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
590 pdata_section
->name
, (unsigned long) datasize
,
591 (unsigned long) stop
);
592 /* Be sure not to read past datasize. */
596 /* Display functions table. */
598 _("\nThe Function Table (interpreted %s section contents)\n"),
599 pdata_section
->name
);
601 fprintf (file
, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
603 if (!bfd_malloc_and_get_section (abfd
, pdata_section
, &pdata
))
606 /* Table of xdata entries. */
607 xdata_arr
= (bfd_vma
*) xmalloc (sizeof (bfd_vma
) * ((stop
/ onaline
) + 1));
610 if (strcmp (abfd
->xvec
->name
, "pei-x86-64") == 0)
611 imagebase
= pe_data (abfd
)->pe_opthdr
.ImageBase
;
615 for (i
= 0; i
< stop
; i
+= onaline
)
617 struct pex64_runtime_function rf
;
619 if (i
+ PDATA_ROW_SIZE
> stop
)
622 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
624 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
625 && rf
.rva_UnwindData
== 0)
626 /* We are probably into the padding of the section now. */
628 fprintf (file
, " %016" PRIx64
, i
+ pdata_section
->vma
);
629 fprintf (file
, ":\t%016" PRIx64
, imagebase
+ rf
.rva_BeginAddress
);
630 fprintf (file
, " %016" PRIx64
, imagebase
+ rf
.rva_EndAddress
);
631 fprintf (file
, " %016" PRIx64
"\n", imagebase
+ rf
.rva_UnwindData
);
632 if (i
!= 0 && rf
.rva_BeginAddress
<= prev_beginaddress
)
635 fprintf (file
, " has %s begin address as predecessor\n",
636 (rf
.rva_BeginAddress
< prev_beginaddress
? "smaller" : "same"));
638 prev_beginaddress
= rf
.rva_BeginAddress
;
639 /* Now we check for negative addresses. */
640 if ((prev_beginaddress
& 0x80000000) != 0)
643 fprintf (file
, " has negative begin address\n");
645 if ((rf
.rva_EndAddress
& 0x80000000) != 0)
648 fprintf (file
, " has negative end address\n");
650 if ((rf
.rva_UnwindData
& 0x80000000) != 0)
653 fprintf (file
, " has negative unwind address\n");
655 else if ((rf
.rva_UnwindData
&& !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
656 || virt_size_is_zero
)
657 xdata_arr
[xdata_arr_cnt
++] = rf
.rva_UnwindData
;
663 /* Add end of list marker. */
664 xdata_arr
[xdata_arr_cnt
++] = ~((bfd_vma
) 0);
666 /* Sort start RVAs of xdata. */
667 if (xdata_arr_cnt
> 1)
668 qsort (xdata_arr
, (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
671 /* Find the section containing the unwind data (.xdata). */
672 xdata_base
= xdata_arr
[0];
673 /* For sections with long names, first look for the same
674 section name, replacing .pdata by .xdata prefix. */
675 if (strcmp (pdata_section
->name
, ".pdata") != 0)
677 size_t len
= strlen (pdata_section
->name
);
678 char *xdata_name
= xmalloc (len
+ 1);
680 xdata_name
= memcpy (xdata_name
, pdata_section
->name
, len
+ 1);
681 /* Transform .pdata prefix into .xdata prefix. */
683 xdata_name
[1] = 'x';
684 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
,
688 /* Second, try the .xdata section itself. */
690 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".xdata");
691 /* Otherwise, if xdata_base is non zero, search also inside
692 other standard sections. */
693 if (!xdata_section
&& xdata_base
)
694 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".rdata");
695 if (!xdata_section
&& xdata_base
)
696 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".data");
697 if (!xdata_section
&& xdata_base
)
698 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".pdata");
699 if (!xdata_section
&& xdata_base
)
700 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".text");
701 /* Transfer xdata section into xdata array. */
703 || (xdata_section
->flags
& SEC_HAS_CONTENTS
) == 0
704 || !bfd_malloc_and_get_section (abfd
, xdata_section
, &xdata
))
707 /* Avoid "also used "... ouput for single unwind info
709 prev_unwinddata_rva
= (bfd_vma
) -1;
711 /* Do dump of pdata related xdata. */
712 for (i
= 0; i
< stop
; i
+= onaline
)
714 struct pex64_runtime_function rf
;
716 if (i
+ PDATA_ROW_SIZE
> stop
)
719 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
721 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
722 && rf
.rva_UnwindData
== 0)
723 /* We are probably into the padding of the section now. */
726 fprintf (file
, _("\nDump of %s\n"), xdata_section
->name
);
728 fprintf (file
, " %016" PRIx64
, rf
.rva_UnwindData
+ imagebase
);
730 if (prev_unwinddata_rva
== rf
.rva_UnwindData
)
732 /* Do not dump again the xdata for the same entry. */
733 fprintf (file
, " also used for function at %016" PRIx64
"\n",
734 rf
.rva_BeginAddress
+ imagebase
);
738 prev_unwinddata_rva
= rf
.rva_UnwindData
;
740 fprintf (file
, " (rva: %08x): %016" PRIx64
" - %016" PRIx64
"\n",
741 (unsigned int) rf
.rva_UnwindData
,
742 rf
.rva_BeginAddress
+ imagebase
,
743 rf
.rva_EndAddress
+ imagebase
);
745 if (rf
.rva_UnwindData
!= 0 || virt_size_is_zero
)
747 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
749 bfd_vma altent
= PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf
);
750 bfd_vma pdata_vma
= bfd_section_vma (pdata_section
);
751 struct pex64_runtime_function arf
;
753 fprintf (file
, "\t shares information with ");
756 if (altent
>= pdata_vma
757 && altent
- pdata_vma
+ PDATA_ROW_SIZE
<= stop
)
759 pex64_get_runtime_function
760 (abfd
, &arf
, &pdata
[altent
- pdata_vma
]);
761 fprintf (file
, "pdata element at 0x%016" PRIx64
,
765 fprintf (file
, "unknown pdata element");
766 fprintf (file
, ".\n");
772 /* Search for the current entry in the sorted array. */
774 bsearch (&rf
.rva_UnwindData
, xdata_arr
,
775 (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
778 /* Advance to the next pointer into the xdata section. We may
779 have shared xdata entries, which will result in a string of
780 identical pointers in the array; advance past all of them. */
781 while (p
[0] <= rf
.rva_UnwindData
)
784 if (p
[0] == ~((bfd_vma
) 0))
787 pex64_dump_xdata (file
, abfd
, xdata_section
, xdata
, p
, &rf
);
803 /* Number of found pdata sections. */
804 unsigned int pdata_count
;
807 /* Functionn prototype. */
808 bool pex64_bfd_print_pdata (bfd
*, void *);
810 /* Helper function for bfd_map_over_section. */
812 pex64_print_all_pdata_sections (bfd
*abfd
, asection
*pdata
, void *arg
)
814 struct pex64_paps
*paps
= arg
;
815 if (startswith (pdata
->name
, ".pdata"))
817 if (pex64_bfd_print_pdata_section (abfd
, paps
->obj
, pdata
))
823 pex64_bfd_print_pdata (bfd
*abfd
, void *vfile
)
825 asection
*pdata_section
= bfd_get_section_by_name (abfd
, ".pdata");
826 struct pex64_paps paps
;
829 return pex64_bfd_print_pdata_section (abfd
, vfile
, pdata_section
);
832 paps
.pdata_count
= 0;
833 bfd_map_over_sections (abfd
, pex64_print_all_pdata_sections
, &paps
);
834 return paps
.pdata_count
!= 0;
837 #define bfd_pe_print_pdata pex64_bfd_print_pdata
838 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
840 #include "coff-x86_64.c"