Automatic date update in version.in
[binutils-gdb.git] / bfd / pei-x86_64.c
blobb1ee6d30f4afda1d71039eeda1422c8cde570774
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright (C) 2006-2024 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 #include "sysdep.h"
62 #include "bfd.h"
63 #include "libbfd.h"
64 #include "coff/x86_64.h"
65 #include "coff/internal.h"
66 #include "coff/pe.h"
67 #include "libcoff.h"
68 #include "libpei.h"
69 #include "libiberty.h"
71 #undef AOUTSZ
72 #define AOUTSZ PEPAOUTSZ
73 #define PEAOUTHDR PEPAOUTHDR
75 /* Name of registers according to SEH conventions. */
77 static const char * const pex_regs[16] = {
78 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
82 /* Swap in a runtime function. */
84 static void
85 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
86 const void *data)
88 const struct external_pex64_runtime_function *ex_rf =
89 (const struct external_pex64_runtime_function *) data;
90 rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress);
91 rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress);
92 rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData);
95 /* Swap in unwind info header. */
97 static bool
98 pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui,
99 void *data, void *data_end)
101 struct external_pex64_unwind_info *ex_ui =
102 (struct external_pex64_unwind_info *) data;
103 bfd_byte *ex_dta = (bfd_byte *) data;
104 bfd_byte *ex_dta_end = (bfd_byte *) data_end;
106 memset (ui, 0, sizeof (struct pex64_unwind_info));
108 if (ex_dta_end - ex_dta < 4)
109 return false;
111 ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags);
112 ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags);
113 ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue;
114 ui->CountOfCodes = (bfd_vma) ex_ui->CountOfCodes;
115 ui->FrameRegister = PEX64_UWI_FRAMEREG (ex_ui->FrameRegisterOffset);
116 ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset);
117 ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes);
118 ui->SizeOfBlock = ui->sizeofUnwindCodes + 4;
119 ui->rawUnwindCodes = ex_dta + 4;
120 ui->rawUnwindCodesEnd = ex_dta_end;
122 if ((size_t) (ex_dta_end - ex_dta) < ui->SizeOfBlock)
123 return false;
124 ex_dta += ui->SizeOfBlock;
126 switch (ui->Flags)
128 case UNW_FLAG_CHAININFO:
129 if (ex_dta_end - ex_dta < 12)
130 return false;
131 ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0);
132 ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4);
133 ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8);
134 ui->SizeOfBlock += 12;
135 return true;
136 case UNW_FLAG_EHANDLER:
137 case UNW_FLAG_UHANDLER:
138 case UNW_FLAG_FHANDLER:
139 if (ex_dta_end - ex_dta < 4)
140 return false;
141 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
142 ui->SizeOfBlock += 4;
143 return true;
144 default:
145 return true;
149 /* Display unwind codes. */
151 static void
152 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
153 struct pex64_unwind_info *ui,
154 struct pex64_runtime_function *rf)
156 unsigned int i;
157 unsigned int tmp; /* At least 32 bits. */
158 int save_allowed;
160 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
161 return;
163 /* According to UNWIND_CODE documentation:
164 If an FP reg is used, the any unwind code taking an offset must only be
165 used after the FP reg is established in the prolog.
166 But there are counter examples of that in system dlls... */
167 save_allowed = true;
169 i = 0;
171 if ((size_t) (ui->rawUnwindCodesEnd - ui->rawUnwindCodes)
172 < ui->CountOfCodes * 2)
174 fprintf (file, _("warning: corrupt unwind data\n"));
175 return;
178 if (ui->Version == 2
179 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
181 /* Display epilog opcode (whose docoding is not fully documented).
182 Looks to be designed to speed-up unwinding, as there is no need
183 to decode instruction flow if outside an epilog. */
184 unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
186 fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
187 ui->rawUnwindCodes[0]);
189 if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
190 fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
192 i++;
193 for (; i < ui->CountOfCodes; i++)
195 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
196 unsigned int off;
198 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
199 break;
200 off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
201 if (off == 0)
202 fprintf (file, " [pad]");
203 else
204 fprintf (file, " 0x%x", func_size - off);
206 fputc ('\n', file);
209 for (; i < ui->CountOfCodes; i++)
211 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
212 unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
213 int unexpected = false;
215 fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]);
217 switch (PEX64_UNWCODE_CODE (dta[1]))
219 case UWOP_PUSH_NONVOL:
220 fprintf (file, "push %s", pex_regs[info]);
221 break;
223 case UWOP_ALLOC_LARGE:
224 if (info == 0)
226 if (ui->rawUnwindCodesEnd - dta < 4)
228 fprintf (file, _("warning: corrupt unwind data\n"));
229 return;
231 tmp = bfd_get_16 (abfd, dta + 2) * 8;
232 i++;
234 else
236 if (ui->rawUnwindCodesEnd - dta < 6)
238 fprintf (file, _("warning: corrupt unwind data\n"));
239 return;
241 tmp = bfd_get_32 (abfd, dta + 2);
242 i += 2;
244 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
245 break;
247 case UWOP_ALLOC_SMALL:
248 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
249 break;
251 case UWOP_SET_FPREG:
252 /* According to the documentation, info field is unused. */
253 fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
254 pex_regs[ui->FrameRegister],
255 (unsigned int) ui->FrameOffset * 16, info);
256 unexpected = ui->FrameRegister == 0;
257 save_allowed = false;
258 break;
260 case UWOP_SAVE_NONVOL:
261 if (ui->rawUnwindCodesEnd - dta < 4)
263 fprintf (file, _("warning: corrupt unwind data\n"));
264 return;
266 tmp = bfd_get_16 (abfd, dta + 2) * 8;
267 i++;
268 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
269 unexpected = !save_allowed;
270 break;
272 case UWOP_SAVE_NONVOL_FAR:
273 if (ui->rawUnwindCodesEnd - dta < 6)
275 fprintf (file, _("warning: corrupt unwind data\n"));
276 return;
278 tmp = bfd_get_32 (abfd, dta + 2);
279 i += 2;
280 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
281 unexpected = !save_allowed;
282 break;
284 case UWOP_SAVE_XMM:
285 if (ui->Version == 1)
287 if (ui->rawUnwindCodesEnd - dta < 4)
289 fprintf (file, _("warning: corrupt unwind data\n"));
290 return;
292 tmp = bfd_get_16 (abfd, dta + 2) * 8;
293 i++;
294 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
295 unexpected = !save_allowed;
297 else if (ui->Version == 2)
299 fprintf (file, "epilog %02x %01x", dta[0], info);
300 unexpected = true;
302 break;
304 case UWOP_SAVE_XMM_FAR:
305 if (ui->rawUnwindCodesEnd - dta < 6)
307 fprintf (file, _("warning: corrupt unwind data\n"));
308 return;
310 tmp = bfd_get_32 (abfd, dta + 2) * 8;
311 i += 2;
312 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
313 unexpected = !save_allowed;
314 break;
316 case UWOP_SAVE_XMM128:
317 if (ui->rawUnwindCodesEnd - dta < 4)
319 fprintf (file, _("warning: corrupt unwind data\n"));
320 return;
322 tmp = bfd_get_16 (abfd, dta + 2) * 16;
323 i++;
324 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
325 unexpected = !save_allowed;
326 break;
328 case UWOP_SAVE_XMM128_FAR:
329 if (ui->rawUnwindCodesEnd - dta < 6)
331 fprintf (file, _("warning: corrupt unwind data\n"));
332 return;
334 tmp = bfd_get_32 (abfd, dta + 2) * 16;
335 i += 2;
336 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
337 unexpected = !save_allowed;
338 break;
340 case UWOP_PUSH_MACHFRAME:
341 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
342 if (info == 0)
343 fprintf (file, ")");
344 else if (info == 1)
345 fprintf (file, ",ErrorCode)");
346 else
347 fprintf (file, ", unknown(%u))", info);
348 break;
350 default:
351 /* PR 17512: file: 2245-7442-0.004. */
352 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
353 break;
356 if (unexpected)
357 fprintf (file, " [Unexpected!]");
358 fputc ('\n', file);
362 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
364 static asection *
365 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
367 asection *section = bfd_get_section_by_name (abfd, sec_name);
368 bfd_vma vsize;
369 bfd_size_type datasize = 0;
371 if (section == NULL
372 || coff_section_data (abfd, section) == NULL
373 || pei_section_data (abfd, section) == NULL)
374 return NULL;
375 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
376 datasize = section->size;
377 if (!datasize || vsize > addr || (vsize + datasize) < addr)
378 return NULL;
379 return section;
382 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
383 designate the bfd section containing the xdata, XDATA is its content,
384 and ENDX the size if known (or NULL). */
386 static void
387 pex64_dump_xdata (FILE *file, bfd *abfd,
388 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
389 struct pex64_runtime_function *rf)
391 bfd_vma vaddr;
392 bfd_vma end_addr;
393 bfd_vma addr = rf->rva_UnwindData;
394 bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
395 struct pex64_unwind_info ui;
397 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
398 addr -= vaddr;
400 /* PR 17512: file: 2245-7442-0.004. */
401 if (addr >= sec_size)
403 fprintf (file, _("warning: xdata section corrupt\n"));
404 return;
407 if (endx)
409 end_addr = endx[0] - vaddr;
410 /* PR 17512: file: 2245-7442-0.004. */
411 if (end_addr > sec_size)
413 fprintf (file, _("warning: xdata section corrupt\n"));
414 end_addr = sec_size;
417 else
418 end_addr = sec_size;
420 if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
422 fprintf (file, _("warning: xdata section corrupt\n"));
423 return;
426 if (ui.Version != 1 && ui.Version != 2)
428 unsigned int i;
429 fprintf (file, "\tVersion %u (unknown).\n",
430 (unsigned int) ui.Version);
431 for (i = 0; addr < end_addr; addr += 1, i++)
433 if ((i & 15) == 0)
434 fprintf (file, "\t %03x:", i);
435 fprintf (file, " %02x", xdata[addr]);
436 if ((i & 15) == 15)
437 fprintf (file, "\n");
439 if ((i & 15) != 0)
440 fprintf (file, "\n");
441 return;
444 fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
445 switch (ui.Flags)
447 case UNW_FLAG_NHANDLER:
448 fprintf (file, "none");
449 break;
450 case UNW_FLAG_EHANDLER:
451 fprintf (file, "UNW_FLAG_EHANDLER");
452 break;
453 case UNW_FLAG_UHANDLER:
454 fprintf (file, "UNW_FLAG_UHANDLER");
455 break;
456 case UNW_FLAG_FHANDLER:
457 fprintf
458 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
459 break;
460 case UNW_FLAG_CHAININFO:
461 fprintf (file, "UNW_FLAG_CHAININFO");
462 break;
463 default:
464 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
465 break;
467 fputc ('\n', file);
468 fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
469 fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
470 (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
471 fprintf (file, "Frame reg: %s\n",
472 ui.FrameRegister == 0 ? "none"
473 : pex_regs[(unsigned int) ui.FrameRegister]);
475 /* PR 17512: file: 2245-7442-0.004. */
476 if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
477 fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
478 else
479 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
481 switch (ui.Flags)
483 case UNW_FLAG_EHANDLER:
484 case UNW_FLAG_UHANDLER:
485 case UNW_FLAG_FHANDLER:
486 fprintf (file, "\tHandler: %016" PRIx64 ".\n",
487 ui.rva_ExceptionHandler + pe_data (abfd)->pe_opthdr.ImageBase);
488 break;
489 case UNW_FLAG_CHAININFO:
490 fprintf (file, "\tChain: start: %016" PRIx64 ", end: %016" PRIx64,
491 ui.rva_BeginAddress, ui.rva_EndAddress);
492 fprintf (file, "\n\t unwind data: %016" PRIx64 ".\n",
493 ui.rva_UnwindData);
494 break;
497 /* Now we need end of this xdata block. */
498 addr += ui.SizeOfBlock;
499 if (addr < end_addr)
501 unsigned int i;
502 fprintf (file,"\tUser data:\n");
503 for (i = 0; addr < end_addr; addr += 1, i++)
505 if ((i & 15) == 0)
506 fprintf (file, "\t %03x:", i);
507 fprintf (file, " %02x", xdata[addr]);
508 if ((i & 15) == 15)
509 fprintf (file, "\n");
511 if ((i & 15) != 0)
512 fprintf (file, "\n");
516 /* Helper function to sort xdata. The entries of xdata are sorted to know
517 the size of each entry. */
519 static int
520 sort_xdata_arr (const void *l, const void *r)
522 const bfd_vma *lp = (const bfd_vma *) l;
523 const bfd_vma *rp = (const bfd_vma *) r;
525 if (*lp == *rp)
526 return 0;
527 return (*lp < *rp ? -1 : 1);
530 /* Display unwind tables for x86-64. */
532 static bool
533 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
535 FILE *file = (FILE *) vfile;
536 bfd_byte *pdata = NULL;
537 bfd_byte *xdata = NULL;
538 asection *xdata_section = NULL;
539 bfd_vma xdata_base;
540 bfd_size_type i;
541 bfd_size_type datasize;
542 bfd_size_type stop;
543 bfd_vma prev_beginaddress = (bfd_vma) -1;
544 bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
545 bfd_vma imagebase;
546 int onaline = PDATA_ROW_SIZE;
547 int seen_error = 0;
548 bfd_vma *xdata_arr = NULL;
549 int xdata_arr_cnt;
550 bool virt_size_is_zero = false;
552 /* Sanity checks. */
553 if (pdata_section == NULL
554 || (pdata_section->flags & SEC_HAS_CONTENTS) == 0
555 || coff_section_data (abfd, pdata_section) == NULL
556 || pei_section_data (abfd, pdata_section) == NULL)
557 return true;
559 stop = pei_section_data (abfd, pdata_section)->virt_size;
560 if ((stop % onaline) != 0)
561 fprintf (file,
562 /* xgettext:c-format */
563 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
564 pdata_section->name, (long) stop, onaline);
566 datasize = pdata_section->size;
567 if (datasize == 0)
569 if (stop)
570 fprintf (file, _("Warning: %s section size is zero\n"),
571 pdata_section->name);
572 return true;
575 /* virt_size might be zero for objects. */
576 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
578 stop = datasize;
579 virt_size_is_zero = true;
581 else if (datasize < stop)
583 fprintf (file,
584 /* xgettext:c-format */
585 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
586 pdata_section->name, (unsigned long) datasize,
587 (unsigned long) stop);
588 /* Be sure not to read past datasize. */
589 stop = datasize;
592 /* Display functions table. */
593 fprintf (file,
594 _("\nThe Function Table (interpreted %s section contents)\n"),
595 pdata_section->name);
597 fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
599 if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
600 goto done;
602 /* Table of xdata entries. */
603 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
604 xdata_arr_cnt = 0;
606 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
607 imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
608 else
609 imagebase = 0;
611 for (i = 0; i < stop; i += onaline)
613 struct pex64_runtime_function rf;
615 if (i + PDATA_ROW_SIZE > stop)
616 break;
618 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
620 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
621 && rf.rva_UnwindData == 0)
622 /* We are probably into the padding of the section now. */
623 break;
624 fprintf (file, " %016" PRIx64, i + pdata_section->vma);
625 fprintf (file, ":\t%016" PRIx64, imagebase + rf.rva_BeginAddress);
626 fprintf (file, " %016" PRIx64, imagebase + rf.rva_EndAddress);
627 fprintf (file, " %016" PRIx64 "\n", imagebase + rf.rva_UnwindData);
628 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
630 seen_error = 1;
631 fprintf (file, " has %s begin address as predecessor\n",
632 (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
634 prev_beginaddress = rf.rva_BeginAddress;
635 /* Now we check for negative addresses. */
636 if ((prev_beginaddress & 0x80000000) != 0)
638 seen_error = 1;
639 fprintf (file, " has negative begin address\n");
641 if ((rf.rva_EndAddress & 0x80000000) != 0)
643 seen_error = 1;
644 fprintf (file, " has negative end address\n");
646 if ((rf.rva_UnwindData & 0x80000000) != 0)
648 seen_error = 1;
649 fprintf (file, " has negative unwind address\n");
651 else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
652 || virt_size_is_zero)
653 xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
656 if (seen_error)
657 goto done;
659 /* Add end of list marker. */
660 xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
662 /* Sort start RVAs of xdata. */
663 if (xdata_arr_cnt > 1)
664 qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
665 sort_xdata_arr);
667 /* Find the section containing the unwind data (.xdata). */
668 xdata_base = xdata_arr[0];
669 /* For sections with long names, first look for the same
670 section name, replacing .pdata by .xdata prefix. */
671 if (strcmp (pdata_section->name, ".pdata") != 0)
673 size_t len = strlen (pdata_section->name);
674 char *xdata_name = xmalloc (len + 1);
676 xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
677 /* Transform .pdata prefix into .xdata prefix. */
678 if (len > 1)
679 xdata_name [1] = 'x';
680 xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
681 xdata_name);
682 free (xdata_name);
684 /* Second, try the .xdata section itself. */
685 if (!xdata_section)
686 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
687 /* Otherwise, if xdata_base is non zero, search also inside
688 other standard sections. */
689 if (!xdata_section && xdata_base)
690 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
691 if (!xdata_section && xdata_base)
692 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
693 if (!xdata_section && xdata_base)
694 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
695 if (!xdata_section && xdata_base)
696 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
697 /* Transfer xdata section into xdata array. */
698 if (!xdata_section
699 || (xdata_section->flags & SEC_HAS_CONTENTS) == 0
700 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
701 goto done;
703 /* Avoid "also used "... ouput for single unwind info
704 in object file. */
705 prev_unwinddata_rva = (bfd_vma) -1;
707 /* Do dump of pdata related xdata. */
708 for (i = 0; i < stop; i += onaline)
710 struct pex64_runtime_function rf;
712 if (i + PDATA_ROW_SIZE > stop)
713 break;
715 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
717 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
718 && rf.rva_UnwindData == 0)
719 /* We are probably into the padding of the section now. */
720 break;
721 if (i == 0)
722 fprintf (file, _("\nDump of %s\n"), xdata_section->name);
724 fprintf (file, " %016" PRIx64, rf.rva_UnwindData + imagebase);
726 if (prev_unwinddata_rva == rf.rva_UnwindData)
728 /* Do not dump again the xdata for the same entry. */
729 fprintf (file, " also used for function at %016" PRIx64 "\n",
730 rf.rva_BeginAddress + imagebase);
731 continue;
733 else
734 prev_unwinddata_rva = rf.rva_UnwindData;
736 fprintf (file, " (rva: %08x): %016" PRIx64 " - %016" PRIx64 "\n",
737 (unsigned int) rf.rva_UnwindData,
738 rf.rva_BeginAddress + imagebase,
739 rf.rva_EndAddress + imagebase);
741 if (rf.rva_UnwindData != 0 || virt_size_is_zero)
743 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
745 bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
746 bfd_vma pdata_vma = bfd_section_vma (pdata_section);
747 struct pex64_runtime_function arf;
749 fprintf (file, "\t shares information with ");
750 altent += imagebase;
752 if (altent >= pdata_vma
753 && altent - pdata_vma + PDATA_ROW_SIZE <= stop)
755 pex64_get_runtime_function
756 (abfd, &arf, &pdata[altent - pdata_vma]);
757 fprintf (file, "pdata element at 0x%016" PRIx64,
758 arf.rva_UnwindData);
760 else
761 fprintf (file, "unknown pdata element");
762 fprintf (file, ".\n");
764 else
766 bfd_vma *p;
768 /* Search for the current entry in the sorted array. */
769 p = (bfd_vma *)
770 bsearch (&rf.rva_UnwindData, xdata_arr,
771 (size_t) xdata_arr_cnt, sizeof (bfd_vma),
772 sort_xdata_arr);
774 /* Advance to the next pointer into the xdata section. We may
775 have shared xdata entries, which will result in a string of
776 identical pointers in the array; advance past all of them. */
777 while (p[0] <= rf.rva_UnwindData)
778 ++p;
780 if (p[0] == ~((bfd_vma) 0))
781 p = NULL;
783 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
788 done:
789 free (pdata);
790 free (xdata_arr);
791 free (xdata);
793 return true;
796 struct pex64_paps
798 void *obj;
799 /* Number of found pdata sections. */
800 unsigned int pdata_count;
803 /* Functionn prototype. */
804 bool pex64_bfd_print_pdata (bfd *, void *);
806 /* Helper function for bfd_map_over_section. */
807 static void
808 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *arg)
810 struct pex64_paps *paps = arg;
811 if (startswith (pdata->name, ".pdata"))
813 if (pex64_bfd_print_pdata_section (abfd, paps->obj, pdata))
814 paps->pdata_count++;
818 bool
819 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
821 asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
822 struct pex64_paps paps;
824 if (pdata_section)
825 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
827 paps.obj = vfile;
828 paps.pdata_count = 0;
829 bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, &paps);
830 return paps.pdata_count != 0;
833 #define bfd_pe_print_pdata pex64_bfd_print_pdata
834 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
836 #include "coff-x86_64.c"