xref: /netbsd-src/external/gpl3/gdb/dist/bfd/pei-x86_64.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2    Copyright (C) 2006-2022 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 bool
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_end - ex_dta < 4)
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   if ((size_t) (ex_dta_end - ex_dta) < ui->SizeOfBlock)
127     return false;
128   ex_dta += ui->SizeOfBlock;
129 
130   switch (ui->Flags)
131     {
132     case UNW_FLAG_CHAININFO:
133       if (ex_dta_end - ex_dta < 12)
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_end - ex_dta < 4)
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 ((size_t) (ui->rawUnwindCodesEnd - ui->rawUnwindCodes)
176       < ui->CountOfCodes * 2)
177     {
178       fprintf (file, _("warning: corrupt unwind data\n"));
179       return;
180     }
181 
182   if (ui->Version == 2
183       && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
184     {
185       /* Display epilog opcode (whose docoding is not fully documented).
186 	 Looks to be designed to speed-up unwinding, as there is no need
187 	 to decode instruction flow if outside an epilog.  */
188       unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
189 
190       fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
191 	       ui->rawUnwindCodes[0]);
192 
193       if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
194 	fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
195 
196       i++;
197       for (; i < ui->CountOfCodes; i++)
198 	{
199 	  const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
200 	  unsigned int off;
201 
202 	  if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
203 	    break;
204 	  off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
205 	  if (off == 0)
206 	    fprintf (file, " [pad]");
207 	  else
208 	    fprintf (file, " 0x%x", func_size - off);
209 	}
210       fputc ('\n', file);
211     }
212 
213   for (; i < ui->CountOfCodes; i++)
214     {
215       const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
216       unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
217       int unexpected = false;
218 
219       fprintf (file, "\t  pc+0x%02x: ", (unsigned int) dta[0]);
220 
221       switch (PEX64_UNWCODE_CODE (dta[1]))
222 	{
223 	case UWOP_PUSH_NONVOL:
224 	  fprintf (file, "push %s", pex_regs[info]);
225 	  break;
226 
227 	case UWOP_ALLOC_LARGE:
228 	  if (info == 0)
229 	    {
230 	      if (ui->rawUnwindCodesEnd - dta < 4)
231 		{
232 		  fprintf (file, _("warning: corrupt unwind data\n"));
233 		  return;
234 		}
235 	      tmp = bfd_get_16 (abfd, dta + 2) * 8;
236 	      i++;
237 	    }
238 	  else
239 	    {
240 	      if (ui->rawUnwindCodesEnd - dta < 6)
241 		{
242 		  fprintf (file, _("warning: corrupt unwind data\n"));
243 		  return;
244 		}
245 	      tmp = bfd_get_32 (abfd, dta + 2);
246 	      i += 2;
247 	    }
248 	  fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
249 	  break;
250 
251 	case UWOP_ALLOC_SMALL:
252 	  fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
253 	  break;
254 
255 	case UWOP_SET_FPREG:
256 	  /* According to the documentation, info field is unused.  */
257 	  fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
258 		   pex_regs[ui->FrameRegister],
259 		   (unsigned int) ui->FrameOffset * 16, info);
260 	  unexpected = ui->FrameRegister == 0;
261 	  save_allowed = false;
262 	  break;
263 
264 	case UWOP_SAVE_NONVOL:
265 	  if (ui->rawUnwindCodesEnd - dta < 4)
266 	    {
267 	      fprintf (file, _("warning: corrupt unwind data\n"));
268 	      return;
269 	    }
270 	  tmp = bfd_get_16 (abfd, dta + 2) * 8;
271 	  i++;
272 	  fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
273 	  unexpected = !save_allowed;
274 	  break;
275 
276 	case UWOP_SAVE_NONVOL_FAR:
277 	  if (ui->rawUnwindCodesEnd - dta < 6)
278 	    {
279 	      fprintf (file, _("warning: corrupt unwind data\n"));
280 	      return;
281 	    }
282 	  tmp = bfd_get_32 (abfd, dta + 2);
283 	  i += 2;
284 	  fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
285 	  unexpected = !save_allowed;
286 	  break;
287 
288 	case UWOP_SAVE_XMM:
289 	  if (ui->Version == 1)
290 	    {
291 	      if (ui->rawUnwindCodesEnd - dta < 4)
292 		{
293 		  fprintf (file, _("warning: corrupt unwind data\n"));
294 		  return;
295 		}
296 	      tmp = bfd_get_16 (abfd, dta + 2) * 8;
297 	      i++;
298 	      fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
299 	      unexpected = !save_allowed;
300 	    }
301 	  else if (ui->Version == 2)
302 	    {
303 	      fprintf (file, "epilog %02x %01x", dta[0], info);
304 	      unexpected = true;
305 	    }
306 	  break;
307 
308 	case UWOP_SAVE_XMM_FAR:
309 	  if (ui->rawUnwindCodesEnd - dta < 6)
310 	    {
311 	      fprintf (file, _("warning: corrupt unwind data\n"));
312 	      return;
313 	    }
314 	  tmp = bfd_get_32 (abfd, dta + 2) * 8;
315 	  i += 2;
316 	  fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
317 	  unexpected = !save_allowed;
318 	  break;
319 
320 	case UWOP_SAVE_XMM128:
321 	  if (ui->rawUnwindCodesEnd - dta < 4)
322 	    {
323 	      fprintf (file, _("warning: corrupt unwind data\n"));
324 	      return;
325 	    }
326 	  tmp = bfd_get_16 (abfd, dta + 2) * 16;
327 	  i++;
328 	  fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
329 	  unexpected = !save_allowed;
330 	  break;
331 
332 	case UWOP_SAVE_XMM128_FAR:
333 	  if (ui->rawUnwindCodesEnd - dta < 6)
334 	    {
335 	      fprintf (file, _("warning: corrupt unwind data\n"));
336 	      return;
337 	    }
338 	  tmp = bfd_get_32 (abfd, dta + 2) * 16;
339 	  i += 2;
340 	  fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
341 	  unexpected = !save_allowed;
342 	  break;
343 
344 	case UWOP_PUSH_MACHFRAME:
345 	  fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
346 	  if (info == 0)
347 	    fprintf (file, ")");
348 	  else if (info == 1)
349 	    fprintf (file, ",ErrorCode)");
350 	  else
351 	    fprintf (file, ", unknown(%u))", info);
352 	  break;
353 
354 	default:
355 	  /* PR 17512: file: 2245-7442-0.004.  */
356 	  fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
357 	  break;
358 	}
359 
360       if (unexpected)
361 	fprintf (file, " [Unexpected!]");
362       fputc ('\n', file);
363     }
364 }
365 
366 /* Check wether section SEC_NAME contains the xdata at address ADDR.  */
367 
368 static asection *
369 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
370 {
371   asection *section = bfd_get_section_by_name (abfd, sec_name);
372   bfd_vma vsize;
373   bfd_size_type datasize = 0;
374 
375   if (section == NULL
376       || coff_section_data (abfd, section) == NULL
377       || pei_section_data (abfd, section) == NULL)
378     return NULL;
379   vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
380   datasize = section->size;
381   if (!datasize || vsize > addr || (vsize + datasize) < addr)
382     return NULL;
383   return section;
384 }
385 
386 /* Dump xdata at for function RF to FILE.  The argument XDATA_SECTION
387    designate the bfd section containing the xdata, XDATA is its content,
388    and ENDX the size if known (or NULL).  */
389 
390 static void
391 pex64_dump_xdata (FILE *file, bfd *abfd,
392 		  asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
393 		  struct pex64_runtime_function *rf)
394 {
395   bfd_vma vaddr;
396   bfd_vma end_addr;
397   bfd_vma addr = rf->rva_UnwindData;
398   bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
399   struct pex64_unwind_info ui;
400 
401   vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
402   addr -= vaddr;
403 
404   /* PR 17512: file: 2245-7442-0.004.  */
405   if (addr >= sec_size)
406     {
407       fprintf (file, _("warning: xdata section corrupt\n"));
408       return;
409     }
410 
411   if (endx)
412     {
413       end_addr = endx[0] - vaddr;
414       /* PR 17512: file: 2245-7442-0.004.  */
415       if (end_addr > sec_size)
416 	{
417 	  fprintf (file, _("warning: xdata section corrupt\n"));
418 	  end_addr = sec_size;
419 	}
420     }
421   else
422     end_addr = sec_size;
423 
424   if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
425     {
426       fprintf (file, _("warning: xdata section corrupt\n"));
427       return;
428     }
429 
430   if (ui.Version != 1 && ui.Version != 2)
431     {
432       unsigned int i;
433       fprintf (file, "\tVersion %u (unknown).\n",
434 	       (unsigned int) ui.Version);
435       for (i = 0; addr < end_addr; addr += 1, i++)
436 	{
437 	  if ((i & 15) == 0)
438 	    fprintf (file, "\t  %03x:", i);
439 	  fprintf (file, " %02x", xdata[addr]);
440 	  if ((i & 15) == 15)
441 	    fprintf (file, "\n");
442 	}
443       if ((i & 15) != 0)
444 	fprintf (file, "\n");
445       return;
446     }
447 
448   fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
449   switch (ui.Flags)
450     {
451     case UNW_FLAG_NHANDLER:
452       fprintf (file, "none");
453       break;
454     case UNW_FLAG_EHANDLER:
455       fprintf (file, "UNW_FLAG_EHANDLER");
456       break;
457     case UNW_FLAG_UHANDLER:
458       fprintf (file, "UNW_FLAG_UHANDLER");
459       break;
460     case UNW_FLAG_FHANDLER:
461       fprintf
462 	(file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
463       break;
464     case UNW_FLAG_CHAININFO:
465       fprintf (file, "UNW_FLAG_CHAININFO");
466       break;
467     default:
468       fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
469       break;
470     }
471   fputc ('\n', file);
472   fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
473   fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
474 	   (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
475   fprintf (file, "Frame reg: %s\n",
476 	   ui.FrameRegister == 0 ? "none"
477 	   : pex_regs[(unsigned int) ui.FrameRegister]);
478 
479   /* PR 17512: file: 2245-7442-0.004.  */
480   if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
481     fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
482   else
483     pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
484 
485   switch (ui.Flags)
486     {
487     case UNW_FLAG_EHANDLER:
488     case UNW_FLAG_UHANDLER:
489     case UNW_FLAG_FHANDLER:
490       fprintf (file, "\tHandler: %016" PRIx64 ".\n",
491 	       ui.rva_ExceptionHandler + pe_data (abfd)->pe_opthdr.ImageBase);
492       break;
493     case UNW_FLAG_CHAININFO:
494       fprintf (file, "\tChain: start: %016" PRIx64 ", end: %016" PRIx64,
495 	       ui.rva_BeginAddress, ui.rva_EndAddress);
496       fprintf (file, "\n\t unwind data: %016" PRIx64 ".\n",
497 	       ui.rva_UnwindData);
498       break;
499     }
500 
501   /* Now we need end of this xdata block.  */
502   addr += ui.SizeOfBlock;
503   if (addr < end_addr)
504     {
505       unsigned int i;
506       fprintf (file,"\tUser data:\n");
507       for (i = 0; addr < end_addr; addr += 1, i++)
508 	{
509 	  if ((i & 15) == 0)
510 	    fprintf (file, "\t  %03x:", i);
511 	  fprintf (file, " %02x", xdata[addr]);
512 	  if ((i & 15) == 15)
513 	    fprintf (file, "\n");
514 	}
515       if ((i & 15) != 0)
516 	fprintf (file, "\n");
517     }
518 }
519 
520 /* Helper function to sort xdata.  The entries of xdata are sorted to know
521    the size of each entry.  */
522 
523 static int
524 sort_xdata_arr (const void *l, const void *r)
525 {
526   const bfd_vma *lp = (const bfd_vma *) l;
527   const bfd_vma *rp = (const bfd_vma *) r;
528 
529   if (*lp == *rp)
530     return 0;
531   return (*lp < *rp ? -1 : 1);
532 }
533 
534 /* Display unwind tables for x86-64.  */
535 
536 static bool
537 pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
538 {
539   FILE *file = (FILE *) vfile;
540   bfd_byte *pdata = NULL;
541   bfd_byte *xdata = NULL;
542   asection *xdata_section = NULL;
543   bfd_vma xdata_base;
544   bfd_size_type i;
545   bfd_size_type datasize;
546   bfd_size_type stop;
547   bfd_vma prev_beginaddress = (bfd_vma) -1;
548   bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
549   bfd_vma imagebase;
550   int onaline = PDATA_ROW_SIZE;
551   int seen_error = 0;
552   bfd_vma *xdata_arr = NULL;
553   int xdata_arr_cnt;
554   bool virt_size_is_zero = false;
555 
556   /* Sanity checks.  */
557   if (pdata_section == NULL
558       || coff_section_data (abfd, pdata_section) == NULL
559       || pei_section_data (abfd, pdata_section) == NULL)
560     return true;
561 
562   stop = pei_section_data (abfd, pdata_section)->virt_size;
563   if ((stop % onaline) != 0)
564     fprintf (file,
565 	     /* xgettext:c-format */
566 	     _("Warning: %s section size (%ld) is not a multiple of %d\n"),
567 	     pdata_section->name, (long) stop, onaline);
568 
569   datasize = pdata_section->size;
570   if (datasize == 0)
571     {
572       if (stop)
573 	fprintf (file, _("Warning: %s section size is zero\n"),
574 		 pdata_section->name);
575       return true;
576     }
577 
578   /* virt_size might be zero for objects.  */
579   if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
580     {
581       stop = datasize;
582       virt_size_is_zero = true;
583     }
584   else if (datasize < stop)
585       {
586 	fprintf (file,
587 		 /* xgettext:c-format */
588 		 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
589 		 pdata_section->name, (unsigned long) datasize,
590 		 (unsigned long) stop);
591 	/* Be sure not to read past datasize.  */
592 	stop = datasize;
593       }
594 
595   /* Display functions table.  */
596   fprintf (file,
597 	   _("\nThe Function Table (interpreted %s section contents)\n"),
598 	   pdata_section->name);
599 
600   fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
601 
602   if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
603     goto done;
604 
605   /* Table of xdata entries.  */
606   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
607   xdata_arr_cnt = 0;
608 
609   if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
610     imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
611   else
612     imagebase = 0;
613 
614   for (i = 0; i < stop; i += onaline)
615     {
616       struct pex64_runtime_function rf;
617 
618       if (i + PDATA_ROW_SIZE > stop)
619 	break;
620 
621       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
622 
623       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
624 	  && rf.rva_UnwindData == 0)
625 	/* We are probably into the padding of the section now.  */
626 	break;
627       fprintf (file, " %016" PRIx64, i + pdata_section->vma);
628       fprintf (file, ":\t%016" PRIx64, imagebase + rf.rva_BeginAddress);
629       fprintf (file, " %016" PRIx64, imagebase + rf.rva_EndAddress);
630       fprintf (file, " %016" PRIx64 "\n", imagebase + rf.rva_UnwindData);
631       if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
632 	{
633 	  seen_error = 1;
634 	  fprintf (file, "  has %s begin address as predecessor\n",
635 	    (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
636 	}
637       prev_beginaddress = rf.rva_BeginAddress;
638       /* Now we check for negative addresses.  */
639       if ((prev_beginaddress & 0x80000000) != 0)
640 	{
641 	  seen_error = 1;
642 	  fprintf (file, "  has negative begin address\n");
643 	}
644       if ((rf.rva_EndAddress & 0x80000000) != 0)
645 	{
646 	  seen_error = 1;
647 	  fprintf (file, "  has negative end address\n");
648 	}
649       if ((rf.rva_UnwindData & 0x80000000) != 0)
650 	{
651 	  seen_error = 1;
652 	  fprintf (file, "  has negative unwind address\n");
653 	}
654       else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
655 		|| virt_size_is_zero)
656 	xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
657     }
658 
659   if (seen_error)
660     goto done;
661 
662   /* Add end of list marker.  */
663   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
664 
665   /* Sort start RVAs of xdata.  */
666   if (xdata_arr_cnt > 1)
667     qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
668 	   sort_xdata_arr);
669 
670   /* Find the section containing the unwind data (.xdata).  */
671   xdata_base = xdata_arr[0];
672   /* For sections with long names, first look for the same
673      section name, replacing .pdata by .xdata prefix.  */
674   if (strcmp (pdata_section->name, ".pdata") != 0)
675     {
676       size_t len = strlen (pdata_section->name);
677       char *xdata_name = xmalloc (len + 1);
678 
679       xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
680       /* Transform .pdata prefix into .xdata prefix.  */
681       if (len > 1)
682 	xdata_name [1] = 'x';
683       xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
684 						xdata_name);
685       free (xdata_name);
686     }
687   /* Second, try the .xdata section itself.  */
688   if (!xdata_section)
689     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
690   /* Otherwise, if xdata_base is non zero, search also inside
691      other standard sections.  */
692   if (!xdata_section && xdata_base)
693     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
694   if (!xdata_section && xdata_base)
695     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
696   if (!xdata_section && xdata_base)
697     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
698   if (!xdata_section && xdata_base)
699     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
700   /* Transfer xdata section into xdata array.  */
701   if (!xdata_section
702       || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
703     goto done;
704 
705   /* Avoid "also used "... ouput for single unwind info
706      in object file.  */
707   prev_unwinddata_rva = (bfd_vma) -1;
708 
709   /* Do dump of pdata related xdata.  */
710   for (i = 0; i < stop; i += onaline)
711     {
712       struct pex64_runtime_function rf;
713 
714       if (i + PDATA_ROW_SIZE > stop)
715 	break;
716 
717       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
718 
719       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
720 	  && rf.rva_UnwindData == 0)
721 	/* We are probably into the padding of the section now.  */
722 	break;
723       if (i == 0)
724 	fprintf (file, _("\nDump of %s\n"), xdata_section->name);
725 
726       fprintf (file, " %016" PRIx64, rf.rva_UnwindData + imagebase);
727 
728       if (prev_unwinddata_rva == rf.rva_UnwindData)
729 	{
730 	  /* Do not dump again the xdata for the same entry.  */
731 	  fprintf (file, " also used for function at %016" PRIx64 "\n",
732 		   rf.rva_BeginAddress + imagebase);
733 	  continue;
734 	}
735       else
736 	prev_unwinddata_rva = rf.rva_UnwindData;
737 
738       fprintf (file, " (rva: %08x): %016" PRIx64 " - %016" PRIx64 "\n",
739 	       (unsigned int) rf.rva_UnwindData,
740 	       rf.rva_BeginAddress + imagebase,
741 	       rf.rva_EndAddress + imagebase);
742 
743       if (rf.rva_UnwindData != 0 || virt_size_is_zero)
744 	{
745 	  if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
746 	    {
747 	      bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
748 	      bfd_vma pdata_vma = bfd_section_vma (pdata_section);
749 	      struct pex64_runtime_function arf;
750 
751 	      fprintf (file, "\t shares information with ");
752 	      altent += imagebase;
753 
754 	      if (altent >= pdata_vma
755 		  && altent - pdata_vma + PDATA_ROW_SIZE <= stop)
756 		{
757 		  pex64_get_runtime_function
758 		    (abfd, &arf, &pdata[altent - pdata_vma]);
759 		  fprintf (file, "pdata element at 0x%016" PRIx64,
760 			   arf.rva_UnwindData);
761 		}
762 	      else
763 		fprintf (file, "unknown pdata element");
764 	      fprintf (file, ".\n");
765 	    }
766 	  else
767 	    {
768 	      bfd_vma *p;
769 
770 	      /* Search for the current entry in the sorted array.  */
771 	      p = (bfd_vma *)
772 		  bsearch (&rf.rva_UnwindData, xdata_arr,
773 			   (size_t) xdata_arr_cnt, sizeof (bfd_vma),
774 			   sort_xdata_arr);
775 
776 	      /* Advance to the next pointer into the xdata section.  We may
777 		 have shared xdata entries, which will result in a string of
778 		 identical pointers in the array; advance past all of them.  */
779 	      while (p[0] <= rf.rva_UnwindData)
780 		++p;
781 
782 	      if (p[0] == ~((bfd_vma) 0))
783 		p = NULL;
784 
785 	      pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
786 	    }
787 	}
788     }
789 
790  done:
791   free (pdata);
792   free (xdata_arr);
793   free (xdata);
794 
795   return true;
796 }
797 
798 struct pex64_paps
799 {
800   void *obj;
801   /* Number of found pdata sections.  */
802   unsigned int pdata_count;
803 };
804 
805 /* Functionn prototype.  */
806 bool pex64_bfd_print_pdata (bfd *, void *);
807 
808 /* Helper function for bfd_map_over_section.  */
809 static void
810 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *arg)
811 {
812   struct pex64_paps *paps = arg;
813   if (startswith (pdata->name, ".pdata"))
814     {
815       if (pex64_bfd_print_pdata_section (abfd, paps->obj, pdata))
816 	paps->pdata_count++;
817     }
818 }
819 
820 bool
821 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
822 {
823   asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
824   struct pex64_paps paps;
825 
826   if (pdata_section)
827     return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
828 
829   paps.obj = vfile;
830   paps.pdata_count = 0;
831   bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, &paps);
832   return paps.pdata_count != 0;
833 }
834 
835 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
836 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
837 
838 #include "coff-x86_64.c"
839