Improve dump of xdata/pdata on x86_64.
[deliverable/binutils-gdb.git] / bfd / pei-x86_64.c
1 /* BFD back-end for Intel 386 PE IMAGE COFF files.
2 Copyright 2006, 2007, 2009 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_64pei_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 void
102 pex64_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];
118 ex_dta += ui->SizeOfBlock;
119 switch (ui->Flags)
120 {
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;
126 return;
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;
132 return;
133 default:
134 return;
135 }
136 }
137
138 /* Display unwind codes. */
139
140 static void
141 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
142 struct pex64_unwind_info *ui)
143 {
144 unsigned int i;
145 unsigned int tmp; /* At least 32 bits. */
146 int save_allowed;
147
148 if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
149 return;
150
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... */
155 save_allowed = TRUE;
156
157 i = 0;
158
159 if (ui->Version == 2 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == 6)
160 {
161 /* Display opcodes 6 (whose meaning is not documented). */
162 fprintf (file, "\tv2 opcode6:");
163 for (; i < ui->CountOfCodes; i++)
164 {
165 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
166
167 if (PEX64_UNWCODE_CODE (dta[1]) != 6)
168 break;
169 fprintf (file, " %02x %01x", dta[0], PEX64_UNWCODE_INFO (dta[1]));
170 }
171 fputc ('\n', file);
172 }
173
174 for (; i < ui->CountOfCodes; i++)
175 {
176 const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
177 unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
178 int unexpected = FALSE;
179
180 fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]);
181 switch (PEX64_UNWCODE_CODE (dta[1]))
182 {
183 case UWOP_PUSH_NONVOL:
184 fprintf (file, "push %s", pex_regs[info]);
185 break;
186 case UWOP_ALLOC_LARGE:
187 if (info == 0)
188 {
189 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
190 i++;
191 }
192 else
193 {
194 tmp = bfd_get_32 (abfd, &dta[2]);
195 i += 2;
196 }
197 fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
198 break;
199 case UWOP_ALLOC_SMALL:
200 fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
201 break;
202 case UWOP_SET_FPREG:
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;
209 break;
210 case UWOP_SAVE_NONVOL:
211 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
212 i++;
213 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
214 unexpected = !save_allowed;
215 break;
216 case UWOP_SAVE_NONVOL_FAR:
217 tmp = bfd_get_32 (abfd, &dta[2]);
218 i += 2;
219 fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
220 unexpected = !save_allowed;
221 break;
222 case UWOP_SAVE_XMM:
223 if (ui->Version == 1)
224 {
225 tmp = bfd_get_16 (abfd, &dta[2]) * 8;
226 i++;
227 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
228 unexpected = !save_allowed;
229 }
230 else if (ui->Version == 2)
231 {
232 fprintf (file, "v2-opc6 %02x %01x", dta[0], info);
233 unexpected = TRUE;
234 }
235 break;
236 case UWOP_SAVE_XMM_FAR:
237 tmp = bfd_get_32 (abfd, &dta[2]) * 8;
238 i += 2;
239 fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
240 unexpected = !save_allowed;
241 break;
242 case UWOP_SAVE_XMM128:
243 tmp = bfd_get_16 (abfd, &dta[2]) * 16;
244 i++;
245 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
246 unexpected = !save_allowed;
247 break;
248 case UWOP_SAVE_XMM128_FAR:
249 tmp = bfd_get_32 (abfd, &dta[2]) * 16;
250 i += 2;
251 fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
252 unexpected = !save_allowed;
253 break;
254 case UWOP_PUSH_MACHFRAME:
255 fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
256 if (info == 0)
257 fprintf (file, ")");
258 else if (info == 1)
259 fprintf (file, ",ErrorCode)");
260 else
261 fprintf (file, ", unknown(%u))", info);
262 break;
263 default:
264 /* Already caught by the previous scan. */
265 abort ();
266 }
267 if (unexpected)
268 fprintf (file, " [Unexpected!]");
269 fputc ('\n', file);
270 }
271 }
272
273 /* Check wether section SEC_NAME contains the xdata at address ADDR. */
274
275 static asection *
276 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
277 {
278 asection *section = bfd_get_section_by_name (abfd, sec_name);
279 bfd_vma vsize;
280 bfd_size_type datasize = 0;
281
282 if (section == NULL
283 || coff_section_data (abfd, section) == NULL
284 || pei_section_data (abfd, section) == NULL)
285 return NULL;
286 vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
287 datasize = section->size;
288 if (!datasize || vsize > addr || (vsize + datasize) < addr)
289 return NULL;
290 return section;
291 }
292
293 /* Dump xdata at rva ADDR to FILE for ABFD. */
294
295 static void
296 pex64_dump_xdata (FILE *file, bfd *abfd,
297 asection *xdata_section, bfd_byte *xdata,
298 bfd_vma addr, bfd_vma *endx)
299 {
300 bfd_vma vaddr;
301 bfd_vma end_addr;
302 struct pex64_unwind_info ui;
303
304 vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
305 addr -= vaddr;
306
307 if (endx)
308 end_addr = endx[0] - vaddr;
309 else
310 end_addr = (xdata_section->rawsize != 0 ?
311 xdata_section->rawsize : xdata_section->size);
312
313
314 pex64_get_unwind_info (abfd, &ui, &xdata[addr]);
315
316 if (ui.Version != 1 && ui.Version != 2)
317 {
318 unsigned int i;
319 fprintf (file, "\tVersion %u (unknown).\n",
320 (unsigned int) ui.Version);
321 for (i = 0; addr < end_addr; addr += 1, i++)
322 {
323 if ((i & 15) == 0)
324 fprintf (file, "\t %03x:", i);
325 fprintf (file, " %02x", xdata[addr]);
326 if ((i & 15) == 15)
327 fprintf (file, "\n");
328 }
329 if ((i & 15) != 0)
330 fprintf (file, "\n");
331 return;
332 }
333
334 fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
335 switch (ui.Flags)
336 {
337 case UNW_FLAG_NHANDLER:
338 fprintf (file, "none");
339 break;
340 case UNW_FLAG_EHANDLER:
341 fprintf (file, "UNW_FLAG_EHANDLER");
342 break;
343 case UNW_FLAG_UHANDLER:
344 fprintf (file, "UNW_FLAG_UHANDLER");
345 break;
346 case UNW_FLAG_FHANDLER:
347 fprintf
348 (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
349 break;
350 case UNW_FLAG_CHAININFO:
351 fprintf (file, "UNW_FLAG_CHAININFO");
352 break;
353 default:
354 fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
355 break;
356 }
357 fputc ('\n', file);
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]);
364
365 pex64_xdata_print_uwd_codes (file, abfd, &ui);
366
367 switch (ui.Flags)
368 {
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");
376 break;
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");
385 break;
386 }
387
388 /* Now we need end of this xdata block. */
389 addr += ui.SizeOfBlock;
390 if (addr < end_addr)
391 {
392 unsigned int i;
393 fprintf (file,"\tUser data:\n");
394 for (i = 0; addr < end_addr; addr += 1, i++)
395 {
396 if ((i & 15) == 0)
397 fprintf (file, "\t %03x:", i);
398 fprintf (file, " %02x", xdata[addr]);
399 if ((i & 15) == 15)
400 fprintf (file, "\n");
401 }
402 if ((i & 15) != 0)
403 fprintf (file, "\n");
404 }
405 }
406
407 /* Helper function to sort xdata. The entries of xdata are sorted to know
408 the size of each entry. */
409
410 static int
411 sort_xdata_arr (const void *l, const void *r)
412 {
413 const bfd_vma *lp = (const bfd_vma *) l;
414 const bfd_vma *rp = (const bfd_vma *) r;
415
416 if (*lp == *rp)
417 return 0;
418 return (*lp < *rp ? -1 : 1);
419 }
420
421 /* Display unwind tables for x86-64. */
422
423 static bfd_boolean
424 pex64_bfd_print_pdata (bfd *abfd, void *vfile)
425 {
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;
431 bfd_vma xdata_base;
432 bfd_size_type i;
433 bfd_size_type stop;
434 bfd_vma prev_beginaddress = 0;
435 bfd_vma prev_unwinddata_rva = 0;
436 bfd_vma imagebase;
437 int onaline = PDATA_ROW_SIZE;
438 int seen_error = 0;
439 bfd_vma *xdata_arr = NULL;
440 int xdata_arr_cnt;
441
442 /* Sanity checks. */
443 if (pdata_section == NULL
444 || coff_section_data (abfd, pdata_section) == NULL
445 || pei_section_data (abfd, pdata_section) == NULL)
446 return TRUE;
447
448 stop = pei_section_data (abfd, pdata_section)->virt_size;
449 if ((stop % onaline) != 0)
450 fprintf (file,
451 _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
452 (long) stop, onaline);
453
454 /* Display functions table. */
455 fprintf (file,
456 _("\nThe Function Table (interpreted .pdata section contents)\n"));
457
458 fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
459
460 if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
461 goto done;
462
463 /* Table of xdata entries. */
464 xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
465 xdata_arr_cnt = 0;
466
467 imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
468
469 for (i = 0; i < stop; i += onaline)
470 {
471 struct pex64_runtime_function rf;
472
473 if (i + PDATA_ROW_SIZE > stop)
474 break;
475 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
476
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. */
480 break;
481 fputc (' ', file);
482 fprintf_vma (file, i + pdata_section->vma);
483 fprintf (file, ":\t");
484 fprintf_vma (file, imagebase + rf.rva_BeginAddress);
485 fprintf (file, " ");
486 fprintf_vma (file, imagebase + rf.rva_EndAddress);
487 fprintf (file, " ");
488 fprintf_vma (file, imagebase + rf.rva_UnwindData);
489 fprintf (file, "\n");
490 if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
491 {
492 seen_error = 1;
493 fprintf (file, " has %s begin address as predecessor\n",
494 (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
495 }
496 prev_beginaddress = rf.rva_BeginAddress;
497 /* Now we check for negative addresses. */
498 if ((prev_beginaddress & 0x80000000) != 0)
499 {
500 seen_error = 1;
501 fprintf (file, " has negative begin address\n");
502 }
503 if ((rf.rva_EndAddress & 0x80000000) != 0)
504 {
505 seen_error = 1;
506 fprintf (file, " has negative end address\n");
507 }
508 if ((rf.rva_UnwindData & 0x80000000) != 0)
509 {
510 seen_error = 1;
511 fprintf (file, " has negative unwind address\n");
512 }
513 if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
514 xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
515 }
516
517 if (seen_error)
518 goto done;
519
520 /* Add end of list marker. */
521 xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
522
523 /* Sort start RVAs of xdata. */
524 if (xdata_arr_cnt > 1)
525 qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
526 sort_xdata_arr);
527
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");
531
532 if (!xdata_section)
533 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
534 if (!xdata_section)
535 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
536 if (!xdata_section)
537 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
538 if (!xdata_section)
539 xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
540 if (!xdata_section
541 || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
542 goto done;
543
544 /* Do dump of pdata related xdata. */
545 for (i = 0; i < stop; i += onaline)
546 {
547 struct pex64_runtime_function rf;
548
549 if (i + PDATA_ROW_SIZE > stop)
550 break;
551 pex64_get_runtime_function (abfd, &rf, &pdata[i]);
552
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. */
556 break;
557 if (i == 0)
558 fprintf (file, "\nDump of .xdata\n");
559
560 fputc (' ', file);
561 fprintf_vma (file, rf.rva_UnwindData + imagebase);
562
563 if (prev_unwinddata_rva == rf.rva_UnwindData)
564 {
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);
568 fputc ('\n', file);
569 continue;
570 }
571 else
572 prev_unwinddata_rva = rf.rva_UnwindData;
573
574 fprintf (file, " (rva: %08x): for function at ",
575 (unsigned int) rf.rva_UnwindData);
576 fprintf_vma (file, rf.rva_BeginAddress + imagebase);
577 fputc ('\n', file);
578
579 if (rf.rva_UnwindData != 0)
580 {
581 if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
582 {
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;
586
587 fprintf (file, "\t shares information with ");
588 altent += imagebase;
589
590 if (altent >= pdata_vma
591 && (altent + PDATA_ROW_SIZE <= pdata_vma
592 + pei_section_data (abfd, pdata_section)->virt_size))
593 {
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);
598 }
599 else
600 fprintf (file, "unknown pdata element");
601 fprintf (file, ".\n");
602 }
603 else
604 {
605 bfd_vma *p;
606
607 /* Search for the current entry in the sorted array. */
608 p = (bfd_vma *)
609 bsearch (&rf.rva_UnwindData, xdata_arr,
610 (size_t) xdata_arr_cnt, sizeof (bfd_vma),
611 sort_xdata_arr);
612
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)
617 ++p;
618 if (p[0] == ~((bfd_vma) 0))
619 p = NULL;
620
621 pex64_dump_xdata (file, abfd, xdata_section, xdata,
622 rf.rva_UnwindData, p);
623 }
624 }
625 }
626
627 done:
628 free (pdata);
629 free (xdata_arr);
630 free (xdata);
631
632 return TRUE;
633 }
634
635 #define bfd_pe_print_pdata pex64_bfd_print_pdata
636
637 #include "coff-x86_64.c"
This page took 0.08028 seconds and 4 git commands to generate.