1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright (C) 2006-2014 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
, void *data
)
104 struct external_pex64_unwind_info
*ex_ui
=
105 (struct external_pex64_unwind_info
*) data
;
106 bfd_byte
*ex_dta
= (bfd_byte
*) data
;
108 memset (ui
, 0, sizeof (struct pex64_unwind_info
));
109 ui
->Version
= PEX64_UWI_VERSION (ex_ui
->Version_Flags
);
110 ui
->Flags
= PEX64_UWI_FLAGS (ex_ui
->Version_Flags
);
111 ui
->SizeOfPrologue
= (bfd_vma
) ex_ui
->SizeOfPrologue
;
112 ui
->CountOfCodes
= (bfd_vma
) ex_ui
->CountOfCodes
;
113 ui
->FrameRegister
= PEX64_UWI_FRAMEREG (ex_ui
->FrameRegisterOffset
);
114 ui
->FrameOffset
= PEX64_UWI_FRAMEOFF (ex_ui
->FrameRegisterOffset
);
115 ui
->sizeofUnwindCodes
= PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui
->CountOfCodes
);
116 ui
->SizeOfBlock
= ui
->sizeofUnwindCodes
+ 4;
117 ui
->rawUnwindCodes
= &ex_dta
[4];
119 ex_dta
+= ui
->SizeOfBlock
;
122 case UNW_FLAG_CHAININFO
:
123 ui
->rva_BeginAddress
= bfd_get_32 (abfd
, ex_dta
+ 0);
124 ui
->rva_EndAddress
= bfd_get_32 (abfd
, ex_dta
+ 4);
125 ui
->rva_UnwindData
= bfd_get_32 (abfd
, ex_dta
+ 8);
126 ui
->SizeOfBlock
+= 12;
128 case UNW_FLAG_EHANDLER
:
129 case UNW_FLAG_UHANDLER
:
130 case UNW_FLAG_FHANDLER
:
131 ui
->rva_ExceptionHandler
= bfd_get_32 (abfd
, ex_dta
);
132 ui
->SizeOfBlock
+= 4;
139 /* Display unwind codes. */
142 pex64_xdata_print_uwd_codes (FILE *file
, bfd
*abfd
,
143 struct pex64_unwind_info
*ui
,
144 struct pex64_runtime_function
*rf
)
147 unsigned int tmp
; /* At least 32 bits. */
150 if (ui
->CountOfCodes
== 0 || ui
->rawUnwindCodes
== NULL
)
153 /* According to UNWIND_CODE documentation:
154 If an FP reg is used, the any unwind code taking an offset must only be
155 used after the FP reg is established in the prolog.
156 But there are counter examples of that in system dlls... */
162 && PEX64_UNWCODE_CODE (ui
->rawUnwindCodes
[1]) == UWOP_EPILOG
)
164 /* Display epilog opcode (whose docoding is not fully documented).
165 Looks to be designed to speed-up unwinding, as there is no need
166 to decode instruction flow if outside an epilog. */
167 unsigned int func_size
= rf
->rva_EndAddress
- rf
->rva_BeginAddress
;
169 fprintf (file
, "\tv2 epilog (length: %02x) at pc+:",
170 ui
->rawUnwindCodes
[0]);
171 if (PEX64_UNWCODE_INFO (ui
->rawUnwindCodes
[1]))
172 fprintf (file
, " 0x%x", func_size
- ui
->rawUnwindCodes
[0]);
174 for (; i
< ui
->CountOfCodes
; i
++)
176 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
179 if (PEX64_UNWCODE_CODE (dta
[1]) != UWOP_EPILOG
)
181 off
= dta
[0] | (PEX64_UNWCODE_INFO (dta
[1]) << 8);
183 fprintf (file
, " [pad]");
185 fprintf (file
, " 0x%x", func_size
- off
);
190 for (; i
< ui
->CountOfCodes
; i
++)
192 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
193 unsigned int info
= PEX64_UNWCODE_INFO (dta
[1]);
194 int unexpected
= FALSE
;
196 fprintf (file
, "\t pc+0x%02x: ", (unsigned int) dta
[0]);
197 switch (PEX64_UNWCODE_CODE (dta
[1]))
199 case UWOP_PUSH_NONVOL
:
200 fprintf (file
, "push %s", pex_regs
[info
]);
202 case UWOP_ALLOC_LARGE
:
205 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
210 tmp
= bfd_get_32 (abfd
, &dta
[2]);
213 fprintf (file
, "alloc large area: rsp = rsp - 0x%x", tmp
);
215 case UWOP_ALLOC_SMALL
:
216 fprintf (file
, "alloc small area: rsp = rsp - 0x%x", (info
+ 1) * 8);
219 /* According to the documentation, info field is unused. */
220 fprintf (file
, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
221 pex_regs
[ui
->FrameRegister
],
222 (unsigned int) ui
->FrameOffset
* 16, info
);
223 unexpected
= ui
->FrameRegister
== 0;
224 save_allowed
= FALSE
;
226 case UWOP_SAVE_NONVOL
:
227 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
229 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
230 unexpected
= !save_allowed
;
232 case UWOP_SAVE_NONVOL_FAR
:
233 tmp
= bfd_get_32 (abfd
, &dta
[2]);
235 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
236 unexpected
= !save_allowed
;
239 if (ui
->Version
== 1)
241 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
243 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
244 unexpected
= !save_allowed
;
246 else if (ui
->Version
== 2)
248 fprintf (file
, "epilog %02x %01x", dta
[0], info
);
252 case UWOP_SAVE_XMM_FAR
:
253 tmp
= bfd_get_32 (abfd
, &dta
[2]) * 8;
255 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
256 unexpected
= !save_allowed
;
258 case UWOP_SAVE_XMM128
:
259 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 16;
261 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
262 unexpected
= !save_allowed
;
264 case UWOP_SAVE_XMM128_FAR
:
265 tmp
= bfd_get_32 (abfd
, &dta
[2]) * 16;
267 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
268 unexpected
= !save_allowed
;
270 case UWOP_PUSH_MACHFRAME
:
271 fprintf (file
, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
275 fprintf (file
, ",ErrorCode)");
277 fprintf (file
, ", unknown(%u))", info
);
280 /* PR 17512: file: 2245-7442-0.004. */
281 fprintf (file
, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta
[1]));
285 fprintf (file
, " [Unexpected!]");
290 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
293 pex64_get_section_by_rva (bfd
*abfd
, bfd_vma addr
, const char *sec_name
)
295 asection
*section
= bfd_get_section_by_name (abfd
, sec_name
);
297 bfd_size_type datasize
= 0;
300 || coff_section_data (abfd
, section
) == NULL
301 || pei_section_data (abfd
, section
) == NULL
)
303 vsize
= section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
304 datasize
= section
->size
;
305 if (!datasize
|| vsize
> addr
|| (vsize
+ datasize
) < addr
)
310 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
311 designate the bfd section containing the xdata, XDATA is its content,
312 and ENDX the size if known (or NULL). */
315 pex64_dump_xdata (FILE *file
, bfd
*abfd
,
316 asection
*xdata_section
, bfd_byte
*xdata
, bfd_vma
*endx
,
317 struct pex64_runtime_function
*rf
)
321 bfd_vma addr
= rf
->rva_UnwindData
;
322 bfd_size_type sec_size
= xdata_section
->rawsize
> 0 ? xdata_section
->rawsize
: xdata_section
->size
;
323 struct pex64_unwind_info ui
;
325 vaddr
= xdata_section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
328 /* PR 17512: file: 2245-7442-0.004. */
329 if (addr
>= sec_size
)
331 fprintf (file
, _("warning: xdata section corrupt\n"));
337 end_addr
= endx
[0] - vaddr
;
338 /* PR 17512: file: 2245-7442-0.004. */
339 if (end_addr
> sec_size
)
341 fprintf (file
, _("warning: xdata section corrupt"));
348 pex64_get_unwind_info (abfd
, &ui
, &xdata
[addr
]);
350 if (ui
.Version
!= 1 && ui
.Version
!= 2)
353 fprintf (file
, "\tVersion %u (unknown).\n",
354 (unsigned int) ui
.Version
);
355 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
358 fprintf (file
, "\t %03x:", i
);
359 fprintf (file
, " %02x", xdata
[addr
]);
361 fprintf (file
, "\n");
364 fprintf (file
, "\n");
368 fprintf (file
, "\tVersion: %d, Flags: ", ui
.Version
);
371 case UNW_FLAG_NHANDLER
:
372 fprintf (file
, "none");
374 case UNW_FLAG_EHANDLER
:
375 fprintf (file
, "UNW_FLAG_EHANDLER");
377 case UNW_FLAG_UHANDLER
:
378 fprintf (file
, "UNW_FLAG_UHANDLER");
380 case UNW_FLAG_FHANDLER
:
382 (file
, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
384 case UNW_FLAG_CHAININFO
:
385 fprintf (file
, "UNW_FLAG_CHAININFO");
388 fprintf (file
, "unknown flags value 0x%x", (unsigned int) ui
.Flags
);
392 fprintf (file
, "\tNbr codes: %u, ", (unsigned int) ui
.CountOfCodes
);
393 fprintf (file
, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
394 (unsigned int) ui
.SizeOfPrologue
, (unsigned int) ui
.FrameOffset
);
395 fprintf (file
, "Frame reg: %s\n",
396 ui
.FrameRegister
== 0 ? "none"
397 : pex_regs
[(unsigned int) ui
.FrameRegister
]);
399 /* PR 17512: file: 2245-7442-0.004. */
400 if (ui
.CountOfCodes
* 2 + ui
.rawUnwindCodes
> xdata
+ xdata_section
->size
)
401 fprintf (file
, _("Too many unwind codes (%ld)\n"), (long) ui
.CountOfCodes
);
403 pex64_xdata_print_uwd_codes (file
, abfd
, &ui
, rf
);
407 case UNW_FLAG_EHANDLER
:
408 case UNW_FLAG_UHANDLER
:
409 case UNW_FLAG_FHANDLER
:
410 fprintf (file
, "\tHandler: ");
411 fprintf_vma (file
, (ui
.rva_ExceptionHandler
412 + pe_data (abfd
)->pe_opthdr
.ImageBase
));
413 fprintf (file
, ".\n");
415 case UNW_FLAG_CHAININFO
:
416 fprintf (file
, "\tChain: start: ");
417 fprintf_vma (file
, ui
.rva_BeginAddress
);
418 fprintf (file
, ", end: ");
419 fprintf_vma (file
, ui
.rva_EndAddress
);
420 fprintf (file
, "\n\t unwind data: ");
421 fprintf_vma (file
, ui
.rva_UnwindData
);
422 fprintf (file
, ".\n");
426 /* Now we need end of this xdata block. */
427 addr
+= ui
.SizeOfBlock
;
431 fprintf (file
,"\tUser data:\n");
432 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
435 fprintf (file
, "\t %03x:", i
);
436 fprintf (file
, " %02x", xdata
[addr
]);
438 fprintf (file
, "\n");
441 fprintf (file
, "\n");
445 /* Helper function to sort xdata. The entries of xdata are sorted to know
446 the size of each entry. */
449 sort_xdata_arr (const void *l
, const void *r
)
451 const bfd_vma
*lp
= (const bfd_vma
*) l
;
452 const bfd_vma
*rp
= (const bfd_vma
*) r
;
456 return (*lp
< *rp
? -1 : 1);
459 /* Display unwind tables for x86-64. */
462 pex64_bfd_print_pdata_section (bfd
*abfd
, void *vfile
, asection
*pdata_section
)
464 FILE *file
= (FILE *) vfile
;
465 bfd_byte
*pdata
= NULL
;
466 bfd_byte
*xdata
= NULL
;
467 asection
*xdata_section
= NULL
;
470 bfd_size_type datasize
;
472 bfd_vma prev_beginaddress
= (bfd_vma
) -1;
473 bfd_vma prev_unwinddata_rva
= (bfd_vma
) -1;
475 int onaline
= PDATA_ROW_SIZE
;
477 bfd_vma
*xdata_arr
= NULL
;
479 bfd_boolean virt_size_is_zero
= FALSE
;
482 if (pdata_section
== NULL
483 || coff_section_data (abfd
, pdata_section
) == NULL
484 || pei_section_data (abfd
, pdata_section
) == NULL
)
487 stop
= pei_section_data (abfd
, pdata_section
)->virt_size
;
488 if ((stop
% onaline
) != 0)
490 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
491 pdata_section
->name
, (long) stop
, onaline
);
493 datasize
= pdata_section
->size
;
497 fprintf (file
, _("Warning: %s section size is zero\n"),
498 pdata_section
->name
);
502 /* virt_size might be zero for objects. */
503 if (stop
== 0 && strcmp (abfd
->xvec
->name
, "pe-x86-64") == 0)
505 stop
= (datasize
/ onaline
) * onaline
;
506 virt_size_is_zero
= TRUE
;
508 else if (datasize
< stop
)
511 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
512 pdata_section
->name
, datasize
, stop
);
513 /* Be sure not to read passed datasize. */
514 stop
= datasize
/ onaline
;
517 /* Display functions table. */
519 _("\nThe Function Table (interpreted %s section contents)\n"),
520 pdata_section
->name
);
522 fprintf (file
, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
524 if (!bfd_malloc_and_get_section (abfd
, pdata_section
, &pdata
))
527 /* Table of xdata entries. */
528 xdata_arr
= (bfd_vma
*) xmalloc (sizeof (bfd_vma
) * ((stop
/ onaline
) + 1));
531 if (strcmp (abfd
->xvec
->name
, "pei-x86-64") == 0)
532 imagebase
= pe_data (abfd
)->pe_opthdr
.ImageBase
;
536 for (i
= 0; i
< stop
; i
+= onaline
)
538 struct pex64_runtime_function rf
;
540 if (i
+ PDATA_ROW_SIZE
> stop
)
543 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
545 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
546 && rf
.rva_UnwindData
== 0)
547 /* We are probably into the padding of the section now. */
550 fprintf_vma (file
, i
+ pdata_section
->vma
);
551 fprintf (file
, ":\t");
552 fprintf_vma (file
, imagebase
+ rf
.rva_BeginAddress
);
554 fprintf_vma (file
, imagebase
+ rf
.rva_EndAddress
);
556 fprintf_vma (file
, imagebase
+ rf
.rva_UnwindData
);
557 fprintf (file
, "\n");
558 if (i
!= 0 && rf
.rva_BeginAddress
<= prev_beginaddress
)
561 fprintf (file
, " has %s begin address as predecessor\n",
562 (rf
.rva_BeginAddress
< prev_beginaddress
? "smaller" : "same"));
564 prev_beginaddress
= rf
.rva_BeginAddress
;
565 /* Now we check for negative addresses. */
566 if ((prev_beginaddress
& 0x80000000) != 0)
569 fprintf (file
, " has negative begin address\n");
571 if ((rf
.rva_EndAddress
& 0x80000000) != 0)
574 fprintf (file
, " has negative end address\n");
576 if ((rf
.rva_UnwindData
& 0x80000000) != 0)
579 fprintf (file
, " has negative unwind address\n");
581 else if ((rf
.rva_UnwindData
&& !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
582 || virt_size_is_zero
)
583 xdata_arr
[xdata_arr_cnt
++] = rf
.rva_UnwindData
;
589 /* Add end of list marker. */
590 xdata_arr
[xdata_arr_cnt
++] = ~((bfd_vma
) 0);
592 /* Sort start RVAs of xdata. */
593 if (xdata_arr_cnt
> 1)
594 qsort (xdata_arr
, (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
597 /* Find the section containing the unwind data (.xdata). */
598 xdata_base
= xdata_arr
[0];
599 /* For sections with long names, first look for the same
600 section name, replacing .pdata by .xdata prefix. */
601 if (strcmp (pdata_section
->name
, ".pdata") != 0)
603 char *xdata_name
= alloca (strlen (pdata_section
->name
+ 1));
605 xdata_name
= strcpy (xdata_name
, pdata_section
->name
);
606 /* Transform .pdata prefix into .xdata prefix. */
607 if (strlen (xdata_name
) > 1)
608 xdata_name
[1] = 'x';
609 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
,
612 /* Second, try the .xdata section itself. */
614 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".xdata");
615 /* Otherwise, if xdata_base is non zero, search also inside
616 other standard sections. */
617 if (!xdata_section
&& xdata_base
)
618 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".rdata");
619 if (!xdata_section
&& xdata_base
)
620 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".data");
621 if (!xdata_section
&& xdata_base
)
622 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".pdata");
623 if (!xdata_section
&& xdata_base
)
624 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".text");
625 /* Transfer xdata section into xdata array. */
627 || !bfd_malloc_and_get_section (abfd
, xdata_section
, &xdata
))
630 /* Avoid "also used "... ouput for single unwind info
632 prev_unwinddata_rva
= (bfd_vma
) -1;
634 /* Do dump of pdata related xdata. */
635 for (i
= 0; i
< stop
; i
+= onaline
)
637 struct pex64_runtime_function rf
;
639 if (i
+ PDATA_ROW_SIZE
> stop
)
642 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
644 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
645 && rf
.rva_UnwindData
== 0)
646 /* We are probably into the padding of the section now. */
649 fprintf (file
, _("\nDump of %s\n"), xdata_section
->name
);
652 fprintf_vma (file
, rf
.rva_UnwindData
+ imagebase
);
654 if (prev_unwinddata_rva
== rf
.rva_UnwindData
)
656 /* Do not dump again the xdata for the same entry. */
657 fprintf (file
, " also used for function at ");
658 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
663 prev_unwinddata_rva
= rf
.rva_UnwindData
;
665 fprintf (file
, " (rva: %08x): ",
666 (unsigned int) rf
.rva_UnwindData
);
667 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
668 fprintf (file
, " - ");
669 fprintf_vma (file
, rf
.rva_EndAddress
+ imagebase
);
672 if (rf
.rva_UnwindData
!= 0 || virt_size_is_zero
)
674 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
676 bfd_vma altent
= PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf
);
677 bfd_vma pdata_vma
= bfd_get_section_vma (abfd
, pdata_section
);
678 struct pex64_runtime_function arf
;
680 fprintf (file
, "\t shares information with ");
683 if (altent
>= pdata_vma
684 && (altent
+ PDATA_ROW_SIZE
<= pdata_vma
685 + pei_section_data (abfd
, pdata_section
)->virt_size
))
687 pex64_get_runtime_function
688 (abfd
, &arf
, &pdata
[altent
- pdata_vma
]);
689 fprintf (file
, "pdata element at 0x");
690 fprintf_vma (file
, arf
.rva_UnwindData
);
693 fprintf (file
, "unknown pdata element");
694 fprintf (file
, ".\n");
700 /* Search for the current entry in the sorted array. */
702 bsearch (&rf
.rva_UnwindData
, xdata_arr
,
703 (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
706 /* Advance to the next pointer into the xdata section. We may
707 have shared xdata entries, which will result in a string of
708 identical pointers in the array; advance past all of them. */
709 while (p
[0] <= rf
.rva_UnwindData
)
712 if (p
[0] == ~((bfd_vma
) 0))
715 pex64_dump_xdata (file
, abfd
, xdata_section
, xdata
, p
, &rf
);
728 /* Static counter of number of found pdata sections. */
729 static bfd_boolean pdata_count
;
731 /* Functionn prototype. */
732 bfd_boolean
pex64_bfd_print_pdata (bfd
*, void *);
734 /* Helper function for bfd_map_over_section. */
736 pex64_print_all_pdata_sections (bfd
*abfd
, asection
*pdata
, void *obj
)
738 if (CONST_STRNEQ (pdata
->name
, ".pdata"))
740 if (pex64_bfd_print_pdata_section (abfd
, obj
, pdata
))
746 pex64_bfd_print_pdata (bfd
*abfd
, void *vfile
)
748 asection
*pdata_section
= bfd_get_section_by_name (abfd
, ".pdata");
751 return pex64_bfd_print_pdata_section (abfd
, vfile
, pdata_section
);
754 bfd_map_over_sections (abfd
, pex64_print_all_pdata_sections
, vfile
);
755 return (pdata_count
> 0);
758 #define bfd_pe_print_pdata pex64_bfd_print_pdata
759 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
761 #include "coff-x86_64.c"