Fixes for memory access violations exposed by fuzzinf various binaries.
[external/binutils.git] / bfd / pei-x86_64.c
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2    Copyright (C) 2006-2014 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
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.
10
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.
15
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.
20
21    Written by Kai Tietz, OneVision Software GmbH&CoKg.  */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25
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)
42
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 }
60
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"
74
75 #undef AOUTSZ
76 #define AOUTSZ          PEPAOUTSZ
77 #define PEAOUTHDR       PEPAOUTHDR
78
79 /* Name of registers according to SEH conventions.  */
80
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"
84 };
85
86 /* Swap in a runtime function.  */
87
88 static void
89 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
90                             const void *data)
91 {
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);
97 }
98
99 /* Swap in unwind info header.  */
100
101 static void
102 pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
103 {
104   struct external_pex64_unwind_info *ex_ui =
105     (struct external_pex64_unwind_info *) data;
106   bfd_byte *ex_dta = (bfd_byte *) data;
107
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)
120     {
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;
135     }
136 }
137
138 /* Display unwind codes.  */
139
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)
144 {
145   unsigned int i;
146   unsigned int tmp; /* At least 32 bits.  */
147   int save_allowed;
148
149   if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
150     return;
151
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;
157
158   i = 0;
159
160   if (ui->Version == 2
161       && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
162     {
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;
167
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++)
174         {
175           const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
176           unsigned int off;
177
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);
185         }
186       fputc ('\n', file);
187     }
188
189   for (; i < ui->CountOfCodes; i++)
190     {
191       const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
192       unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
193       int unexpected = FALSE;
194
195       fprintf (file, "\t  pc+0x%02x: ", (unsigned int) dta[0]);
196       switch (PEX64_UNWCODE_CODE (dta[1]))
197         {
198         case UWOP_PUSH_NONVOL:
199           fprintf (file, "push %s", pex_regs[info]);
200           break;
201         case UWOP_ALLOC_LARGE:
202           if (info == 0)
203             {
204               tmp = bfd_get_16 (abfd, &dta[2]) * 8;
205               i++;
206             }
207           else
208             {
209               tmp = bfd_get_32 (abfd, &dta[2]);
210               i += 2;
211             }
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)
239             {
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;
244             }
245           else if (ui->Version == 2)
246             {
247               fprintf (file, "epilog %02x %01x", dta[0], info);
248               unexpected = TRUE;
249             }
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;
282       }
283       if (unexpected)
284         fprintf (file, " [Unexpected!]");
285       fputc ('\n', file);
286     }
287 }
288
289 /* Check wether section SEC_NAME contains the xdata at address ADDR.  */
290
291 static asection *
292 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
293 {
294   asection *section = bfd_get_section_by_name (abfd, sec_name);
295   bfd_vma vsize;
296   bfd_size_type datasize = 0;
297
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;
307 }
308
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).  */
312
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)
317 {
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;
323
324   vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
325   addr -= vaddr;
326
327   /* PR 17512: file: 2245-7442-0.004.  */
328   if (addr >= sec_size)
329     {
330       fprintf (file, _("warning: xdata section corrupt\n"));
331       return;
332     }
333
334   if (endx)
335     {
336       end_addr = endx[0] - vaddr;
337       /* PR 17512: file: 2245-7442-0.004.  */
338       if (end_addr > sec_size)
339         {
340           fprintf (file, _("warning: xdata section corrupt"));
341           end_addr = sec_size;
342         }
343     }
344   else
345     end_addr = sec_size;
346
347   pex64_get_unwind_info (abfd, &ui, &xdata[addr]);
348   
349   if (ui.Version != 1 && ui.Version != 2)
350     {
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++)
355         {
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");
361         }
362       if ((i & 15) != 0)
363         fprintf (file, "\n");
364       return;
365     }
366
367   fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
368   switch (ui.Flags)
369     {
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;
389     }
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]);
397
398   /* PR 17512: file: 2245-7442-0.004.  */
399   if (ui.CountOfCodes * 2 + ui.rawUnwindCodes + addr >= 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);
403
404   switch (ui.Flags)
405     {
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;
423     }
424
425   /* Now we need end of this xdata block.  */
426   addr += ui.SizeOfBlock;
427   if (addr < end_addr)
428     {
429       unsigned int i;
430       fprintf (file,"\tUser data:\n");
431       for (i = 0; addr < end_addr; addr += 1, i++)
432         {
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");
438         }
439       if ((i & 15) != 0)
440         fprintf (file, "\n");
441     }
442 }
443
444 /* Helper function to sort xdata.  The entries of xdata are sorted to know
445    the size of each entry.  */
446
447 static int
448 sort_xdata_arr (const void *l, const void *r)
449 {
450   const bfd_vma *lp = (const bfd_vma *) l;
451   const bfd_vma *rp = (const bfd_vma *) r;
452
453   if (*lp == *rp)
454     return 0;
455   return (*lp < *rp ? -1 : 1);
456 }
457
458 /* Display unwind tables for x86-64.  */
459
460 static bfd_boolean
461 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
462 {
463   FILE *file = (FILE *) vfile;
464   bfd_byte *pdata = NULL;
465   bfd_byte *xdata = NULL;
466   asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
467   asection *xdata_section;
468   bfd_vma xdata_base;
469   bfd_size_type i;
470   bfd_size_type stop;
471   bfd_vma prev_beginaddress = 0;
472   bfd_vma prev_unwinddata_rva = 0;
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
479   /* Sanity checks.  */
480   if (pdata_section == NULL
481       || coff_section_data (abfd, pdata_section) == NULL
482       || pei_section_data (abfd, pdata_section) == NULL)
483     return TRUE;
484
485   stop = pei_section_data (abfd, pdata_section)->virt_size;
486   /* PR 17512: file: 005-181405-0.004.  */
487   if (stop == 0 || pdata_section->size == 0)
488     {
489       fprintf (file, _("No unwind data in .pdata section\n"));
490       return TRUE;
491     }
492   if ((stop % onaline) != 0)
493     fprintf (file,
494              _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
495              (long) stop, onaline);
496
497   /* Display functions table.  */
498   fprintf (file,
499            _("\nThe Function Table (interpreted .pdata section contents)\n"));
500
501   fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
502
503   if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
504     goto done;
505
506   /* Table of xdata entries.  */
507   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
508   xdata_arr_cnt = 0;
509
510   imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
511
512   for (i = 0; i < stop; i += onaline)
513     {
514       struct pex64_runtime_function rf;
515
516       if (i + PDATA_ROW_SIZE > stop)
517         break;
518
519       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
520
521       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
522           && rf.rva_UnwindData == 0)
523         /* We are probably into the padding of the section now.  */
524         break;
525       fputc (' ', file);
526       fprintf_vma (file, i + pdata_section->vma);
527       fprintf (file, ":\t");
528       fprintf_vma (file, imagebase + rf.rva_BeginAddress);
529       fprintf (file, " ");
530       fprintf_vma (file, imagebase + rf.rva_EndAddress);
531       fprintf (file, " ");
532       fprintf_vma (file, imagebase + rf.rva_UnwindData);
533       fprintf (file, "\n");
534       if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
535         {
536           seen_error = 1;
537           fprintf (file, "  has %s begin address as predecessor\n",
538             (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
539         }
540       prev_beginaddress = rf.rva_BeginAddress;
541       /* Now we check for negative addresses.  */
542       if ((prev_beginaddress & 0x80000000) != 0)
543         {
544           seen_error = 1;
545           fprintf (file, "  has negative begin address\n");
546         }
547       if ((rf.rva_EndAddress & 0x80000000) != 0)
548         {
549           seen_error = 1;
550           fprintf (file, "  has negative end address\n");
551         }
552       if ((rf.rva_UnwindData & 0x80000000) != 0)
553         {
554           seen_error = 1;
555           fprintf (file, "  has negative unwind address\n");
556         }
557       if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
558         xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
559     }
560
561   if (seen_error)
562     goto done;
563
564   /* Add end of list marker.  */
565   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
566
567   /* Sort start RVAs of xdata.  */
568   if (xdata_arr_cnt > 1)
569     qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
570            sort_xdata_arr);
571
572   /* Find the section containing the unwind data (.xdata).  */
573   xdata_base = xdata_arr[0];
574   xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
575
576   if (!xdata_section)
577     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
578   if (!xdata_section)
579     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
580   if (!xdata_section)
581     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
582   if (!xdata_section)
583     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
584   if (!xdata_section
585       || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
586     goto done;
587
588   /* Do dump of pdata related xdata.  */
589   for (i = 0; i < stop; i += onaline)
590     {
591       struct pex64_runtime_function rf;
592
593       if (i + PDATA_ROW_SIZE > stop)
594         break;
595
596       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
597
598       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
599           && rf.rva_UnwindData == 0)
600         /* We are probably into the padding of the section now.  */
601         break;
602       if (i == 0)
603         fprintf (file, "\nDump of .xdata\n");
604
605       fputc (' ', file);
606       fprintf_vma (file, rf.rva_UnwindData + imagebase);
607
608       if (prev_unwinddata_rva == rf.rva_UnwindData)
609         {
610           /* Do not dump again the xdata for the same entry.  */
611           fprintf (file, " also used for function at ");
612           fprintf_vma (file, rf.rva_BeginAddress + imagebase);
613           fputc ('\n', file);
614           continue;
615         }
616       else
617         prev_unwinddata_rva = rf.rva_UnwindData;
618
619       fprintf (file, " (rva: %08x): ",
620                (unsigned int) rf.rva_UnwindData);
621       fprintf_vma (file, rf.rva_BeginAddress + imagebase);
622       fprintf (file, " - ");
623       fprintf_vma (file, rf.rva_EndAddress + imagebase);
624       fputc ('\n', file);
625
626       if (rf.rva_UnwindData != 0)
627         {
628           if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
629             {
630               bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
631               bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
632               struct pex64_runtime_function arf;
633
634               fprintf (file, "\t shares information with ");
635               altent += imagebase;
636
637               if (altent >= pdata_vma
638                   && (altent + PDATA_ROW_SIZE <= pdata_vma
639                       + pei_section_data (abfd, pdata_section)->virt_size))
640                 {
641                   pex64_get_runtime_function
642                     (abfd, &arf, &pdata[altent - pdata_vma]);
643                   fprintf (file, "pdata element at 0x");
644                   fprintf_vma (file, arf.rva_UnwindData);
645                 }
646               else
647                 fprintf (file, "unknown pdata element");
648               fprintf (file, ".\n");
649             }
650           else
651             {
652               bfd_vma *p;
653
654               /* Search for the current entry in the sorted array.  */
655               p = (bfd_vma *)
656                   bsearch (&rf.rva_UnwindData, xdata_arr,
657                            (size_t) xdata_arr_cnt, sizeof (bfd_vma),
658                            sort_xdata_arr);
659
660               /* Advance to the next pointer into the xdata section.  We may
661                  have shared xdata entries, which will result in a string of
662                  identical pointers in the array; advance past all of them.  */
663               while (p[0] <= rf.rva_UnwindData)
664                 ++p;
665
666               if (p[0] == ~((bfd_vma) 0))
667                 p = NULL;
668
669               pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
670             }
671         }
672     }
673
674  done:
675   free (pdata);
676   free (xdata_arr);
677   free (xdata);
678
679   return TRUE;
680 }
681
682 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
683
684 #include "coff-x86_64.c"