1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright (C) 2006-2022 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
>= ex_dta_end
|| ex_dta
+ 4 >= ex_dta_end
)
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 ex_dta
+= ui
->SizeOfBlock
;
127 if (ex_dta
>= ex_dta_end
)
132 case UNW_FLAG_CHAININFO
:
133 if (ex_dta
+ 12 >= ex_dta_end
)
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
+ 4 >= ex_dta_end
)
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 (ui
->rawUnwindCodes
+ 1 >= ui
->rawUnwindCodesEnd
)
177 fprintf (file
, _("warning: corrupt unwind data\n"));
182 && PEX64_UNWCODE_CODE (ui
->rawUnwindCodes
[1]) == UWOP_EPILOG
)
184 /* Display epilog opcode (whose docoding is not fully documented).
185 Looks to be designed to speed-up unwinding, as there is no need
186 to decode instruction flow if outside an epilog. */
187 unsigned int func_size
= rf
->rva_EndAddress
- rf
->rva_BeginAddress
;
189 if (ui
->rawUnwindCodes
+ 1 + (ui
->CountOfCodes
* 2) >= ui
->rawUnwindCodesEnd
)
191 fprintf (file
, _("warning: corrupt unwind data\n"));
195 fprintf (file
, "\tv2 epilog (length: %02x) at pc+:",
196 ui
->rawUnwindCodes
[0]);
198 if (PEX64_UNWCODE_INFO (ui
->rawUnwindCodes
[1]))
199 fprintf (file
, " 0x%x", func_size
- ui
->rawUnwindCodes
[0]);
202 for (; i
< ui
->CountOfCodes
; i
++)
204 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
207 if (PEX64_UNWCODE_CODE (dta
[1]) != UWOP_EPILOG
)
209 off
= dta
[0] | (PEX64_UNWCODE_INFO (dta
[1]) << 8);
211 fprintf (file
, " [pad]");
213 fprintf (file
, " 0x%x", func_size
- off
);
218 if (ui
->rawUnwindCodes
+ 2 + (ui
->CountOfCodes
* 2) >= ui
->rawUnwindCodesEnd
)
220 fprintf (file
, _("warning: corrupt unwind data\n"));
224 for (; i
< ui
->CountOfCodes
; i
++)
226 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
227 unsigned int info
= PEX64_UNWCODE_INFO (dta
[1]);
228 int unexpected
= false;
230 fprintf (file
, "\t pc+0x%02x: ", (unsigned int) dta
[0]);
232 switch (PEX64_UNWCODE_CODE (dta
[1]))
234 case UWOP_PUSH_NONVOL
:
235 fprintf (file
, "push %s", pex_regs
[info
]);
238 case UWOP_ALLOC_LARGE
:
241 if (dta
+ 4 > ui
->rawUnwindCodesEnd
)
243 fprintf (file
, _("warning: corrupt unwind data\n"));
246 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
251 if (dta
+ 6 > ui
->rawUnwindCodesEnd
)
253 fprintf (file
, _("warning: corrupt unwind data\n"));
256 tmp
= bfd_get_32 (abfd
, dta
+ 2);
259 fprintf (file
, "alloc large area: rsp = rsp - 0x%x", tmp
);
262 case UWOP_ALLOC_SMALL
:
263 fprintf (file
, "alloc small area: rsp = rsp - 0x%x", (info
+ 1) * 8);
267 /* According to the documentation, info field is unused. */
268 fprintf (file
, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
269 pex_regs
[ui
->FrameRegister
],
270 (unsigned int) ui
->FrameOffset
* 16, info
);
271 unexpected
= ui
->FrameRegister
== 0;
272 save_allowed
= false;
275 case UWOP_SAVE_NONVOL
:
276 if (dta
+ 4 > ui
->rawUnwindCodesEnd
)
278 fprintf (file
, _("warning: corrupt unwind data\n"));
281 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
283 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
284 unexpected
= !save_allowed
;
287 case UWOP_SAVE_NONVOL_FAR
:
288 if (dta
+ 6 > ui
->rawUnwindCodesEnd
)
290 fprintf (file
, _("warning: corrupt unwind data\n"));
293 tmp
= bfd_get_32 (abfd
, dta
+ 2);
295 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
296 unexpected
= !save_allowed
;
300 if (ui
->Version
== 1)
302 if (dta
+ 4 > ui
->rawUnwindCodesEnd
)
304 fprintf (file
, _("warning: corrupt unwind data\n"));
307 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 8;
309 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
310 unexpected
= !save_allowed
;
312 else if (ui
->Version
== 2)
314 fprintf (file
, "epilog %02x %01x", dta
[0], info
);
319 case UWOP_SAVE_XMM_FAR
:
320 if (dta
+ 6 > ui
->rawUnwindCodesEnd
)
322 fprintf (file
, _("warning: corrupt unwind data\n"));
325 tmp
= bfd_get_32 (abfd
, dta
+ 2) * 8;
327 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
328 unexpected
= !save_allowed
;
331 case UWOP_SAVE_XMM128
:
332 if (dta
+ 4 > ui
->rawUnwindCodesEnd
)
334 fprintf (file
, _("warning: corrupt unwind data\n"));
337 tmp
= bfd_get_16 (abfd
, dta
+ 2) * 16;
339 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
340 unexpected
= !save_allowed
;
343 case UWOP_SAVE_XMM128_FAR
:
344 if (dta
+ 6 > ui
->rawUnwindCodesEnd
)
346 fprintf (file
, _("warning: corrupt unwind data\n"));
349 tmp
= bfd_get_32 (abfd
, dta
+ 2) * 16;
351 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
352 unexpected
= !save_allowed
;
355 case UWOP_PUSH_MACHFRAME
:
356 fprintf (file
, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
360 fprintf (file
, ",ErrorCode)");
362 fprintf (file
, ", unknown(%u))", info
);
366 /* PR 17512: file: 2245-7442-0.004. */
367 fprintf (file
, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta
[1]));
372 fprintf (file
, " [Unexpected!]");
377 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
380 pex64_get_section_by_rva (bfd
*abfd
, bfd_vma addr
, const char *sec_name
)
382 asection
*section
= bfd_get_section_by_name (abfd
, sec_name
);
384 bfd_size_type datasize
= 0;
387 || coff_section_data (abfd
, section
) == NULL
388 || pei_section_data (abfd
, section
) == NULL
)
390 vsize
= section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
391 datasize
= section
->size
;
392 if (!datasize
|| vsize
> addr
|| (vsize
+ datasize
) < addr
)
397 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
398 designate the bfd section containing the xdata, XDATA is its content,
399 and ENDX the size if known (or NULL). */
402 pex64_dump_xdata (FILE *file
, bfd
*abfd
,
403 asection
*xdata_section
, bfd_byte
*xdata
, bfd_vma
*endx
,
404 struct pex64_runtime_function
*rf
)
408 bfd_vma addr
= rf
->rva_UnwindData
;
409 bfd_size_type sec_size
= xdata_section
->rawsize
> 0 ? xdata_section
->rawsize
: xdata_section
->size
;
410 struct pex64_unwind_info ui
;
412 vaddr
= xdata_section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
415 /* PR 17512: file: 2245-7442-0.004. */
416 if (addr
>= sec_size
)
418 fprintf (file
, _("warning: xdata section corrupt\n"));
424 end_addr
= endx
[0] - vaddr
;
425 /* PR 17512: file: 2245-7442-0.004. */
426 if (end_addr
> sec_size
)
428 fprintf (file
, _("warning: xdata section corrupt\n"));
435 if (! pex64_get_unwind_info (abfd
, &ui
, xdata
+ addr
, xdata
+ end_addr
))
437 fprintf (file
, _("warning: xdata section corrupt\n"));
441 if (ui
.Version
!= 1 && ui
.Version
!= 2)
444 fprintf (file
, "\tVersion %u (unknown).\n",
445 (unsigned int) ui
.Version
);
446 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
449 fprintf (file
, "\t %03x:", i
);
450 fprintf (file
, " %02x", xdata
[addr
]);
452 fprintf (file
, "\n");
455 fprintf (file
, "\n");
459 fprintf (file
, "\tVersion: %d, Flags: ", ui
.Version
);
462 case UNW_FLAG_NHANDLER
:
463 fprintf (file
, "none");
465 case UNW_FLAG_EHANDLER
:
466 fprintf (file
, "UNW_FLAG_EHANDLER");
468 case UNW_FLAG_UHANDLER
:
469 fprintf (file
, "UNW_FLAG_UHANDLER");
471 case UNW_FLAG_FHANDLER
:
473 (file
, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
475 case UNW_FLAG_CHAININFO
:
476 fprintf (file
, "UNW_FLAG_CHAININFO");
479 fprintf (file
, "unknown flags value 0x%x", (unsigned int) ui
.Flags
);
483 fprintf (file
, "\tNbr codes: %u, ", (unsigned int) ui
.CountOfCodes
);
484 fprintf (file
, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
485 (unsigned int) ui
.SizeOfPrologue
, (unsigned int) ui
.FrameOffset
);
486 fprintf (file
, "Frame reg: %s\n",
487 ui
.FrameRegister
== 0 ? "none"
488 : pex_regs
[(unsigned int) ui
.FrameRegister
]);
490 /* PR 17512: file: 2245-7442-0.004. */
491 if (ui
.CountOfCodes
* 2 + ui
.rawUnwindCodes
> xdata
+ xdata_section
->size
)
492 fprintf (file
, _("Too many unwind codes (%ld)\n"), (long) ui
.CountOfCodes
);
494 pex64_xdata_print_uwd_codes (file
, abfd
, &ui
, rf
);
498 case UNW_FLAG_EHANDLER
:
499 case UNW_FLAG_UHANDLER
:
500 case UNW_FLAG_FHANDLER
:
501 fprintf (file
, "\tHandler: ");
502 fprintf_vma (file
, (ui
.rva_ExceptionHandler
503 + pe_data (abfd
)->pe_opthdr
.ImageBase
));
504 fprintf (file
, ".\n");
506 case UNW_FLAG_CHAININFO
:
507 fprintf (file
, "\tChain: start: ");
508 fprintf_vma (file
, ui
.rva_BeginAddress
);
509 fprintf (file
, ", end: ");
510 fprintf_vma (file
, ui
.rva_EndAddress
);
511 fprintf (file
, "\n\t unwind data: ");
512 fprintf_vma (file
, ui
.rva_UnwindData
);
513 fprintf (file
, ".\n");
517 /* Now we need end of this xdata block. */
518 addr
+= ui
.SizeOfBlock
;
522 fprintf (file
,"\tUser data:\n");
523 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
526 fprintf (file
, "\t %03x:", i
);
527 fprintf (file
, " %02x", xdata
[addr
]);
529 fprintf (file
, "\n");
532 fprintf (file
, "\n");
536 /* Helper function to sort xdata. The entries of xdata are sorted to know
537 the size of each entry. */
540 sort_xdata_arr (const void *l
, const void *r
)
542 const bfd_vma
*lp
= (const bfd_vma
*) l
;
543 const bfd_vma
*rp
= (const bfd_vma
*) r
;
547 return (*lp
< *rp
? -1 : 1);
550 /* Display unwind tables for x86-64. */
553 pex64_bfd_print_pdata_section (bfd
*abfd
, void *vfile
, asection
*pdata_section
)
555 FILE *file
= (FILE *) vfile
;
556 bfd_byte
*pdata
= NULL
;
557 bfd_byte
*xdata
= NULL
;
558 asection
*xdata_section
= NULL
;
561 bfd_size_type datasize
;
563 bfd_vma prev_beginaddress
= (bfd_vma
) -1;
564 bfd_vma prev_unwinddata_rva
= (bfd_vma
) -1;
566 int onaline
= PDATA_ROW_SIZE
;
568 bfd_vma
*xdata_arr
= NULL
;
570 bool virt_size_is_zero
= false;
573 if (pdata_section
== NULL
574 || coff_section_data (abfd
, pdata_section
) == NULL
575 || pei_section_data (abfd
, pdata_section
) == NULL
)
578 stop
= pei_section_data (abfd
, pdata_section
)->virt_size
;
579 if ((stop
% onaline
) != 0)
581 /* xgettext:c-format */
582 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
583 pdata_section
->name
, (long) stop
, onaline
);
585 datasize
= pdata_section
->size
;
589 fprintf (file
, _("Warning: %s section size is zero\n"),
590 pdata_section
->name
);
594 /* virt_size might be zero for objects. */
595 if (stop
== 0 && strcmp (abfd
->xvec
->name
, "pe-x86-64") == 0)
598 virt_size_is_zero
= true;
600 else if (datasize
< stop
)
603 /* xgettext:c-format */
604 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
605 pdata_section
->name
, (unsigned long) datasize
,
606 (unsigned long) stop
);
607 /* Be sure not to read past datasize. */
611 /* Display functions table. */
613 _("\nThe Function Table (interpreted %s section contents)\n"),
614 pdata_section
->name
);
616 fprintf (file
, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
618 if (!bfd_malloc_and_get_section (abfd
, pdata_section
, &pdata
))
621 /* Table of xdata entries. */
622 xdata_arr
= (bfd_vma
*) xmalloc (sizeof (bfd_vma
) * ((stop
/ onaline
) + 1));
625 if (strcmp (abfd
->xvec
->name
, "pei-x86-64") == 0)
626 imagebase
= pe_data (abfd
)->pe_opthdr
.ImageBase
;
630 for (i
= 0; i
< stop
; i
+= onaline
)
632 struct pex64_runtime_function rf
;
634 if (i
+ PDATA_ROW_SIZE
> stop
)
637 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
639 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
640 && rf
.rva_UnwindData
== 0)
641 /* We are probably into the padding of the section now. */
644 fprintf_vma (file
, i
+ pdata_section
->vma
);
645 fprintf (file
, ":\t");
646 fprintf_vma (file
, imagebase
+ rf
.rva_BeginAddress
);
648 fprintf_vma (file
, imagebase
+ rf
.rva_EndAddress
);
650 fprintf_vma (file
, imagebase
+ rf
.rva_UnwindData
);
651 fprintf (file
, "\n");
652 if (i
!= 0 && rf
.rva_BeginAddress
<= prev_beginaddress
)
655 fprintf (file
, " has %s begin address as predecessor\n",
656 (rf
.rva_BeginAddress
< prev_beginaddress
? "smaller" : "same"));
658 prev_beginaddress
= rf
.rva_BeginAddress
;
659 /* Now we check for negative addresses. */
660 if ((prev_beginaddress
& 0x80000000) != 0)
663 fprintf (file
, " has negative begin address\n");
665 if ((rf
.rva_EndAddress
& 0x80000000) != 0)
668 fprintf (file
, " has negative end address\n");
670 if ((rf
.rva_UnwindData
& 0x80000000) != 0)
673 fprintf (file
, " has negative unwind address\n");
675 else if ((rf
.rva_UnwindData
&& !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
676 || virt_size_is_zero
)
677 xdata_arr
[xdata_arr_cnt
++] = rf
.rva_UnwindData
;
683 /* Add end of list marker. */
684 xdata_arr
[xdata_arr_cnt
++] = ~((bfd_vma
) 0);
686 /* Sort start RVAs of xdata. */
687 if (xdata_arr_cnt
> 1)
688 qsort (xdata_arr
, (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
691 /* Find the section containing the unwind data (.xdata). */
692 xdata_base
= xdata_arr
[0];
693 /* For sections with long names, first look for the same
694 section name, replacing .pdata by .xdata prefix. */
695 if (strcmp (pdata_section
->name
, ".pdata") != 0)
697 size_t len
= strlen (pdata_section
->name
);
698 char *xdata_name
= xmalloc (len
+ 1);
700 xdata_name
= memcpy (xdata_name
, pdata_section
->name
, len
+ 1);
701 /* Transform .pdata prefix into .xdata prefix. */
703 xdata_name
[1] = 'x';
704 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
,
708 /* Second, try the .xdata section itself. */
710 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".xdata");
711 /* Otherwise, if xdata_base is non zero, search also inside
712 other standard sections. */
713 if (!xdata_section
&& xdata_base
)
714 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".rdata");
715 if (!xdata_section
&& xdata_base
)
716 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".data");
717 if (!xdata_section
&& xdata_base
)
718 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".pdata");
719 if (!xdata_section
&& xdata_base
)
720 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".text");
721 /* Transfer xdata section into xdata array. */
723 || !bfd_malloc_and_get_section (abfd
, xdata_section
, &xdata
))
726 /* Avoid "also used "... ouput for single unwind info
728 prev_unwinddata_rva
= (bfd_vma
) -1;
730 /* Do dump of pdata related xdata. */
731 for (i
= 0; i
< stop
; i
+= onaline
)
733 struct pex64_runtime_function rf
;
735 if (i
+ PDATA_ROW_SIZE
> stop
)
738 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
740 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
741 && rf
.rva_UnwindData
== 0)
742 /* We are probably into the padding of the section now. */
745 fprintf (file
, _("\nDump of %s\n"), xdata_section
->name
);
748 fprintf_vma (file
, rf
.rva_UnwindData
+ imagebase
);
750 if (prev_unwinddata_rva
== rf
.rva_UnwindData
)
752 /* Do not dump again the xdata for the same entry. */
753 fprintf (file
, " also used for function at ");
754 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
759 prev_unwinddata_rva
= rf
.rva_UnwindData
;
761 fprintf (file
, " (rva: %08x): ",
762 (unsigned int) rf
.rva_UnwindData
);
763 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
764 fprintf (file
, " - ");
765 fprintf_vma (file
, rf
.rva_EndAddress
+ imagebase
);
768 if (rf
.rva_UnwindData
!= 0 || virt_size_is_zero
)
770 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
772 bfd_vma altent
= PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf
);
773 bfd_vma pdata_vma
= bfd_section_vma (pdata_section
);
774 struct pex64_runtime_function arf
;
776 fprintf (file
, "\t shares information with ");
779 if (altent
>= pdata_vma
780 && altent
- pdata_vma
+ PDATA_ROW_SIZE
<= stop
)
782 pex64_get_runtime_function
783 (abfd
, &arf
, &pdata
[altent
- pdata_vma
]);
784 fprintf (file
, "pdata element at 0x");
785 fprintf_vma (file
, arf
.rva_UnwindData
);
788 fprintf (file
, "unknown pdata element");
789 fprintf (file
, ".\n");
795 /* Search for the current entry in the sorted array. */
797 bsearch (&rf
.rva_UnwindData
, xdata_arr
,
798 (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
801 /* Advance to the next pointer into the xdata section. We may
802 have shared xdata entries, which will result in a string of
803 identical pointers in the array; advance past all of them. */
804 while (p
[0] <= rf
.rva_UnwindData
)
807 if (p
[0] == ~((bfd_vma
) 0))
810 pex64_dump_xdata (file
, abfd
, xdata_section
, xdata
, p
, &rf
);
826 /* Number of found pdata sections. */
827 unsigned int pdata_count
;
830 /* Functionn prototype. */
831 bool pex64_bfd_print_pdata (bfd
*, void *);
833 /* Helper function for bfd_map_over_section. */
835 pex64_print_all_pdata_sections (bfd
*abfd
, asection
*pdata
, void *arg
)
837 struct pex64_paps
*paps
= arg
;
838 if (startswith (pdata
->name
, ".pdata"))
840 if (pex64_bfd_print_pdata_section (abfd
, paps
->obj
, pdata
))
846 pex64_bfd_print_pdata (bfd
*abfd
, void *vfile
)
848 asection
*pdata_section
= bfd_get_section_by_name (abfd
, ".pdata");
849 struct pex64_paps paps
;
852 return pex64_bfd_print_pdata_section (abfd
, vfile
, pdata_section
);
855 paps
.pdata_count
= 0;
856 bfd_map_over_sections (abfd
, pex64_print_all_pdata_sections
, &paps
);
857 return paps
.pdata_count
!= 0;
860 #define bfd_pe_print_pdata pex64_bfd_print_pdata
861 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
863 #include "coff-x86_64.c"