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