xref: /dragonfly/contrib/binutils-2.34/bfd/pei-x86_64.c (revision b52ef7118d1621abed722c5bbbd542210290ecef)
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2    Copyright (C) 2006-2020 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
pex64_get_runtime_function(bfd * abfd,struct pex64_runtime_function * rf,const void * data)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
pex64_get_unwind_info(bfd * abfd,struct pex64_unwind_info * ui,void * data,void * data_end)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
pex64_xdata_print_uwd_codes(FILE * file,bfd * abfd,struct pex64_unwind_info * ui,struct pex64_runtime_function * rf)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 *
pex64_get_section_by_rva(bfd * abfd,bfd_vma addr,const char * sec_name)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
pex64_dump_xdata(FILE * file,bfd * abfd,asection * xdata_section,bfd_byte * xdata,bfd_vma * endx,struct pex64_runtime_function * rf)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
sort_xdata_arr(const void * l,const void * r)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
pex64_bfd_print_pdata_section(bfd * abfd,void * vfile,asection * pdata_section)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_section_vma (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
pex64_print_all_pdata_sections(bfd * abfd,asection * pdata,void * obj)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
pex64_bfd_print_pdata(bfd * abfd,void * vfile)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"
857