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