Remove path name from test case
[binutils-gdb.git] / bfd / pei-x86_64.c
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright (C) 2006-2023 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
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
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
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 *
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
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
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
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
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
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"