oops - omitted changelog entry from previous delta.
[deliverable/binutils-gdb.git] / bfd / pei-x86_64.c
CommitLineData
99ad8390 1/* BFD back-end for Intel 386 PE IMAGE COFF files.
82704155 2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
99ad8390
NC
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
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
99ad8390
NC
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
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA.
68ffbac6 20
99ad8390
NC
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
22
99ad8390 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
99ad8390 25
07d6d2b8
AM
26#define TARGET_SYM x86_64_pei_vec
27#define TARGET_NAME "pei-x86-64"
99ad8390
NC
28#define COFF_IMAGE_WITH_PE
29#define COFF_WITH_PE
30#define COFF_WITH_pex64
07d6d2b8 31#define PCRELOFFSET TRUE
ef72a554 32#if defined (USE_MINGW64_LEADING_UNDERSCORES)
07d6d2b8 33#define TARGET_UNDERSCORE '_'
ef72a554 34#else
07d6d2b8 35#define TARGET_UNDERSCORE 0
ef72a554 36#endif
88183869
DK
37/* Long section names not allowed in executable images, only object files. */
38#define COFF_LONG_SECTION_NAMES 0
99ad8390
NC
39#define COFF_SUPPORT_GNU_LINKONCE
40#define COFF_LONG_FILENAMES
e48570bb 41#define PDATA_ROW_SIZE (3 * 4)
99ad8390
NC
42
43#define COFF_SECTION_ALIGNMENT_ENTRIES \
44{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
45 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
51ec9544 46{ COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
99ad8390 47 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
51ec9544 48{ COFF_SECTION_NAME_PARTIAL_MATCH (".rdata"), \
99ad8390 49 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
51ec9544 50{ COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
99ad8390
NC
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
e48570bb
DK
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
48d5accb
TG
79/* Name of registers according to SEH conventions. */
80
81static const char * const pex_regs[16] = {
e48570bb
DK
82 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
84};
85
48d5accb
TG
86/* Swap in a runtime function. */
87
e48570bb
DK
88static void
89pex64_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);
e48570bb
DK
97}
98
48d5accb
TG
99/* Swap in unwind info header. */
100
3e33b239
NC
101static bfd_boolean
102pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui,
103 void *data, void *data_end)
e48570bb
DK
104{
105 struct external_pex64_unwind_info *ex_ui =
106 (struct external_pex64_unwind_info *) data;
107 bfd_byte *ex_dta = (bfd_byte *) data;
3e33b239 108 bfd_byte *ex_dta_end = (bfd_byte *) data_end;
e48570bb
DK
109
110 memset (ui, 0, sizeof (struct pex64_unwind_info));
3e33b239
NC
111
112 if (ex_dta >= ex_dta_end || ex_dta + 4 >= ex_dta_end)
113 return FALSE;
114
e48570bb
DK
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;
3e33b239
NC
123 ui->rawUnwindCodes = ex_dta + 4;
124 ui->rawUnwindCodesEnd = ex_dta_end;
854399ea 125
e48570bb 126 ex_dta += ui->SizeOfBlock;
3e33b239
NC
127 if (ex_dta >= ex_dta_end)
128 return FALSE;
4b24dd1a 129
e48570bb
DK
130 switch (ui->Flags)
131 {
e48570bb 132 case UNW_FLAG_CHAININFO:
3e33b239
NC
133 if (ex_dta + 12 >= ex_dta_end)
134 return FALSE;
48d5accb
TG
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;
3e33b239 139 return TRUE;
48d5accb
TG
140 case UNW_FLAG_EHANDLER:
141 case UNW_FLAG_UHANDLER:
142 case UNW_FLAG_FHANDLER:
3e33b239
NC
143 if (ex_dta + 4 >= ex_dta_end)
144 return FALSE;
48d5accb 145 ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
e48570bb 146 ui->SizeOfBlock += 4;
3e33b239 147 return TRUE;
e48570bb 148 default:
3e33b239 149 return TRUE;
e48570bb 150 }
e48570bb
DK
151}
152
48d5accb
TG
153/* Display unwind codes. */
154
e48570bb 155static void
48d5accb 156pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
2b597f54
TG
157 struct pex64_unwind_info *ui,
158 struct pex64_runtime_function *rf)
e48570bb 159{
48d5accb
TG
160 unsigned int i;
161 unsigned int tmp; /* At least 32 bits. */
162 int save_allowed;
e48570bb 163
48d5accb 164 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
e48570bb
DK
165 return;
166
48d5accb
TG
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;
e48570bb 172
48d5accb
TG
173 i = 0;
174
3e33b239
NC
175 if (ui->rawUnwindCodes + 1 >= ui->rawUnwindCodesEnd)
176 {
177 fprintf (file, _("warning: corrupt unwind data\n"));
178 return;
179 }
180
2b597f54
TG
181 if (ui->Version == 2
182 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
48d5accb 183 {
2b597f54 184 /* Display epilog opcode (whose docoding is not fully documented).
07d6d2b8 185 Looks to be designed to speed-up unwinding, as there is no need
2b597f54
TG
186 to decode instruction flow if outside an epilog. */
187 unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
188
3e33b239
NC
189 if (ui->rawUnwindCodes + 1 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
190 {
191 fprintf (file, _("warning: corrupt unwind data\n"));
192 return;
193 }
4b24dd1a 194
2b597f54
TG
195 fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
196 ui->rawUnwindCodes[0]);
3e33b239 197
2b597f54
TG
198 if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
199 fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
3e33b239 200
2b597f54 201 i++;
48d5accb 202 for (; i < ui->CountOfCodes; i++)
e48570bb 203 {
48d5accb 204 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
2b597f54 205 unsigned int off;
48d5accb 206
2b597f54 207 if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
48d5accb 208 break;
2b597f54
TG
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);
e48570bb 214 }
48d5accb 215 fputc ('\n', file);
e48570bb 216 }
48d5accb 217
3e33b239
NC
218 if (ui->rawUnwindCodes + 2 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
219 {
220 fprintf (file, _("warning: corrupt unwind data\n"));
221 return;
222 }
4b24dd1a 223
48d5accb 224 for (; i < ui->CountOfCodes; i++)
e48570bb 225 {
48d5accb
TG
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]);
e48570bb
DK
231 switch (PEX64_UNWCODE_CODE (dta[1]))
232 {
233 case UWOP_PUSH_NONVOL:
48d5accb 234 fprintf (file, "push %s", pex_regs[info]);
e48570bb
DK
235 break;
236 case UWOP_ALLOC_LARGE:
48d5accb 237 if (info == 0)
e48570bb 238 {
48d5accb
TG
239 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
240 i++;
e48570bb
DK
241 }
242 else
48d5accb
TG
243 {
244 tmp = bfd_get_32 (abfd, &dta[2]);
245 i += 2;
246 }
247 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
e48570bb
DK
248 break;
249 case UWOP_ALLOC_SMALL:
48d5accb 250 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
e48570bb
DK
251 break;
252 case UWOP_SET_FPREG:
48d5accb
TG
253 /* According to the documentation, info field is unused. */
254 fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
255 pex_regs[ui->FrameRegister],
256 (unsigned int) ui->FrameOffset * 16, info);
257 unexpected = ui->FrameRegister == 0;
258 save_allowed = FALSE;
e48570bb
DK
259 break;
260 case UWOP_SAVE_NONVOL:
48d5accb
TG
261 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
262 i++;
263 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
264 unexpected = !save_allowed;
e48570bb
DK
265 break;
266 case UWOP_SAVE_NONVOL_FAR:
48d5accb
TG
267 tmp = bfd_get_32 (abfd, &dta[2]);
268 i += 2;
269 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
270 unexpected = !save_allowed;
e48570bb
DK
271 break;
272 case UWOP_SAVE_XMM:
48d5accb
TG
273 if (ui->Version == 1)
274 {
275 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
276 i++;
277 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
278 unexpected = !save_allowed;
279 }
280 else if (ui->Version == 2)
281 {
2b597f54 282 fprintf (file, "epilog %02x %01x", dta[0], info);
48d5accb
TG
283 unexpected = TRUE;
284 }
e48570bb
DK
285 break;
286 case UWOP_SAVE_XMM_FAR:
48d5accb
TG
287 tmp = bfd_get_32 (abfd, &dta[2]) * 8;
288 i += 2;
289 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
290 unexpected = !save_allowed;
e48570bb
DK
291 break;
292 case UWOP_SAVE_XMM128:
48d5accb
TG
293 tmp = bfd_get_16 (abfd, &dta[2]) * 16;
294 i++;
295 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
296 unexpected = !save_allowed;
e48570bb
DK
297 break;
298 case UWOP_SAVE_XMM128_FAR:
48d5accb
TG
299 tmp = bfd_get_32 (abfd, &dta[2]) * 16;
300 i += 2;
301 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
302 unexpected = !save_allowed;
e48570bb
DK
303 break;
304 case UWOP_PUSH_MACHFRAME:
305 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
48d5accb
TG
306 if (info == 0)
307 fprintf (file, ")");
308 else if (info == 1)
309 fprintf (file, ",ErrorCode)");
e48570bb 310 else
48d5accb 311 fprintf (file, ", unknown(%u))", info);
e48570bb
DK
312 break;
313 default:
0a9d414a
NC
314 /* PR 17512: file: 2245-7442-0.004. */
315 fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
316 break;
e48570bb 317 }
48d5accb
TG
318 if (unexpected)
319 fprintf (file, " [Unexpected!]");
320 fputc ('\n', file);
e48570bb
DK
321 }
322}
323
48d5accb
TG
324/* Check wether section SEC_NAME contains the xdata at address ADDR. */
325
e48570bb
DK
326static asection *
327pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
328{
329 asection *section = bfd_get_section_by_name (abfd, sec_name);
330 bfd_vma vsize;
331 bfd_size_type datasize = 0;
332
333 if (section == NULL
334 || coff_section_data (abfd, section) == NULL
335 || pei_section_data (abfd, section) == NULL)
336 return NULL;
337 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
338 datasize = section->size;
339 if (!datasize || vsize > addr || (vsize + datasize) < addr)
340 return NULL;
341 return section;
342}
343
2b597f54
TG
344/* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
345 designate the bfd section containing the xdata, XDATA is its content,
346 and ENDX the size if known (or NULL). */
48d5accb 347
e48570bb 348static void
48d5accb 349pex64_dump_xdata (FILE *file, bfd *abfd,
2b597f54
TG
350 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
351 struct pex64_runtime_function *rf)
e48570bb 352{
48d5accb 353 bfd_vma vaddr;
2eb03909 354 bfd_vma end_addr;
2b597f54 355 bfd_vma addr = rf->rva_UnwindData;
0a9d414a 356 bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
48d5accb 357 struct pex64_unwind_info ui;
e48570bb 358
48d5accb
TG
359 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
360 addr -= vaddr;
2eb03909 361
0a9d414a
NC
362 /* PR 17512: file: 2245-7442-0.004. */
363 if (addr >= sec_size)
364 {
365 fprintf (file, _("warning: xdata section corrupt\n"));
366 return;
367 }
368
1360ae66 369 if (endx)
0a9d414a
NC
370 {
371 end_addr = endx[0] - vaddr;
372 /* PR 17512: file: 2245-7442-0.004. */
373 if (end_addr > sec_size)
374 {
3e33b239 375 fprintf (file, _("warning: xdata section corrupt\n"));
0a9d414a
NC
376 end_addr = sec_size;
377 }
378 }
1360ae66 379 else
0a9d414a 380 end_addr = sec_size;
e48570bb 381
3e33b239
NC
382 if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
383 {
384 fprintf (file, _("warning: xdata section corrupt\n"));
385 return;
386 }
1b786873 387
48d5accb
TG
388 if (ui.Version != 1 && ui.Version != 2)
389 {
390 unsigned int i;
391 fprintf (file, "\tVersion %u (unknown).\n",
392 (unsigned int) ui.Version);
393 for (i = 0; addr < end_addr; addr += 1, i++)
e48570bb 394 {
48d5accb
TG
395 if ((i & 15) == 0)
396 fprintf (file, "\t %03x:", i);
397 fprintf (file, " %02x", xdata[addr]);
398 if ((i & 15) == 15)
399 fprintf (file, "\n");
e48570bb 400 }
48d5accb
TG
401 if ((i & 15) != 0)
402 fprintf (file, "\n");
403 return;
404 }
e48570bb 405
48d5accb
TG
406 fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
407 switch (ui.Flags)
408 {
409 case UNW_FLAG_NHANDLER:
410 fprintf (file, "none");
411 break;
412 case UNW_FLAG_EHANDLER:
413 fprintf (file, "UNW_FLAG_EHANDLER");
414 break;
415 case UNW_FLAG_UHANDLER:
416 fprintf (file, "UNW_FLAG_UHANDLER");
417 break;
418 case UNW_FLAG_FHANDLER:
419 fprintf
420 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
421 break;
422 case UNW_FLAG_CHAININFO:
423 fprintf (file, "UNW_FLAG_CHAININFO");
424 break;
425 default:
426 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
427 break;
428 }
429 fputc ('\n', file);
430 fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
431 fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
432 (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
433 fprintf (file, "Frame reg: %s\n",
434 ui.FrameRegister == 0 ? "none"
435 : pex_regs[(unsigned int) ui.FrameRegister]);
436
0a9d414a 437 /* PR 17512: file: 2245-7442-0.004. */
854399ea 438 if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
0a9d414a
NC
439 fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
440 else
441 pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
48d5accb
TG
442
443 switch (ui.Flags)
444 {
445 case UNW_FLAG_EHANDLER:
446 case UNW_FLAG_UHANDLER:
447 case UNW_FLAG_FHANDLER:
448 fprintf (file, "\tHandler: ");
449 fprintf_vma (file, (ui.rva_ExceptionHandler
450 + pe_data (abfd)->pe_opthdr.ImageBase));
e48570bb 451 fprintf (file, ".\n");
48d5accb
TG
452 break;
453 case UNW_FLAG_CHAININFO:
454 fprintf (file, "\tChain: start: ");
455 fprintf_vma (file, ui.rva_BeginAddress);
456 fprintf (file, ", end: ");
457 fprintf_vma (file, ui.rva_EndAddress);
458 fprintf (file, "\n\t unwind data: ");
459 fprintf_vma (file, ui.rva_UnwindData);
460 fprintf (file, ".\n");
461 break;
462 }
463
464 /* Now we need end of this xdata block. */
465 addr += ui.SizeOfBlock;
466 if (addr < end_addr)
467 {
468 unsigned int i;
469 fprintf (file,"\tUser data:\n");
470 for (i = 0; addr < end_addr; addr += 1, i++)
471 {
472 if ((i & 15) == 0)
473 fprintf (file, "\t %03x:", i);
474 fprintf (file, " %02x", xdata[addr]);
475 if ((i & 15) == 15)
2eb03909 476 fprintf (file, "\n");
48d5accb
TG
477 }
478 if ((i & 15) != 0)
479 fprintf (file, "\n");
e48570bb 480 }
e48570bb
DK
481}
482
48d5accb
TG
483/* Helper function to sort xdata. The entries of xdata are sorted to know
484 the size of each entry. */
485
1360ae66
KT
486static int
487sort_xdata_arr (const void *l, const void *r)
488{
489 const bfd_vma *lp = (const bfd_vma *) l;
490 const bfd_vma *rp = (const bfd_vma *) r;
491
492 if (*lp == *rp)
493 return 0;
494 return (*lp < *rp ? -1 : 1);
495}
496
48d5accb
TG
497/* Display unwind tables for x86-64. */
498
e48570bb 499static bfd_boolean
854399ea 500pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
e48570bb
DK
501{
502 FILE *file = (FILE *) vfile;
48d5accb
TG
503 bfd_byte *pdata = NULL;
504 bfd_byte *xdata = NULL;
854399ea 505 asection *xdata_section = NULL;
48d5accb 506 bfd_vma xdata_base;
e48570bb 507 bfd_size_type i;
854399ea 508 bfd_size_type datasize;
2eb03909 509 bfd_size_type stop;
854399ea
PM
510 bfd_vma prev_beginaddress = (bfd_vma) -1;
511 bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
48d5accb 512 bfd_vma imagebase;
e48570bb 513 int onaline = PDATA_ROW_SIZE;
2eb03909 514 int seen_error = 0;
48d5accb 515 bfd_vma *xdata_arr = NULL;
1360ae66 516 int xdata_arr_cnt;
854399ea 517 bfd_boolean virt_size_is_zero = FALSE;
e48570bb 518
48d5accb
TG
519 /* Sanity checks. */
520 if (pdata_section == NULL
521 || coff_section_data (abfd, pdata_section) == NULL
522 || pei_section_data (abfd, pdata_section) == NULL)
e48570bb
DK
523 return TRUE;
524
48d5accb 525 stop = pei_section_data (abfd, pdata_section)->virt_size;
854399ea
PM
526 if ((stop % onaline) != 0)
527 fprintf (file,
695344c0 528 /* xgettext:c-format */
854399ea
PM
529 _("Warning: %s section size (%ld) is not a multiple of %d\n"),
530 pdata_section->name, (long) stop, onaline);
531
532 datasize = pdata_section->size;
533 if (datasize == 0)
6937bb54 534 {
854399ea
PM
535 if (stop)
536 fprintf (file, _("Warning: %s section size is zero\n"),
537 pdata_section->name);
6937bb54
NC
538 return TRUE;
539 }
854399ea
PM
540
541 /* virt_size might be zero for objects. */
542 if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
543 {
179f2db0 544 stop = datasize;
854399ea
PM
545 virt_size_is_zero = TRUE;
546 }
547 else if (datasize < stop)
548 {
549 fprintf (file,
695344c0 550 /* xgettext:c-format */
854399ea 551 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
09eb8b7b
L
552 pdata_section->name, (unsigned long) datasize,
553 (unsigned long) stop);
179f2db0
AM
554 /* Be sure not to read past datasize. */
555 stop = datasize;
854399ea 556 }
e48570bb 557
48d5accb 558 /* Display functions table. */
e48570bb 559 fprintf (file,
854399ea
PM
560 _("\nThe Function Table (interpreted %s section contents)\n"),
561 pdata_section->name);
e48570bb
DK
562
563 fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
564
48d5accb
TG
565 if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
566 goto done;
e48570bb 567
48d5accb 568 /* Table of xdata entries. */
1360ae66
KT
569 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
570 xdata_arr_cnt = 0;
48d5accb 571
854399ea
PM
572 if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
573 imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
574 else
575 imagebase = 0;
48d5accb 576
2eb03909 577 for (i = 0; i < stop; i += onaline)
e48570bb
DK
578 {
579 struct pex64_runtime_function rf;
580
581 if (i + PDATA_ROW_SIZE > stop)
582 break;
6937bb54 583
48d5accb 584 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
e48570bb
DK
585
586 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
587 && rf.rva_UnwindData == 0)
588 /* We are probably into the padding of the section now. */
589 break;
e48570bb 590 fputc (' ', file);
48d5accb 591 fprintf_vma (file, i + pdata_section->vma);
e48570bb 592 fprintf (file, ":\t");
48d5accb
TG
593 fprintf_vma (file, imagebase + rf.rva_BeginAddress);
594 fprintf (file, " ");
595 fprintf_vma (file, imagebase + rf.rva_EndAddress);
596 fprintf (file, " ");
597 fprintf_vma (file, imagebase + rf.rva_UnwindData);
e48570bb 598 fprintf (file, "\n");
2eb03909
KT
599 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
600 {
601 seen_error = 1;
602 fprintf (file, " has %s begin address as predecessor\n",
603 (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
07d6d2b8 604 }
2eb03909
KT
605 prev_beginaddress = rf.rva_BeginAddress;
606 /* Now we check for negative addresses. */
607 if ((prev_beginaddress & 0x80000000) != 0)
608 {
609 seen_error = 1;
610 fprintf (file, " has negative begin address\n");
611 }
612 if ((rf.rva_EndAddress & 0x80000000) != 0)
613 {
614 seen_error = 1;
615 fprintf (file, " has negative end address\n");
616 }
617 if ((rf.rva_UnwindData & 0x80000000) != 0)
618 {
619 seen_error = 1;
620 fprintf (file, " has negative unwind address\n");
621 }
854399ea
PM
622 else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
623 || virt_size_is_zero)
624 xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
2eb03909
KT
625 }
626
627 if (seen_error)
48d5accb 628 goto done;
1360ae66
KT
629
630 /* Add end of list marker. */
631 xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
632
633 /* Sort start RVAs of xdata. */
634 if (xdata_arr_cnt > 1)
635 qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
636 sort_xdata_arr);
637
48d5accb
TG
638 /* Find the section containing the unwind data (.xdata). */
639 xdata_base = xdata_arr[0];
854399ea
PM
640 /* For sections with long names, first look for the same
641 section name, replacing .pdata by .xdata prefix. */
642 if (strcmp (pdata_section->name, ".pdata") != 0)
643 {
de0d7895 644 size_t len = strlen (pdata_section->name);
e1fa0163 645 char *xdata_name = xmalloc (len + 1);
854399ea 646
de0d7895 647 xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
854399ea 648 /* Transform .pdata prefix into .xdata prefix. */
de0d7895 649 if (len > 1)
854399ea
PM
650 xdata_name [1] = 'x';
651 xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
652 xdata_name);
e1fa0163 653 free (xdata_name);
854399ea
PM
654 }
655 /* Second, try the .xdata section itself. */
48d5accb
TG
656 if (!xdata_section)
657 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
854399ea
PM
658 /* Otherwise, if xdata_base is non zero, search also inside
659 other standard sections. */
660 if (!xdata_section && xdata_base)
661 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
662 if (!xdata_section && xdata_base)
663 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
664 if (!xdata_section && xdata_base)
48d5accb 665 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
854399ea 666 if (!xdata_section && xdata_base)
48d5accb 667 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
854399ea 668 /* Transfer xdata section into xdata array. */
48d5accb
TG
669 if (!xdata_section
670 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
671 goto done;
2eb03909 672
854399ea
PM
673 /* Avoid "also used "... ouput for single unwind info
674 in object file. */
675 prev_unwinddata_rva = (bfd_vma) -1;
676
48d5accb 677 /* Do dump of pdata related xdata. */
2eb03909
KT
678 for (i = 0; i < stop; i += onaline)
679 {
680 struct pex64_runtime_function rf;
681
682 if (i + PDATA_ROW_SIZE > stop)
683 break;
0a9d414a 684
48d5accb 685 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
2eb03909
KT
686
687 if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
688 && rf.rva_UnwindData == 0)
689 /* We are probably into the padding of the section now. */
690 break;
691 if (i == 0)
07d6d2b8 692 fprintf (file, _("\nDump of %s\n"), xdata_section->name);
48d5accb 693
2eb03909 694 fputc (' ', file);
48d5accb
TG
695 fprintf_vma (file, rf.rva_UnwindData + imagebase);
696
697 if (prev_unwinddata_rva == rf.rva_UnwindData)
698 {
699 /* Do not dump again the xdata for the same entry. */
700 fprintf (file, " also used for function at ");
701 fprintf_vma (file, rf.rva_BeginAddress + imagebase);
702 fputc ('\n', file);
703 continue;
704 }
705 else
706 prev_unwinddata_rva = rf.rva_UnwindData;
2eb03909 707
2b597f54 708 fprintf (file, " (rva: %08x): ",
48d5accb
TG
709 (unsigned int) rf.rva_UnwindData);
710 fprintf_vma (file, rf.rva_BeginAddress + imagebase);
2b597f54
TG
711 fprintf (file, " - ");
712 fprintf_vma (file, rf.rva_EndAddress + imagebase);
48d5accb 713 fputc ('\n', file);
e48570bb 714
854399ea 715 if (rf.rva_UnwindData != 0 || virt_size_is_zero)
e48570bb 716 {
48d5accb 717 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
e48570bb 718 {
48d5accb
TG
719 bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
720 bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
721 struct pex64_runtime_function arf;
722
723 fprintf (file, "\t shares information with ");
724 altent += imagebase;
725
726 if (altent >= pdata_vma
179f2db0 727 && altent - pdata_vma + PDATA_ROW_SIZE <= stop)
48d5accb
TG
728 {
729 pex64_get_runtime_function
730 (abfd, &arf, &pdata[altent - pdata_vma]);
731 fprintf (file, "pdata element at 0x");
732 fprintf_vma (file, arf.rva_UnwindData);
733 }
734 else
735 fprintf (file, "unknown pdata element");
e48570bb
DK
736 fprintf (file, ".\n");
737 }
738 else
1360ae66
KT
739 {
740 bfd_vma *p;
741
742 /* Search for the current entry in the sorted array. */
743 p = (bfd_vma *)
07d6d2b8 744 bsearch (&rf.rva_UnwindData, xdata_arr,
1360ae66
KT
745 (size_t) xdata_arr_cnt, sizeof (bfd_vma),
746 sort_xdata_arr);
747
748 /* Advance to the next pointer into the xdata section. We may
749 have shared xdata entries, which will result in a string of
750 identical pointers in the array; advance past all of them. */
751 while (p[0] <= rf.rva_UnwindData)
752 ++p;
0a9d414a 753
1360ae66
KT
754 if (p[0] == ~((bfd_vma) 0))
755 p = NULL;
756
2b597f54 757 pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
1360ae66 758 }
e48570bb
DK
759 }
760 }
761
48d5accb
TG
762 done:
763 free (pdata);
1360ae66 764 free (xdata_arr);
48d5accb 765 free (xdata);
e48570bb
DK
766
767 return TRUE;
768}
769
854399ea
PM
770/* Static counter of number of found pdata sections. */
771static bfd_boolean pdata_count;
772
773/* Functionn prototype. */
774bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
775
776/* Helper function for bfd_map_over_section. */
777static void
778pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
779{
780 if (CONST_STRNEQ (pdata->name, ".pdata"))
781 {
782 if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
783 pdata_count++;
784 }
785}
786
787bfd_boolean
788pex64_bfd_print_pdata (bfd *abfd, void *vfile)
789{
790 asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
791
792 if (pdata_section)
793 return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
794
795 pdata_count = 0;
796 bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
797 return (pdata_count > 0);
798}
799
e48570bb 800#define bfd_pe_print_pdata pex64_bfd_print_pdata
854399ea 801#define bfd_coff_std_swap_table bfd_coff_pei_swap_table
e48570bb 802
99ad8390 803#include "coff-x86_64.c"
This page took 0.931616 seconds and 4 git commands to generate.