1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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,
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
26 #define TARGET_SYM x86_64pei_vec
27 #define TARGET_NAME "pei-x86-64"
28 #define COFF_IMAGE_WITH_PE
30 #define COFF_WITH_pex64
31 #define PCRELOFFSET TRUE
32 #if defined (USE_MINGW64_LEADING_UNDERSCORES)
33 #define TARGET_UNDERSCORE '_'
35 #define TARGET_UNDERSCORE 0
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)
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 }
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 */
68 #include "coff/x86_64.h"
69 #include "coff/internal.h"
73 #include "libiberty.h"
76 #define AOUTSZ PEPAOUTSZ
77 #define PEAOUTHDR PEPAOUTHDR
79 /* Name of registers according to SEH conventions. */
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"
86 /* Swap in a runtime function. */
89 pex64_get_runtime_function (bfd
*abfd
, struct pex64_runtime_function
*rf
,
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
);
99 /* Swap in unwind info header. */
102 pex64_get_unwind_info (bfd
*abfd
, struct pex64_unwind_info
*ui
, void *data
)
104 struct external_pex64_unwind_info
*ex_ui
=
105 (struct external_pex64_unwind_info
*) data
;
106 bfd_byte
*ex_dta
= (bfd_byte
*) data
;
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
;
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;
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;
138 /* Display unwind codes. */
141 pex64_xdata_print_uwd_codes (FILE *file
, bfd
*abfd
,
142 struct pex64_unwind_info
*ui
)
145 unsigned int tmp
; /* At least 32 bits. */
148 if (ui
->CountOfCodes
== 0 || ui
->rawUnwindCodes
== NULL
)
151 /* According to UNWIND_CODE documentation:
152 If an FP reg is used, the any unwind code taking an offset must only be
153 used after the FP reg is established in the prolog.
154 But there are counter examples of that in system dlls... */
159 if (ui
->Version
== 2 && PEX64_UNWCODE_CODE (ui
->rawUnwindCodes
[1]) == 6)
161 /* Display opcodes 6 (whose meaning is not documented). */
162 fprintf (file
, "\tv2 opcode6:");
163 for (; i
< ui
->CountOfCodes
; i
++)
165 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
167 if (PEX64_UNWCODE_CODE (dta
[1]) != 6)
169 fprintf (file
, " %02x %01x", dta
[0], PEX64_UNWCODE_INFO (dta
[1]));
174 for (; i
< ui
->CountOfCodes
; i
++)
176 const bfd_byte
*dta
= ui
->rawUnwindCodes
+ 2 * i
;
177 unsigned int info
= PEX64_UNWCODE_INFO (dta
[1]);
178 int unexpected
= FALSE
;
180 fprintf (file
, "\t pc+0x%02x: ", (unsigned int) dta
[0]);
181 switch (PEX64_UNWCODE_CODE (dta
[1]))
183 case UWOP_PUSH_NONVOL
:
184 fprintf (file
, "push %s", pex_regs
[info
]);
186 case UWOP_ALLOC_LARGE
:
189 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
194 tmp
= bfd_get_32 (abfd
, &dta
[2]);
197 fprintf (file
, "alloc large area: rsp = rsp - 0x%x", tmp
);
199 case UWOP_ALLOC_SMALL
:
200 fprintf (file
, "alloc small area: rsp = rsp - 0x%x", (info
+ 1) * 8);
203 /* According to the documentation, info field is unused. */
204 fprintf (file
, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
205 pex_regs
[ui
->FrameRegister
],
206 (unsigned int) ui
->FrameOffset
* 16, info
);
207 unexpected
= ui
->FrameRegister
== 0;
208 save_allowed
= FALSE
;
210 case UWOP_SAVE_NONVOL
:
211 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
213 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
214 unexpected
= !save_allowed
;
216 case UWOP_SAVE_NONVOL_FAR
:
217 tmp
= bfd_get_32 (abfd
, &dta
[2]);
219 fprintf (file
, "save %s at rsp + 0x%x", pex_regs
[info
], tmp
);
220 unexpected
= !save_allowed
;
223 if (ui
->Version
== 1)
225 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 8;
227 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
228 unexpected
= !save_allowed
;
230 else if (ui
->Version
== 2)
232 fprintf (file
, "v2-opc6 %02x %01x", dta
[0], info
);
236 case UWOP_SAVE_XMM_FAR
:
237 tmp
= bfd_get_32 (abfd
, &dta
[2]) * 8;
239 fprintf (file
, "save mm%u at rsp + 0x%x", info
, tmp
);
240 unexpected
= !save_allowed
;
242 case UWOP_SAVE_XMM128
:
243 tmp
= bfd_get_16 (abfd
, &dta
[2]) * 16;
245 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
246 unexpected
= !save_allowed
;
248 case UWOP_SAVE_XMM128_FAR
:
249 tmp
= bfd_get_32 (abfd
, &dta
[2]) * 16;
251 fprintf (file
, "save xmm%u at rsp + 0x%x", info
, tmp
);
252 unexpected
= !save_allowed
;
254 case UWOP_PUSH_MACHFRAME
:
255 fprintf (file
, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
259 fprintf (file
, ",ErrorCode)");
261 fprintf (file
, ", unknown(%u))", info
);
264 /* Already caught by the previous scan. */
268 fprintf (file
, " [Unexpected!]");
273 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
276 pex64_get_section_by_rva (bfd
*abfd
, bfd_vma addr
, const char *sec_name
)
278 asection
*section
= bfd_get_section_by_name (abfd
, sec_name
);
280 bfd_size_type datasize
= 0;
283 || coff_section_data (abfd
, section
) == NULL
284 || pei_section_data (abfd
, section
) == NULL
)
286 vsize
= section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
287 datasize
= section
->size
;
288 if (!datasize
|| vsize
> addr
|| (vsize
+ datasize
) < addr
)
293 /* Dump xdata at rva ADDR to FILE for ABFD. */
296 pex64_dump_xdata (FILE *file
, bfd
*abfd
,
297 asection
*xdata_section
, bfd_byte
*xdata
,
298 bfd_vma addr
, bfd_vma
*endx
)
302 struct pex64_unwind_info ui
;
304 vaddr
= xdata_section
->vma
- pe_data (abfd
)->pe_opthdr
.ImageBase
;
308 end_addr
= endx
[0] - vaddr
;
310 end_addr
= (xdata_section
->rawsize
!= 0 ?
311 xdata_section
->rawsize
: xdata_section
->size
);
314 pex64_get_unwind_info (abfd
, &ui
, &xdata
[addr
]);
316 if (ui
.Version
!= 1 && ui
.Version
!= 2)
319 fprintf (file
, "\tVersion %u (unknown).\n",
320 (unsigned int) ui
.Version
);
321 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
324 fprintf (file
, "\t %03x:", i
);
325 fprintf (file
, " %02x", xdata
[addr
]);
327 fprintf (file
, "\n");
330 fprintf (file
, "\n");
334 fprintf (file
, "\tVersion: %d, Flags: ", ui
.Version
);
337 case UNW_FLAG_NHANDLER
:
338 fprintf (file
, "none");
340 case UNW_FLAG_EHANDLER
:
341 fprintf (file
, "UNW_FLAG_EHANDLER");
343 case UNW_FLAG_UHANDLER
:
344 fprintf (file
, "UNW_FLAG_UHANDLER");
346 case UNW_FLAG_FHANDLER
:
348 (file
, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
350 case UNW_FLAG_CHAININFO
:
351 fprintf (file
, "UNW_FLAG_CHAININFO");
354 fprintf (file
, "unknown flags value 0x%x", (unsigned int) ui
.Flags
);
358 fprintf (file
, "\tNbr codes: %u, ", (unsigned int) ui
.CountOfCodes
);
359 fprintf (file
, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
360 (unsigned int) ui
.SizeOfPrologue
, (unsigned int) ui
.FrameOffset
);
361 fprintf (file
, "Frame reg: %s\n",
362 ui
.FrameRegister
== 0 ? "none"
363 : pex_regs
[(unsigned int) ui
.FrameRegister
]);
365 pex64_xdata_print_uwd_codes (file
, abfd
, &ui
);
369 case UNW_FLAG_EHANDLER
:
370 case UNW_FLAG_UHANDLER
:
371 case UNW_FLAG_FHANDLER
:
372 fprintf (file
, "\tHandler: ");
373 fprintf_vma (file
, (ui
.rva_ExceptionHandler
374 + pe_data (abfd
)->pe_opthdr
.ImageBase
));
375 fprintf (file
, ".\n");
377 case UNW_FLAG_CHAININFO
:
378 fprintf (file
, "\tChain: start: ");
379 fprintf_vma (file
, ui
.rva_BeginAddress
);
380 fprintf (file
, ", end: ");
381 fprintf_vma (file
, ui
.rva_EndAddress
);
382 fprintf (file
, "\n\t unwind data: ");
383 fprintf_vma (file
, ui
.rva_UnwindData
);
384 fprintf (file
, ".\n");
388 /* Now we need end of this xdata block. */
389 addr
+= ui
.SizeOfBlock
;
393 fprintf (file
,"\tUser data:\n");
394 for (i
= 0; addr
< end_addr
; addr
+= 1, i
++)
397 fprintf (file
, "\t %03x:", i
);
398 fprintf (file
, " %02x", xdata
[addr
]);
400 fprintf (file
, "\n");
403 fprintf (file
, "\n");
407 /* Helper function to sort xdata. The entries of xdata are sorted to know
408 the size of each entry. */
411 sort_xdata_arr (const void *l
, const void *r
)
413 const bfd_vma
*lp
= (const bfd_vma
*) l
;
414 const bfd_vma
*rp
= (const bfd_vma
*) r
;
418 return (*lp
< *rp
? -1 : 1);
421 /* Display unwind tables for x86-64. */
424 pex64_bfd_print_pdata (bfd
*abfd
, void *vfile
)
426 FILE *file
= (FILE *) vfile
;
427 bfd_byte
*pdata
= NULL
;
428 bfd_byte
*xdata
= NULL
;
429 asection
*pdata_section
= bfd_get_section_by_name (abfd
, ".pdata");
430 asection
*xdata_section
;
434 bfd_vma prev_beginaddress
= 0;
435 bfd_vma prev_unwinddata_rva
= 0;
437 int onaline
= PDATA_ROW_SIZE
;
439 bfd_vma
*xdata_arr
= NULL
;
443 if (pdata_section
== NULL
444 || coff_section_data (abfd
, pdata_section
) == NULL
445 || pei_section_data (abfd
, pdata_section
) == NULL
)
448 stop
= pei_section_data (abfd
, pdata_section
)->virt_size
;
449 if ((stop
% onaline
) != 0)
451 _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
452 (long) stop
, onaline
);
454 /* Display functions table. */
456 _("\nThe Function Table (interpreted .pdata section contents)\n"));
458 fprintf (file
, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
460 if (!bfd_malloc_and_get_section (abfd
, pdata_section
, &pdata
))
463 /* Table of xdata entries. */
464 xdata_arr
= (bfd_vma
*) xmalloc (sizeof (bfd_vma
) * ((stop
/ onaline
) + 1));
467 imagebase
= pe_data (abfd
)->pe_opthdr
.ImageBase
;
469 for (i
= 0; i
< stop
; i
+= onaline
)
471 struct pex64_runtime_function rf
;
473 if (i
+ PDATA_ROW_SIZE
> stop
)
475 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
477 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
478 && rf
.rva_UnwindData
== 0)
479 /* We are probably into the padding of the section now. */
482 fprintf_vma (file
, i
+ pdata_section
->vma
);
483 fprintf (file
, ":\t");
484 fprintf_vma (file
, imagebase
+ rf
.rva_BeginAddress
);
486 fprintf_vma (file
, imagebase
+ rf
.rva_EndAddress
);
488 fprintf_vma (file
, imagebase
+ rf
.rva_UnwindData
);
489 fprintf (file
, "\n");
490 if (i
!= 0 && rf
.rva_BeginAddress
<= prev_beginaddress
)
493 fprintf (file
, " has %s begin address as predecessor\n",
494 (rf
.rva_BeginAddress
< prev_beginaddress
? "smaller" : "same"));
496 prev_beginaddress
= rf
.rva_BeginAddress
;
497 /* Now we check for negative addresses. */
498 if ((prev_beginaddress
& 0x80000000) != 0)
501 fprintf (file
, " has negative begin address\n");
503 if ((rf
.rva_EndAddress
& 0x80000000) != 0)
506 fprintf (file
, " has negative end address\n");
508 if ((rf
.rva_UnwindData
& 0x80000000) != 0)
511 fprintf (file
, " has negative unwind address\n");
513 if (rf
.rva_UnwindData
&& !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
514 xdata_arr
[xdata_arr_cnt
++] = rf
.rva_UnwindData
;
520 /* Add end of list marker. */
521 xdata_arr
[xdata_arr_cnt
++] = ~((bfd_vma
) 0);
523 /* Sort start RVAs of xdata. */
524 if (xdata_arr_cnt
> 1)
525 qsort (xdata_arr
, (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
528 /* Find the section containing the unwind data (.xdata). */
529 xdata_base
= xdata_arr
[0];
530 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".rdata");
533 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".data");
535 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".xdata");
537 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".pdata");
539 xdata_section
= pex64_get_section_by_rva (abfd
, xdata_base
, ".text");
541 || !bfd_malloc_and_get_section (abfd
, xdata_section
, &xdata
))
544 /* Do dump of pdata related xdata. */
545 for (i
= 0; i
< stop
; i
+= onaline
)
547 struct pex64_runtime_function rf
;
549 if (i
+ PDATA_ROW_SIZE
> stop
)
551 pex64_get_runtime_function (abfd
, &rf
, &pdata
[i
]);
553 if (rf
.rva_BeginAddress
== 0 && rf
.rva_EndAddress
== 0
554 && rf
.rva_UnwindData
== 0)
555 /* We are probably into the padding of the section now. */
558 fprintf (file
, "\nDump of .xdata\n");
561 fprintf_vma (file
, rf
.rva_UnwindData
+ imagebase
);
563 if (prev_unwinddata_rva
== rf
.rva_UnwindData
)
565 /* Do not dump again the xdata for the same entry. */
566 fprintf (file
, " also used for function at ");
567 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
572 prev_unwinddata_rva
= rf
.rva_UnwindData
;
574 fprintf (file
, " (rva: %08x): for function at ",
575 (unsigned int) rf
.rva_UnwindData
);
576 fprintf_vma (file
, rf
.rva_BeginAddress
+ imagebase
);
579 if (rf
.rva_UnwindData
!= 0)
581 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf
))
583 bfd_vma altent
= PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf
);
584 bfd_vma pdata_vma
= bfd_get_section_vma (abfd
, pdata_section
);
585 struct pex64_runtime_function arf
;
587 fprintf (file
, "\t shares information with ");
590 if (altent
>= pdata_vma
591 && (altent
+ PDATA_ROW_SIZE
<= pdata_vma
592 + pei_section_data (abfd
, pdata_section
)->virt_size
))
594 pex64_get_runtime_function
595 (abfd
, &arf
, &pdata
[altent
- pdata_vma
]);
596 fprintf (file
, "pdata element at 0x");
597 fprintf_vma (file
, arf
.rva_UnwindData
);
600 fprintf (file
, "unknown pdata element");
601 fprintf (file
, ".\n");
607 /* Search for the current entry in the sorted array. */
609 bsearch (&rf
.rva_UnwindData
, xdata_arr
,
610 (size_t) xdata_arr_cnt
, sizeof (bfd_vma
),
613 /* Advance to the next pointer into the xdata section. We may
614 have shared xdata entries, which will result in a string of
615 identical pointers in the array; advance past all of them. */
616 while (p
[0] <= rf
.rva_UnwindData
)
618 if (p
[0] == ~((bfd_vma
) 0))
621 pex64_dump_xdata (file
, abfd
, xdata_section
, xdata
,
622 rf
.rva_UnwindData
, p
);
635 #define bfd_pe_print_pdata pex64_bfd_print_pdata
637 #include "coff-x86_64.c"