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