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