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