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