1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2    Copyright (C) 2006-2016 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 
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 
141 static void
pex64_xdata_print_uwd_codes(FILE * file,bfd * abfd,struct pex64_unwind_info * ui,struct pex64_runtime_function * rf)142 pex64_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 
292 static asection *
pex64_get_section_by_rva(bfd * abfd,bfd_vma addr,const char * sec_name)293 pex64_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 
314 static void
pex64_dump_xdata(FILE * file,bfd * abfd,asection * xdata_section,bfd_byte * xdata,bfd_vma * endx,struct pex64_runtime_function * rf)315 pex64_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 
448 static int
sort_xdata_arr(const void * l,const void * r)449 sort_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 
461 static bfd_boolean
pex64_bfd_print_pdata_section(bfd * abfd,void * vfile,asection * pdata_section)462 pex64_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 	     _("Warning: %s section size (%ld) is not a multiple of %d\n"),
491 	     pdata_section->name, (long) stop, onaline);
492 
493   datasize = pdata_section->size;
494   if (datasize == 0)
495     {
496       if (stop)
497 	fprintf (file, _("Warning: %s section size is zero\n"),
498 		 pdata_section->name);
499       return TRUE;
500     }
501 
502   /* virt_size might be zero for objects.  */
503   if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
504     {
505       stop = (datasize / onaline) * onaline;
506       virt_size_is_zero = TRUE;
507     }
508   else if (datasize < stop)
509       {
510 	fprintf (file,
511 		 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
512 		 pdata_section->name, (unsigned long) datasize,
513 		 (unsigned long) stop);
514 	/* Be sure not to read passed datasize.  */
515 	stop = datasize / onaline;
516       }
517 
518   /* Display functions table.  */
519   fprintf (file,
520 	   _("\nThe Function Table (interpreted %s section contents)\n"),
521 	   pdata_section->name);
522 
523   fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
524 
525   if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
526     goto done;
527 
528   /* Table of xdata entries.  */
529   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
530   xdata_arr_cnt = 0;
531 
532   if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
533     imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
534   else
535     imagebase = 0;
536 
537   for (i = 0; i < stop; i += onaline)
538     {
539       struct pex64_runtime_function rf;
540 
541       if (i + PDATA_ROW_SIZE > stop)
542 	break;
543 
544       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
545 
546       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
547 	  && rf.rva_UnwindData == 0)
548 	/* We are probably into the padding of the section now.  */
549 	break;
550       fputc (' ', file);
551       fprintf_vma (file, i + pdata_section->vma);
552       fprintf (file, ":\t");
553       fprintf_vma (file, imagebase + rf.rva_BeginAddress);
554       fprintf (file, " ");
555       fprintf_vma (file, imagebase + rf.rva_EndAddress);
556       fprintf (file, " ");
557       fprintf_vma (file, imagebase + rf.rva_UnwindData);
558       fprintf (file, "\n");
559       if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
560 	{
561 	  seen_error = 1;
562 	  fprintf (file, "  has %s begin address as predecessor\n",
563 	    (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
564         }
565       prev_beginaddress = rf.rva_BeginAddress;
566       /* Now we check for negative addresses.  */
567       if ((prev_beginaddress & 0x80000000) != 0)
568 	{
569 	  seen_error = 1;
570 	  fprintf (file, "  has negative begin address\n");
571 	}
572       if ((rf.rva_EndAddress & 0x80000000) != 0)
573 	{
574 	  seen_error = 1;
575 	  fprintf (file, "  has negative end address\n");
576 	}
577       if ((rf.rva_UnwindData & 0x80000000) != 0)
578 	{
579 	  seen_error = 1;
580 	  fprintf (file, "  has negative unwind address\n");
581 	}
582       else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
583 		|| virt_size_is_zero)
584 	xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
585     }
586 
587   if (seen_error)
588     goto done;
589 
590   /* Add end of list marker.  */
591   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
592 
593   /* Sort start RVAs of xdata.  */
594   if (xdata_arr_cnt > 1)
595     qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
596 	   sort_xdata_arr);
597 
598   /* Find the section containing the unwind data (.xdata).  */
599   xdata_base = xdata_arr[0];
600   /* For sections with long names, first look for the same
601      section name, replacing .pdata by .xdata prefix.  */
602   if (strcmp (pdata_section->name, ".pdata") != 0)
603     {
604       size_t len = strlen (pdata_section->name);
605       char *xdata_name = xmalloc (len + 1);
606 
607       xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
608       /* Transform .pdata prefix into .xdata prefix.  */
609       if (len > 1)
610 	xdata_name [1] = 'x';
611       xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
612 						xdata_name);
613       free (xdata_name);
614     }
615   /* Second, try the .xdata section itself.  */
616   if (!xdata_section)
617     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
618   /* Otherwise, if xdata_base is non zero, search also inside
619      other standard sections.  */
620   if (!xdata_section && xdata_base)
621     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
622   if (!xdata_section && xdata_base)
623     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
624   if (!xdata_section && xdata_base)
625     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
626   if (!xdata_section && xdata_base)
627     xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
628   /* Transfer xdata section into xdata array.  */
629   if (!xdata_section
630       || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
631     goto done;
632 
633   /* Avoid "also used "... ouput for single unwind info
634      in object file.  */
635   prev_unwinddata_rva = (bfd_vma) -1;
636 
637   /* Do dump of pdata related xdata.  */
638   for (i = 0; i < stop; i += onaline)
639     {
640       struct pex64_runtime_function rf;
641 
642       if (i + PDATA_ROW_SIZE > stop)
643 	break;
644 
645       pex64_get_runtime_function (abfd, &rf, &pdata[i]);
646 
647       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
648 	  && rf.rva_UnwindData == 0)
649 	/* We are probably into the padding of the section now.  */
650 	break;
651       if (i == 0)
652         fprintf (file, _("\nDump of %s\n"), xdata_section->name);
653 
654       fputc (' ', file);
655       fprintf_vma (file, rf.rva_UnwindData + imagebase);
656 
657       if (prev_unwinddata_rva == rf.rva_UnwindData)
658 	{
659 	  /* Do not dump again the xdata for the same entry.  */
660 	  fprintf (file, " also used for function at ");
661 	  fprintf_vma (file, rf.rva_BeginAddress + imagebase);
662 	  fputc ('\n', file);
663 	  continue;
664 	}
665       else
666 	prev_unwinddata_rva = rf.rva_UnwindData;
667 
668       fprintf (file, " (rva: %08x): ",
669 	       (unsigned int) rf.rva_UnwindData);
670       fprintf_vma (file, rf.rva_BeginAddress + imagebase);
671       fprintf (file, " - ");
672       fprintf_vma (file, rf.rva_EndAddress + imagebase);
673       fputc ('\n', file);
674 
675       if (rf.rva_UnwindData != 0 || virt_size_is_zero)
676 	{
677 	  if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
678 	    {
679 	      bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
680 	      bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
681 	      struct pex64_runtime_function arf;
682 
683 	      fprintf (file, "\t shares information with ");
684 	      altent += imagebase;
685 
686 	      if (altent >= pdata_vma
687 		  && (altent + PDATA_ROW_SIZE <= pdata_vma
688 		      + pei_section_data (abfd, pdata_section)->virt_size))
689 		{
690 		  pex64_get_runtime_function
691 		    (abfd, &arf, &pdata[altent - pdata_vma]);
692 		  fprintf (file, "pdata element at 0x");
693 		  fprintf_vma (file, arf.rva_UnwindData);
694 		}
695 	      else
696 		fprintf (file, "unknown pdata element");
697 	      fprintf (file, ".\n");
698 	    }
699 	  else
700 	    {
701 	      bfd_vma *p;
702 
703 	      /* Search for the current entry in the sorted array.  */
704 	      p = (bfd_vma *)
705 	          bsearch (&rf.rva_UnwindData, xdata_arr,
706 			   (size_t) xdata_arr_cnt, sizeof (bfd_vma),
707 			   sort_xdata_arr);
708 
709 	      /* Advance to the next pointer into the xdata section.  We may
710 		 have shared xdata entries, which will result in a string of
711 		 identical pointers in the array; advance past all of them.  */
712 	      while (p[0] <= rf.rva_UnwindData)
713 		++p;
714 
715 	      if (p[0] == ~((bfd_vma) 0))
716 		p = NULL;
717 
718 	      pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
719 	    }
720 	}
721     }
722 
723  done:
724   free (pdata);
725   free (xdata_arr);
726   free (xdata);
727 
728   return TRUE;
729 }
730 
731 /* Static counter of number of found pdata sections.  */
732 static bfd_boolean pdata_count;
733 
734 /* Functionn prototype.  */
735 bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
736 
737 /* Helper function for bfd_map_over_section.  */
738 static void
pex64_print_all_pdata_sections(bfd * abfd,asection * pdata,void * obj)739 pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
740 {
741   if (CONST_STRNEQ (pdata->name, ".pdata"))
742     {
743       if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
744 	pdata_count++;
745     }
746 }
747 
748 bfd_boolean
pex64_bfd_print_pdata(bfd * abfd,void * vfile)749 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
750 {
751   asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
752 
753   if (pdata_section)
754     return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
755 
756   pdata_count = 0;
757   bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
758   return (pdata_count > 0);
759 }
760 
761 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
762 #define bfd_coff_std_swap_table bfd_coff_pei_swap_table
763 
764 #include "coff-x86_64.c"
765