gprofng: fix build with -mx32
[binutils-gdb/blckswan.git] / bfd / pei-x86_64.c
blob90ee530ea20bed14ba26eddef16868dfd094d5fa
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,
19 MA 02110-1301, USA.
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
23 #include "sysdep.h"
24 #include "bfd.h"
26 #define TARGET_SYM x86_64_pei_vec
27 #define TARGET_NAME "pei-x86-64"
28 #define COFF_IMAGE_WITH_PE
29 #define COFF_WITH_PE
30 #define COFF_WITH_pex64
31 #define PCRELOFFSET true
32 #if defined (USE_MINGW64_LEADING_UNDERSCORES)
33 #define TARGET_UNDERSCORE '_'
34 #else
35 #define TARGET_UNDERSCORE 0
36 #endif
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 */
64 #define PEI_HEADERS
65 #include "sysdep.h"
66 #include "bfd.h"
67 #include "libbfd.h"
68 #include "coff/x86_64.h"
69 #include "coff/internal.h"
70 #include "coff/pe.h"
71 #include "libcoff.h"
72 #include "libpei.h"
73 #include "libiberty.h"
75 #undef AOUTSZ
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. */
88 static void
89 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
90 const void *data)
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. */
101 static bool
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)
113 return false;
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)
128 return false;
130 switch (ui->Flags)
132 case UNW_FLAG_CHAININFO:
133 if (ex_dta + 12 >= ex_dta_end)
134 return false;
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;
139 return true;
140 case UNW_FLAG_EHANDLER:
141 case UNW_FLAG_UHANDLER:
142 case UNW_FLAG_FHANDLER:
143 if (ex_dta + 4 >= ex_dta_end)
144 return false;
145 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
146 ui->SizeOfBlock += 4;
147 return true;
148 default:
149 return true;
153 /* Display unwind codes. */
155 static void
156 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
157 struct pex64_unwind_info *ui,
158 struct pex64_runtime_function *rf)
160 unsigned int i;
161 unsigned int tmp; /* At least 32 bits. */
162 int save_allowed;
164 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
165 return;
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... */
171 save_allowed = true;
173 i = 0;
175 if (ui->rawUnwindCodes + 1 >= ui->rawUnwindCodesEnd)
177 fprintf (file, _("warning: corrupt unwind data\n"));
178 return;
181 if (ui->Version == 2
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"));
192 return;
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]);
201 i++;
202 for (; i < ui->CountOfCodes; i++)
204 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
205 unsigned int off;
207 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
208 break;
209 off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
210 if (off == 0)
211 fprintf (file, " [pad]");
212 else
213 fprintf (file, " 0x%x", func_size - off);
215 fputc ('\n', file);
218 if (ui->rawUnwindCodes + 2 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
220 fprintf (file, _("warning: corrupt unwind data\n"));
221 return;
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]);
236 break;
238 case UWOP_ALLOC_LARGE:
239 if (info == 0)
241 if (dta + 4 > ui->rawUnwindCodesEnd)
243 fprintf (file, _("warning: corrupt unwind data\n"));
244 return;
246 tmp = bfd_get_16 (abfd, dta + 2) * 8;
247 i++;
249 else
251 if (dta + 6 > ui->rawUnwindCodesEnd)
253 fprintf (file, _("warning: corrupt unwind data\n"));
254 return;
256 tmp = bfd_get_32 (abfd, dta + 2);
257 i += 2;
259 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
260 break;
262 case UWOP_ALLOC_SMALL:
263 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
264 break;
266 case UWOP_SET_FPREG:
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;
273 break;
275 case UWOP_SAVE_NONVOL:
276 if (dta + 4 > ui->rawUnwindCodesEnd)
278 fprintf (file, _("warning: corrupt unwind data\n"));
279 return;
281 tmp = bfd_get_16 (abfd, dta + 2) * 8;
282 i++;
283 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
284 unexpected = !save_allowed;
285 break;
287 case UWOP_SAVE_NONVOL_FAR:
288 if (dta + 6 > ui->rawUnwindCodesEnd)
290 fprintf (file, _("warning: corrupt unwind data\n"));
291 return;
293 tmp = bfd_get_32 (abfd, dta + 2);
294 i += 2;
295 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
296 unexpected = !save_allowed;
297 break;
299 case UWOP_SAVE_XMM:
300 if (ui->Version == 1)
302 if (dta + 4 > ui->rawUnwindCodesEnd)
304 fprintf (file, _("warning: corrupt unwind data\n"));
305 return;
307 tmp = bfd_get_16 (abfd, dta + 2) * 8;
308 i++;
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);
315 unexpected = true;
317 break;
319 case UWOP_SAVE_XMM_FAR:
320 if (dta + 6 > ui->rawUnwindCodesEnd)
322 fprintf (file, _("warning: corrupt unwind data\n"));
323 return;
325 tmp = bfd_get_32 (abfd, dta + 2) * 8;
326 i += 2;
327 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
328 unexpected = !save_allowed;
329 break;
331 case UWOP_SAVE_XMM128:
332 if (dta + 4 > ui->rawUnwindCodesEnd)
334 fprintf (file, _("warning: corrupt unwind data\n"));
335 return;
337 tmp = bfd_get_16 (abfd, dta + 2) * 16;
338 i++;
339 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
340 unexpected = !save_allowed;
341 break;
343 case UWOP_SAVE_XMM128_FAR:
344 if (dta + 6 > ui->rawUnwindCodesEnd)
346 fprintf (file, _("warning: corrupt unwind data\n"));
347 return;
349 tmp = bfd_get_32 (abfd, dta + 2) * 16;
350 i += 2;
351 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
352 unexpected = !save_allowed;
353 break;
355 case UWOP_PUSH_MACHFRAME:
356 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
357 if (info == 0)
358 fprintf (file, ")");
359 else if (info == 1)
360 fprintf (file, ",ErrorCode)");
361 else
362 fprintf (file, ", unknown(%u))", info);
363 break;
365 default:
366 /* PR 17512: file: 2245-7442-0.004. */
367 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
368 break;
371 if (unexpected)
372 fprintf (file, " [Unexpected!]");
373 fputc ('\n', file);
377 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
379 static asection *
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);
383 bfd_vma vsize;
384 bfd_size_type datasize = 0;
386 if (section == NULL
387 || coff_section_data (abfd, section) == NULL
388 || pei_section_data (abfd, section) == NULL)
389 return NULL;
390 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
391 datasize = section->size;
392 if (!datasize || vsize > addr || (vsize + datasize) < addr)
393 return NULL;
394 return section;
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). */
401 static void
402 pex64_dump_xdata (FILE *file, bfd *abfd,
403 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
404 struct pex64_runtime_function *rf)
406 bfd_vma vaddr;
407 bfd_vma end_addr;
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;
413 addr -= vaddr;
415 /* PR 17512: file: 2245-7442-0.004. */
416 if (addr >= sec_size)
418 fprintf (file, _("warning: xdata section corrupt\n"));
419 return;
422 if (endx)
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"));
429 end_addr = sec_size;
432 else
433 end_addr = sec_size;
435 if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
437 fprintf (file, _("warning: xdata section corrupt\n"));
438 return;
441 if (ui.Version != 1 && ui.Version != 2)
443 unsigned int i;
444 fprintf (file, "\tVersion %u (unknown).\n",
445 (unsigned int) ui.Version);
446 for (i = 0; addr < end_addr; addr += 1, i++)
448 if ((i & 15) == 0)
449 fprintf (file, "\t %03x:", i);
450 fprintf (file, " %02x", xdata[addr]);
451 if ((i & 15) == 15)
452 fprintf (file, "\n");
454 if ((i & 15) != 0)
455 fprintf (file, "\n");
456 return;
459 fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
460 switch (ui.Flags)
462 case UNW_FLAG_NHANDLER:
463 fprintf (file, "none");
464 break;
465 case UNW_FLAG_EHANDLER:
466 fprintf (file, "UNW_FLAG_EHANDLER");
467 break;
468 case UNW_FLAG_UHANDLER:
469 fprintf (file, "UNW_FLAG_UHANDLER");
470 break;
471 case UNW_FLAG_FHANDLER:
472 fprintf
473 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
474 break;
475 case UNW_FLAG_CHAININFO:
476 fprintf (file, "UNW_FLAG_CHAININFO");
477 break;
478 default:
479 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
480 break;
482 fputc ('\n', file);
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);
493 else
494 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
496 switch (ui.Flags)
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");
505 break;
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");
514 break;
517 /* Now we need end of this xdata block. */
518 addr += ui.SizeOfBlock;
519 if (addr < end_addr)
521 unsigned int i;
522 fprintf (file,"\tUser data:\n");
523 for (i = 0; addr < end_addr; addr += 1, i++)
525 if ((i & 15) == 0)
526 fprintf (file, "\t %03x:", i);
527 fprintf (file, " %02x", xdata[addr]);
528 if ((i & 15) == 15)
529 fprintf (file, "\n");
531 if ((i & 15) != 0)
532 fprintf (file, "\n");
536 /* Helper function to sort xdata. The entries of xdata are sorted to know
537 the size of each entry. */
539 static int
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;
545 if (*lp == *rp)
546 return 0;
547 return (*lp < *rp ? -1 : 1);
550 /* Display unwind tables for x86-64. */
552 static bool
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;
559 bfd_vma xdata_base;
560 bfd_size_type i;
561 bfd_size_type datasize;
562 bfd_size_type stop;
563 bfd_vma prev_beginaddress = (bfd_vma) -1;
564 bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
565 bfd_vma imagebase;
566 int onaline = PDATA_ROW_SIZE;
567 int seen_error = 0;
568 bfd_vma *xdata_arr = NULL;
569 int xdata_arr_cnt;
570 bool virt_size_is_zero = false;
572 /* Sanity checks. */
573 if (pdata_section == NULL
574 || coff_section_data (abfd, pdata_section) == NULL
575 || pei_section_data (abfd, pdata_section) == NULL)
576 return true;
578 stop = pei_section_data (abfd, pdata_section)->virt_size;
579 if ((stop % onaline) != 0)
580 fprintf (file,
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;
586 if (datasize == 0)
588 if (stop)
589 fprintf (file, _("Warning: %s section size is zero\n"),
590 pdata_section->name);
591 return true;
594 /* virt_size might be zero for objects. */
595 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
597 stop = datasize;
598 virt_size_is_zero = true;
600 else if (datasize < stop)
602 fprintf (file,
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. */
608 stop = datasize;
611 /* Display functions table. */
612 fprintf (file,
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))
619 goto done;
621 /* Table of xdata entries. */
622 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
623 xdata_arr_cnt = 0;
625 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
626 imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
627 else
628 imagebase = 0;
630 for (i = 0; i < stop; i += onaline)
632 struct pex64_runtime_function rf;
634 if (i + PDATA_ROW_SIZE > stop)
635 break;
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. */
642 break;
643 fputc (' ', file);
644 fprintf_vma (file, i + pdata_section->vma);
645 fprintf (file, ":\t");
646 fprintf_vma (file, imagebase + rf.rva_BeginAddress);
647 fprintf (file, " ");
648 fprintf_vma (file, imagebase + rf.rva_EndAddress);
649 fprintf (file, " ");
650 fprintf_vma (file, imagebase + rf.rva_UnwindData);
651 fprintf (file, "\n");
652 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
654 seen_error = 1;
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)
662 seen_error = 1;
663 fprintf (file, " has negative begin address\n");
665 if ((rf.rva_EndAddress & 0x80000000) != 0)
667 seen_error = 1;
668 fprintf (file, " has negative end address\n");
670 if ((rf.rva_UnwindData & 0x80000000) != 0)
672 seen_error = 1;
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;
680 if (seen_error)
681 goto done;
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),
689 sort_xdata_arr);
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. */
702 if (len > 1)
703 xdata_name [1] = 'x';
704 xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
705 xdata_name);
706 free (xdata_name);
708 /* Second, try the .xdata section itself. */
709 if (!xdata_section)
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. */
722 if (!xdata_section
723 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
724 goto done;
726 /* Avoid "also used "... ouput for single unwind info
727 in object file. */
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)
736 break;
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. */
743 break;
744 if (i == 0)
745 fprintf (file, _("\nDump of %s\n"), xdata_section->name);
747 fputc (' ', file);
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);
755 fputc ('\n', file);
756 continue;
758 else
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);
766 fputc ('\n', file);
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 ");
777 altent += imagebase;
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);
787 else
788 fprintf (file, "unknown pdata element");
789 fprintf (file, ".\n");
791 else
793 bfd_vma *p;
795 /* Search for the current entry in the sorted array. */
796 p = (bfd_vma *)
797 bsearch (&rf.rva_UnwindData, xdata_arr,
798 (size_t) xdata_arr_cnt, sizeof (bfd_vma),
799 sort_xdata_arr);
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)
805 ++p;
807 if (p[0] == ~((bfd_vma) 0))
808 p = NULL;
810 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
815 done:
816 free (pdata);
817 free (xdata_arr);
818 free (xdata);
820 return true;
823 struct pex64_paps
825 void *obj;
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. */
834 static void
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))
841 paps->pdata_count++;
845 bool
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;
851 if (pdata_section)
852 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
854 paps.obj = vfile;
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"