tmpfs - Fix tmpfs_fid, fix NFS exports
[dragonfly.git] / contrib / binutils-2.25 / bfd / pei-x86_64.c
blobe53a353a515a6ceb0e6cbdaa2c5e1df949006853
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,
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 void
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];
118 ex_dta += ui->SizeOfBlock;
119 switch (ui->Flags)
121 case UNW_FLAG_CHAININFO:
122 ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0);
123 ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4);
124 ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8);
125 ui->SizeOfBlock += 12;
126 return;
127 case UNW_FLAG_EHANDLER:
128 case UNW_FLAG_UHANDLER:
129 case UNW_FLAG_FHANDLER:
130 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
131 ui->SizeOfBlock += 4;
132 return;
133 default:
134 return;
138 /* Display unwind codes. */
140 static void
141 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
142 struct pex64_unwind_info *ui,
143 struct pex64_runtime_function *rf)
145 unsigned int i;
146 unsigned int tmp; /* At least 32 bits. */
147 int save_allowed;
149 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
150 return;
152 /* According to UNWIND_CODE documentation:
153 If an FP reg is used, the any unwind code taking an offset must only be
154 used after the FP reg is established in the prolog.
155 But there are counter examples of that in system dlls... */
156 save_allowed = TRUE;
158 i = 0;
160 if (ui->Version == 2
161 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
163 /* Display epilog opcode (whose docoding is not fully documented).
164 Looks to be designed to speed-up unwinding, as there is no need
165 to decode instruction flow if outside an epilog. */
166 unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
168 fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
169 ui->rawUnwindCodes[0]);
170 if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
171 fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
172 i++;
173 for (; i < ui->CountOfCodes; i++)
175 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
176 unsigned int off;
178 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
179 break;
180 off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
181 if (off == 0)
182 fprintf (file, " [pad]");
183 else
184 fprintf (file, " 0x%x", func_size - off);
186 fputc ('\n', file);
189 for (; i < ui->CountOfCodes; i++)
191 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
192 unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
193 int unexpected = FALSE;
195 fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]);
196 switch (PEX64_UNWCODE_CODE (dta[1]))
198 case UWOP_PUSH_NONVOL:
199 fprintf (file, "push %s", pex_regs[info]);
200 break;
201 case UWOP_ALLOC_LARGE:
202 if (info == 0)
204 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
205 i++;
207 else
209 tmp = bfd_get_32 (abfd, &dta[2]);
210 i += 2;
212 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
213 break;
214 case UWOP_ALLOC_SMALL:
215 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
216 break;
217 case UWOP_SET_FPREG:
218 /* According to the documentation, info field is unused. */
219 fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
220 pex_regs[ui->FrameRegister],
221 (unsigned int) ui->FrameOffset * 16, info);
222 unexpected = ui->FrameRegister == 0;
223 save_allowed = FALSE;
224 break;
225 case UWOP_SAVE_NONVOL:
226 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
227 i++;
228 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
229 unexpected = !save_allowed;
230 break;
231 case UWOP_SAVE_NONVOL_FAR:
232 tmp = bfd_get_32 (abfd, &dta[2]);
233 i += 2;
234 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
235 unexpected = !save_allowed;
236 break;
237 case UWOP_SAVE_XMM:
238 if (ui->Version == 1)
240 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
241 i++;
242 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
243 unexpected = !save_allowed;
245 else if (ui->Version == 2)
247 fprintf (file, "epilog %02x %01x", dta[0], info);
248 unexpected = TRUE;
250 break;
251 case UWOP_SAVE_XMM_FAR:
252 tmp = bfd_get_32 (abfd, &dta[2]) * 8;
253 i += 2;
254 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
255 unexpected = !save_allowed;
256 break;
257 case UWOP_SAVE_XMM128:
258 tmp = bfd_get_16 (abfd, &dta[2]) * 16;
259 i++;
260 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
261 unexpected = !save_allowed;
262 break;
263 case UWOP_SAVE_XMM128_FAR:
264 tmp = bfd_get_32 (abfd, &dta[2]) * 16;
265 i += 2;
266 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
267 unexpected = !save_allowed;
268 break;
269 case UWOP_PUSH_MACHFRAME:
270 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
271 if (info == 0)
272 fprintf (file, ")");
273 else if (info == 1)
274 fprintf (file, ",ErrorCode)");
275 else
276 fprintf (file, ", unknown(%u))", info);
277 break;
278 default:
279 /* PR 17512: file: 2245-7442-0.004. */
280 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
281 break;
283 if (unexpected)
284 fprintf (file, " [Unexpected!]");
285 fputc ('\n', file);
289 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
291 static asection *
292 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
294 asection *section = bfd_get_section_by_name (abfd, sec_name);
295 bfd_vma vsize;
296 bfd_size_type datasize = 0;
298 if (section == NULL
299 || coff_section_data (abfd, section) == NULL
300 || pei_section_data (abfd, section) == NULL)
301 return NULL;
302 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
303 datasize = section->size;
304 if (!datasize || vsize > addr || (vsize + datasize) < addr)
305 return NULL;
306 return section;
309 /* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
310 designate the bfd section containing the xdata, XDATA is its content,
311 and ENDX the size if known (or NULL). */
313 static void
314 pex64_dump_xdata (FILE *file, bfd *abfd,
315 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
316 struct pex64_runtime_function *rf)
318 bfd_vma vaddr;
319 bfd_vma end_addr;
320 bfd_vma addr = rf->rva_UnwindData;
321 bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
322 struct pex64_unwind_info ui;
324 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
325 addr -= vaddr;
327 /* PR 17512: file: 2245-7442-0.004. */
328 if (addr >= sec_size)
330 fprintf (file, _("warning: xdata section corrupt\n"));
331 return;
334 if (endx)
336 end_addr = endx[0] - vaddr;
337 /* PR 17512: file: 2245-7442-0.004. */
338 if (end_addr > sec_size)
340 fprintf (file, _("warning: xdata section corrupt"));
341 end_addr = sec_size;
344 else
345 end_addr = sec_size;
347 pex64_get_unwind_info (abfd, &ui, &xdata[addr]);
349 if (ui.Version != 1 && ui.Version != 2)
351 unsigned int i;
352 fprintf (file, "\tVersion %u (unknown).\n",
353 (unsigned int) ui.Version);
354 for (i = 0; addr < end_addr; addr += 1, i++)
356 if ((i & 15) == 0)
357 fprintf (file, "\t %03x:", i);
358 fprintf (file, " %02x", xdata[addr]);
359 if ((i & 15) == 15)
360 fprintf (file, "\n");
362 if ((i & 15) != 0)
363 fprintf (file, "\n");
364 return;
367 fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
368 switch (ui.Flags)
370 case UNW_FLAG_NHANDLER:
371 fprintf (file, "none");
372 break;
373 case UNW_FLAG_EHANDLER:
374 fprintf (file, "UNW_FLAG_EHANDLER");
375 break;
376 case UNW_FLAG_UHANDLER:
377 fprintf (file, "UNW_FLAG_UHANDLER");
378 break;
379 case UNW_FLAG_FHANDLER:
380 fprintf
381 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
382 break;
383 case UNW_FLAG_CHAININFO:
384 fprintf (file, "UNW_FLAG_CHAININFO");
385 break;
386 default:
387 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
388 break;
390 fputc ('\n', file);
391 fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
392 fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
393 (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
394 fprintf (file, "Frame reg: %s\n",
395 ui.FrameRegister == 0 ? "none"
396 : pex_regs[(unsigned int) ui.FrameRegister]);
398 /* PR 17512: file: 2245-7442-0.004. */
399 if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
400 fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
401 else
402 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
404 switch (ui.Flags)
406 case UNW_FLAG_EHANDLER:
407 case UNW_FLAG_UHANDLER:
408 case UNW_FLAG_FHANDLER:
409 fprintf (file, "\tHandler: ");
410 fprintf_vma (file, (ui.rva_ExceptionHandler
411 + pe_data (abfd)->pe_opthdr.ImageBase));
412 fprintf (file, ".\n");
413 break;
414 case UNW_FLAG_CHAININFO:
415 fprintf (file, "\tChain: start: ");
416 fprintf_vma (file, ui.rva_BeginAddress);
417 fprintf (file, ", end: ");
418 fprintf_vma (file, ui.rva_EndAddress);
419 fprintf (file, "\n\t unwind data: ");
420 fprintf_vma (file, ui.rva_UnwindData);
421 fprintf (file, ".\n");
422 break;
425 /* Now we need end of this xdata block. */
426 addr += ui.SizeOfBlock;
427 if (addr < end_addr)
429 unsigned int i;
430 fprintf (file,"\tUser data:\n");
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");
444 /* Helper function to sort xdata. The entries of xdata are sorted to know
445 the size of each entry. */
447 static int
448 sort_xdata_arr (const void *l, const void *r)
450 const bfd_vma *lp = (const bfd_vma *) l;
451 const bfd_vma *rp = (const bfd_vma *) r;
453 if (*lp == *rp)
454 return 0;
455 return (*lp < *rp ? -1 : 1);
458 /* Display unwind tables for x86-64. */
460 static bfd_boolean
461 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
463 FILE *file = (FILE *) vfile;
464 bfd_byte *pdata = NULL;
465 bfd_byte *xdata = NULL;
466 asection *xdata_section = NULL;
467 bfd_vma xdata_base;
468 bfd_size_type i;
469 bfd_size_type datasize;
470 bfd_size_type stop;
471 bfd_vma prev_beginaddress = (bfd_vma) -1;
472 bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
473 bfd_vma imagebase;
474 int onaline = PDATA_ROW_SIZE;
475 int seen_error = 0;
476 bfd_vma *xdata_arr = NULL;
477 int xdata_arr_cnt;
478 bfd_boolean virt_size_is_zero = FALSE;
480 /* Sanity checks. */
481 if (pdata_section == NULL
482 || coff_section_data (abfd, pdata_section) == NULL
483 || pei_section_data (abfd, pdata_section) == NULL)
484 return TRUE;
486 stop = pei_section_data (abfd, pdata_section)->virt_size;
487 if ((stop % onaline) != 0)
488 fprintf (file,
489 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
490 pdata_section->name, (long) stop, onaline);
492 datasize = pdata_section->size;
493 if (datasize == 0)
495 if (stop)
496 fprintf (file, _("Warning: %s section size is zero\n"),
497 pdata_section->name);
498 return TRUE;
501 /* virt_size might be zero for objects. */
502 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
504 stop = (datasize / onaline) * onaline;
505 virt_size_is_zero = TRUE;
507 else if (datasize < stop)
509 fprintf (file,
510 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
511 pdata_section->name, (unsigned long) datasize,
512 (unsigned long) stop);
513 /* Be sure not to read passed datasize. */
514 stop = datasize / onaline;
517 /* Display functions table. */
518 fprintf (file,
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))
525 goto done;
527 /* Table of xdata entries. */
528 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
529 xdata_arr_cnt = 0;
531 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
532 imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
533 else
534 imagebase = 0;
536 for (i = 0; i < stop; i += onaline)
538 struct pex64_runtime_function rf;
540 if (i + PDATA_ROW_SIZE > stop)
541 break;
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. */
548 break;
549 fputc (' ', file);
550 fprintf_vma (file, i + pdata_section->vma);
551 fprintf (file, ":\t");
552 fprintf_vma (file, imagebase + rf.rva_BeginAddress);
553 fprintf (file, " ");
554 fprintf_vma (file, imagebase + rf.rva_EndAddress);
555 fprintf (file, " ");
556 fprintf_vma (file, imagebase + rf.rva_UnwindData);
557 fprintf (file, "\n");
558 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
560 seen_error = 1;
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)
568 seen_error = 1;
569 fprintf (file, " has negative begin address\n");
571 if ((rf.rva_EndAddress & 0x80000000) != 0)
573 seen_error = 1;
574 fprintf (file, " has negative end address\n");
576 if ((rf.rva_UnwindData & 0x80000000) != 0)
578 seen_error = 1;
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;
586 if (seen_error)
587 goto done;
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),
595 sort_xdata_arr);
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 size_t len = strlen (pdata_section->name);
604 char *xdata_name = alloca (len + 1);
606 xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
607 /* Transform .pdata prefix into .xdata prefix. */
608 if (len > 1)
609 xdata_name [1] = 'x';
610 xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
611 xdata_name);
613 /* Second, try the .xdata section itself. */
614 if (!xdata_section)
615 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
616 /* Otherwise, if xdata_base is non zero, search also inside
617 other standard sections. */
618 if (!xdata_section && xdata_base)
619 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
620 if (!xdata_section && xdata_base)
621 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
622 if (!xdata_section && xdata_base)
623 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
624 if (!xdata_section && xdata_base)
625 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
626 /* Transfer xdata section into xdata array. */
627 if (!xdata_section
628 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
629 goto done;
631 /* Avoid "also used "... ouput for single unwind info
632 in object file. */
633 prev_unwinddata_rva = (bfd_vma) -1;
635 /* Do dump of pdata related xdata. */
636 for (i = 0; i < stop; i += onaline)
638 struct pex64_runtime_function rf;
640 if (i + PDATA_ROW_SIZE > stop)
641 break;
643 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
645 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
646 && rf.rva_UnwindData == 0)
647 /* We are probably into the padding of the section now. */
648 break;
649 if (i == 0)
650 fprintf (file, _("\nDump of %s\n"), xdata_section->name);
652 fputc (' ', file);
653 fprintf_vma (file, rf.rva_UnwindData + imagebase);
655 if (prev_unwinddata_rva == rf.rva_UnwindData)
657 /* Do not dump again the xdata for the same entry. */
658 fprintf (file, " also used for function at ");
659 fprintf_vma (file, rf.rva_BeginAddress + imagebase);
660 fputc ('\n', file);
661 continue;
663 else
664 prev_unwinddata_rva = rf.rva_UnwindData;
666 fprintf (file, " (rva: %08x): ",
667 (unsigned int) rf.rva_UnwindData);
668 fprintf_vma (file, rf.rva_BeginAddress + imagebase);
669 fprintf (file, " - ");
670 fprintf_vma (file, rf.rva_EndAddress + imagebase);
671 fputc ('\n', file);
673 if (rf.rva_UnwindData != 0 || virt_size_is_zero)
675 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
677 bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
678 bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
679 struct pex64_runtime_function arf;
681 fprintf (file, "\t shares information with ");
682 altent += imagebase;
684 if (altent >= pdata_vma
685 && (altent + PDATA_ROW_SIZE <= pdata_vma
686 + pei_section_data (abfd, pdata_section)->virt_size))
688 pex64_get_runtime_function
689 (abfd, &arf, &pdata[altent - pdata_vma]);
690 fprintf (file, "pdata element at 0x");
691 fprintf_vma (file, arf.rva_UnwindData);
693 else
694 fprintf (file, "unknown pdata element");
695 fprintf (file, ".\n");
697 else
699 bfd_vma *p;
701 /* Search for the current entry in the sorted array. */
702 p = (bfd_vma *)
703 bsearch (&rf.rva_UnwindData, xdata_arr,
704 (size_t) xdata_arr_cnt, sizeof (bfd_vma),
705 sort_xdata_arr);
707 /* Advance to the next pointer into the xdata section. We may
708 have shared xdata entries, which will result in a string of
709 identical pointers in the array; advance past all of them. */
710 while (p[0] <= rf.rva_UnwindData)
711 ++p;
713 if (p[0] == ~((bfd_vma) 0))
714 p = NULL;
716 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
721 done:
722 free (pdata);
723 free (xdata_arr);
724 free (xdata);
726 return TRUE;
729 /* Static counter of number of found pdata sections. */
730 static bfd_boolean pdata_count;
732 /* Functionn prototype. */
733 bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
735 /* Helper function for bfd_map_over_section. */
736 static void
737 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
739 if (CONST_STRNEQ (pdata->name, ".pdata"))
741 if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
742 pdata_count++;
746 bfd_boolean
747 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
749 asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
751 if (pdata_section)
752 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
754 pdata_count = 0;
755 bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
756 return (pdata_count > 0);
759 #define bfd_pe_print_pdata pex64_bfd_print_pdata
760 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
762 #include "coff-x86_64.c"