packaging: Enable testing infrastructure
[external/binutils.git] / bfd / pei-x86_64.c
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2    Copyright (C) 2006-2019 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 bfd_boolean
102 pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui,
103                        void *data, void *data_end)
104 {
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;
109
110   memset (ui, 0, sizeof (struct pex64_unwind_info));
111
112   if (ex_dta >= ex_dta_end || ex_dta + 4 >= ex_dta_end)
113     return FALSE;
114
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;
125
126   ex_dta += ui->SizeOfBlock;
127   if (ex_dta >= ex_dta_end)
128     return FALSE;
129
130   switch (ui->Flags)
131     {
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;
150     }
151 }
152
153 /* Display unwind codes.  */
154
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)
159 {
160   unsigned int i;
161   unsigned int tmp; /* At least 32 bits.  */
162   int save_allowed;
163
164   if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
165     return;
166
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;
172
173   i = 0;
174
175   if (ui->rawUnwindCodes + 1 >= ui->rawUnwindCodesEnd)
176     {
177       fprintf (file, _("warning: corrupt unwind data\n"));
178       return;
179     }
180
181   if (ui->Version == 2
182       && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
183     {
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;
188
189       if (ui->rawUnwindCodes + 1 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
190         {
191           fprintf (file, _("warning: corrupt unwind data\n"));
192           return;
193         }
194
195       fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
196                ui->rawUnwindCodes[0]);
197
198       if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
199         fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
200
201       i++;
202       for (; i < ui->CountOfCodes; i++)
203         {
204           const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
205           unsigned int off;
206
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);
214         }
215       fputc ('\n', file);
216     }
217
218   if (ui->rawUnwindCodes + 2 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
219     {
220       fprintf (file, _("warning: corrupt unwind data\n"));
221       return;
222     }
223
224   for (; i < ui->CountOfCodes; i++)
225     {
226       const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
227       unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
228       int unexpected = FALSE;
229
230       fprintf (file, "\t  pc+0x%02x: ", (unsigned int) dta[0]);
231
232       switch (PEX64_UNWCODE_CODE (dta[1]))
233         {
234         case UWOP_PUSH_NONVOL:
235           fprintf (file, "push %s", pex_regs[info]);
236           break;
237
238         case UWOP_ALLOC_LARGE:
239           if (info == 0)
240             {
241               if (dta + 4 > ui->rawUnwindCodesEnd)
242                 {
243                   fprintf (file, _("warning: corrupt unwind data\n"));
244                   return;
245                 }
246               tmp = bfd_get_16 (abfd, dta + 2) * 8;
247               i++;
248             }
249           else
250             {
251               if (dta + 6 > ui->rawUnwindCodesEnd)
252                 {
253                   fprintf (file, _("warning: corrupt unwind data\n"));
254                   return;
255                 }
256               tmp = bfd_get_32 (abfd, dta + 2);
257               i += 2;
258             }
259           fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
260           break;
261
262         case UWOP_ALLOC_SMALL:
263           fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
264           break;
265
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;
274
275         case UWOP_SAVE_NONVOL:
276           if (dta + 4 > ui->rawUnwindCodesEnd)
277             {
278               fprintf (file, _("warning: corrupt unwind data\n"));
279               return;
280             }
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;
286
287         case UWOP_SAVE_NONVOL_FAR:
288           if (dta + 6 > ui->rawUnwindCodesEnd)
289             {
290               fprintf (file, _("warning: corrupt unwind data\n"));
291               return;
292             }
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;
298
299         case UWOP_SAVE_XMM:
300           if (ui->Version == 1)
301             {
302               if (dta + 4 > ui->rawUnwindCodesEnd)
303                 {
304                   fprintf (file, _("warning: corrupt unwind data\n"));
305                   return;
306                 }
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;
311             }
312           else if (ui->Version == 2)
313             {
314               fprintf (file, "epilog %02x %01x", dta[0], info);
315               unexpected = TRUE;
316             }
317           break;
318
319         case UWOP_SAVE_XMM_FAR:
320           if (dta + 6 > ui->rawUnwindCodesEnd)
321             {
322               fprintf (file, _("warning: corrupt unwind data\n"));
323               return;
324             }
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;
330
331         case UWOP_SAVE_XMM128:
332           if (dta + 4 > ui->rawUnwindCodesEnd)
333             {
334               fprintf (file, _("warning: corrupt unwind data\n"));
335               return;
336             }
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;
342
343         case UWOP_SAVE_XMM128_FAR:
344           if (dta + 6 > ui->rawUnwindCodesEnd)
345             {
346               fprintf (file, _("warning: corrupt unwind data\n"));
347               return;
348             }
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;
354
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;
364
365         default:
366           /* PR 17512: file: 2245-7442-0.004.  */
367           fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
368           break;
369         }
370
371       if (unexpected)
372         fprintf (file, " [Unexpected!]");
373       fputc ('\n', file);
374     }
375 }
376
377 /* Check wether section SEC_NAME contains the xdata at address ADDR.  */
378
379 static asection *
380 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
381 {
382   asection *section = bfd_get_section_by_name (abfd, sec_name);
383   bfd_vma vsize;
384   bfd_size_type datasize = 0;
385
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;
395 }
396
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).  */
400
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)
405 {
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;
411
412   vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
413   addr -= vaddr;
414
415   /* PR 17512: file: 2245-7442-0.004.  */
416   if (addr >= sec_size)
417     {
418       fprintf (file, _("warning: xdata section corrupt\n"));
419       return;
420     }
421
422   if (endx)
423     {
424       end_addr = endx[0] - vaddr;
425       /* PR 17512: file: 2245-7442-0.004.  */
426       if (end_addr > sec_size)
427         {
428           fprintf (file, _("warning: xdata section corrupt\n"));
429           end_addr = sec_size;
430         }
431     }
432   else
433     end_addr = sec_size;
434
435   if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
436     {
437       fprintf (file, _("warning: xdata section corrupt\n"));
438       return;
439     }
440
441   if (ui.Version != 1 && ui.Version != 2)
442     {
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++)
447         {
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");
453         }
454       if ((i & 15) != 0)
455         fprintf (file, "\n");
456       return;
457     }
458
459   fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
460   switch (ui.Flags)
461     {
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;
481     }
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]);
489
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);
495
496   switch (ui.Flags)
497     {
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;
515     }
516
517   /* Now we need end of this xdata block.  */
518   addr += ui.SizeOfBlock;
519   if (addr < end_addr)
520     {
521       unsigned int i;
522       fprintf (file,"\tUser data:\n");
523       for (i = 0; addr < end_addr; addr += 1, i++)
524         {
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");
530         }
531       if ((i & 15) != 0)
532         fprintf (file, "\n");
533     }
534 }
535
536 /* Helper function to sort xdata.  The entries of xdata are sorted to know
537    the size of each entry.  */
538
539 static int
540 sort_xdata_arr (const void *l, const void *r)
541 {
542   const bfd_vma *lp = (const bfd_vma *) l;
543   const bfd_vma *rp = (const bfd_vma *) r;
544
545   if (*lp == *rp)
546     return 0;
547   return (*lp < *rp ? -1 : 1);
548 }
549
550 /* Display unwind tables for x86-64.  */
551
552 static bfd_boolean
553 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
554 {
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   bfd_boolean virt_size_is_zero = FALSE;
571
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;
577
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);
584
585   datasize = pdata_section->size;
586   if (datasize == 0)
587     {
588       if (stop)
589         fprintf (file, _("Warning: %s section size is zero\n"),
590                  pdata_section->name);
591       return TRUE;
592     }
593
594   /* virt_size might be zero for objects.  */
595   if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
596     {
597       stop = datasize;
598       virt_size_is_zero = TRUE;
599     }
600   else if (datasize < stop)
601       {
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;
609       }
610
611   /* Display functions table.  */
612   fprintf (file,
613            _("\nThe Function Table (interpreted %s section contents)\n"),
614            pdata_section->name);
615
616   fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
617
618   if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
619     goto done;
620
621   /* Table of xdata entries.  */
622   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
623   xdata_arr_cnt = 0;
624
625   if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
626     imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
627   else
628     imagebase = 0;
629
630   for (i = 0; i < stop; i += onaline)
631     {
632       struct pex64_runtime_function rf;
633
634       if (i + PDATA_ROW_SIZE > stop)
635         break;
636
637       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
638
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)
653         {
654           seen_error = 1;
655           fprintf (file, "  has %s begin address as predecessor\n",
656             (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
657         }
658       prev_beginaddress = rf.rva_BeginAddress;
659       /* Now we check for negative addresses.  */
660       if ((prev_beginaddress & 0x80000000) != 0)
661         {
662           seen_error = 1;
663           fprintf (file, "  has negative begin address\n");
664         }
665       if ((rf.rva_EndAddress & 0x80000000) != 0)
666         {
667           seen_error = 1;
668           fprintf (file, "  has negative end address\n");
669         }
670       if ((rf.rva_UnwindData & 0x80000000) != 0)
671         {
672           seen_error = 1;
673           fprintf (file, "  has negative unwind address\n");
674         }
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;
678     }
679
680   if (seen_error)
681     goto done;
682
683   /* Add end of list marker.  */
684   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
685
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);
690
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)
696     {
697       size_t len = strlen (pdata_section->name);
698       char *xdata_name = xmalloc (len + 1);
699
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);
707     }
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;
725
726   /* Avoid "also used "... ouput for single unwind info
727      in object file.  */
728   prev_unwinddata_rva = (bfd_vma) -1;
729
730   /* Do dump of pdata related xdata.  */
731   for (i = 0; i < stop; i += onaline)
732     {
733       struct pex64_runtime_function rf;
734
735       if (i + PDATA_ROW_SIZE > stop)
736         break;
737
738       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
739
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);
746
747       fputc (' ', file);
748       fprintf_vma (file, rf.rva_UnwindData + imagebase);
749
750       if (prev_unwinddata_rva == rf.rva_UnwindData)
751         {
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;
757         }
758       else
759         prev_unwinddata_rva = rf.rva_UnwindData;
760
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);
767
768       if (rf.rva_UnwindData != 0 || virt_size_is_zero)
769         {
770           if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
771             {
772               bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
773               bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
774               struct pex64_runtime_function arf;
775
776               fprintf (file, "\t shares information with ");
777               altent += imagebase;
778
779               if (altent >= pdata_vma
780                   && altent - pdata_vma + PDATA_ROW_SIZE <= stop)
781                 {
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);
786                 }
787               else
788                 fprintf (file, "unknown pdata element");
789               fprintf (file, ".\n");
790             }
791           else
792             {
793               bfd_vma *p;
794
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);
800
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;
806
807               if (p[0] == ~((bfd_vma) 0))
808                 p = NULL;
809
810               pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
811             }
812         }
813     }
814
815  done:
816   free (pdata);
817   free (xdata_arr);
818   free (xdata);
819
820   return TRUE;
821 }
822
823 /* Static counter of number of found pdata sections.  */
824 static bfd_boolean pdata_count;
825
826 /* Functionn prototype.  */
827 bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
828
829 /* Helper function for bfd_map_over_section.  */
830 static void
831 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
832 {
833   if (CONST_STRNEQ (pdata->name, ".pdata"))
834     {
835       if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
836         pdata_count++;
837     }
838 }
839
840 bfd_boolean
841 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
842 {
843   asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
844
845   if (pdata_section)
846     return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
847
848   pdata_count = 0;
849   bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
850   return (pdata_count > 0);
851 }
852
853 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
854 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
855
856 #include "coff-x86_64.c"