Rev 5197 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5197 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Support for the generic parts of PE/PEI, for BFD. |
1 | /* Support for the generic parts of PE/PEI, for BFD. |
2 | Copyright 1995-2013 Free Software Foundation, Inc. |
2 | Copyright (C) 1995-2015 Free Software Foundation, Inc. |
3 | Written by Cygnus Solutions. |
3 | Written by Cygnus Solutions. |
Line 4... | Line 4... | ||
4 | 4 | ||
Line 5... | Line 5... | ||
5 | This file is part of BFD, the Binary File Descriptor library. |
5 | This file is part of BFD, the Binary File Descriptor library. |
Line 269... | Line 269... | ||
269 | pe->coff.pe = 1; |
269 | pe->coff.pe = 1; |
Line 270... | Line 270... | ||
270 | 270 | ||
271 | /* in_reloc_p is architecture dependent. */ |
271 | /* in_reloc_p is architecture dependent. */ |
Line -... | Line 272... | ||
- | 272 | pe->in_reloc_p = in_reloc_p; |
|
272 | pe->in_reloc_p = in_reloc_p; |
273 | |
273 | 274 | memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr); |
|
Line 274... | Line 275... | ||
274 | return TRUE; |
275 | return TRUE; |
Line 565... | Line 566... | ||
565 | 566 | ||
566 | /* Initialise the internal symbol structure. */ |
567 | /* Initialise the internal symbol structure. */ |
567 | ent->u.syment.n_sclass = sclass; |
568 | ent->u.syment.n_sclass = sclass; |
568 | ent->u.syment.n_scnum = section->target_index; |
569 | ent->u.syment.n_scnum = section->target_index; |
- | 570 | ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym; |
|
Line 569... | Line 571... | ||
569 | ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym; |
571 | ent->is_sym = TRUE; |
570 | 572 | ||
571 | sym->symbol.the_bfd = vars->abfd; |
573 | sym->symbol.the_bfd = vars->abfd; |
572 | sym->symbol.name = vars->string_ptr; |
574 | sym->symbol.name = vars->string_ptr; |
Line 627... | Line 629... | ||
627 | then the entire string length, including the null byte, |
629 | then the entire string length, including the null byte, |
628 | is even and so the extra, padding byte, is not needed. */ |
630 | is even and so the extra, padding byte, is not needed. */ |
629 | if (size & 1) |
631 | if (size & 1) |
630 | vars->data --; |
632 | vars->data --; |
Line -... | Line 633... | ||
- | 633 | ||
- | 634 | # if (GCC_VERSION >= 3000) |
|
- | 635 | /* PR 18758: See note in pe_ILF_buid_a_bfd. We must make sure that we |
|
- | 636 | preserve host alignment requirements. We test 'size' rather than |
|
- | 637 | vars.data as we cannot perform binary arithmetic on pointers. We assume |
|
- | 638 | that vars.data was sufficiently aligned upon entry to this function. |
|
- | 639 | The BFD_ASSERTs in this functions will warn us if we run out of room, |
|
- | 640 | but we should already have enough padding built in to ILF_DATA_SIZE. */ |
|
- | 641 | { |
|
- | 642 | unsigned int alignment = __alignof__ (struct coff_section_tdata); |
|
- | 643 | ||
- | 644 | if (size & (alignment - 1)) |
|
- | 645 | vars->data += alignment - (size & (alignment - 1)); |
|
- | 646 | } |
|
631 | 647 | #endif |
|
632 | /* Create a coff_section_tdata structure for our use. */ |
648 | /* Create a coff_section_tdata structure for our use. */ |
633 | sec->used_by_bfd = (struct coff_section_tdata *) vars->data; |
649 | sec->used_by_bfd = (struct coff_section_tdata *) vars->data; |
Line 634... | Line 650... | ||
634 | vars->data += sizeof (struct coff_section_tdata); |
650 | vars->data += sizeof (struct coff_section_tdata); |
Line 832... | Line 848... | ||
832 | ptr += SIZEOF_ILF_STRINGS; |
848 | ptr += SIZEOF_ILF_STRINGS; |
833 | vars.end_string_ptr = (char *) ptr; |
849 | vars.end_string_ptr = (char *) ptr; |
Line 834... | Line 850... | ||
834 | 850 | ||
835 | /* The remaining space in bim->buffer is used |
851 | /* The remaining space in bim->buffer is used |
- | 852 | by the pe_ILF_make_a_section() function. */ |
|
- | 853 | # if (GCC_VERSION >= 3000) |
|
- | 854 | /* PR 18758: Make sure that the data area is sufficiently aligned for |
|
- | 855 | pointers on the host. __alignof__ is a gcc extension, hence the test |
|
- | 856 | above. For other compilers we will have to assume that the alignment is |
|
- | 857 | unimportant, or else extra code can be added here and in |
|
- | 858 | pe_ILF_make_a_section. |
|
- | 859 | ||
- | 860 | Note - we cannot test 'ptr' directly as it is illegal to perform binary |
|
- | 861 | arithmetic on pointers, but we know that the strings section is the only |
|
- | 862 | one that might end on an unaligned boundary. */ |
|
- | 863 | { |
|
- | 864 | unsigned int alignment = __alignof__ (char *); |
|
- | 865 | ||
- | 866 | if (SIZEOF_ILF_STRINGS & (alignment - 1)) |
|
- | 867 | ptr += alignment - (SIZEOF_ILF_STRINGS & (alignment - 1)); |
|
- | 868 | } |
|
- | 869 | #endif |
|
836 | by the pe_ILF_make_a_section() function. */ |
870 | |
837 | vars.data = ptr; |
871 | vars.data = ptr; |
838 | vars.abfd = abfd; |
872 | vars.abfd = abfd; |
839 | vars.sec_index = 0; |
873 | vars.sec_index = 0; |
Line 969... | Line 1003... | ||
969 | (struct bfd_symbol **) imp_sym, |
1003 | (struct bfd_symbol **) imp_sym, |
970 | imp_index); |
1004 | imp_index); |
971 | } |
1005 | } |
972 | else |
1006 | else |
973 | #endif |
1007 | #endif |
- | 1008 | #ifdef AMD64MAGIC |
|
- | 1009 | if (magic == AMD64MAGIC) |
|
- | 1010 | { |
|
- | 1011 | pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset, |
|
- | 1012 | BFD_RELOC_32_PCREL, (asymbol **) imp_sym, |
|
- | 1013 | imp_index); |
|
- | 1014 | } |
|
- | 1015 | else |
|
- | 1016 | #endif |
|
974 | pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset, |
1017 | pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset, |
975 | BFD_RELOC_32, (asymbol **) imp_sym, |
1018 | BFD_RELOC_32, (asymbol **) imp_sym, |
976 | imp_index); |
1019 | imp_index); |
Line 977... | Line 1020... | ||
977 | 1020 | ||
Line 1075... | Line 1118... | ||
1075 | Decode the element and return the appropriate target. */ |
1118 | Decode the element and return the appropriate target. */ |
Line 1076... | Line 1119... | ||
1076 | 1119 | ||
1077 | static const bfd_target * |
1120 | static const bfd_target * |
1078 | pe_ILF_object_p (bfd * abfd) |
1121 | pe_ILF_object_p (bfd * abfd) |
1079 | { |
1122 | { |
1080 | bfd_byte buffer[16]; |
1123 | bfd_byte buffer[14]; |
1081 | bfd_byte * ptr; |
1124 | bfd_byte * ptr; |
1082 | char * symbol_name; |
1125 | char * symbol_name; |
1083 | char * source_dll; |
1126 | char * source_dll; |
1084 | unsigned int machine; |
1127 | unsigned int machine; |
1085 | bfd_size_type size; |
1128 | bfd_size_type size; |
1086 | unsigned int ordinal; |
1129 | unsigned int ordinal; |
1087 | unsigned int types; |
1130 | unsigned int types; |
Line 1088... | Line 1131... | ||
1088 | unsigned int magic; |
1131 | unsigned int magic; |
1089 | 1132 | ||
1090 | /* Upon entry the first four buyes of the ILF header have |
1133 | /* Upon entry the first six bytes of the ILF header have |
1091 | already been read. Now read the rest of the header. */ |
1134 | already been read. Now read the rest of the header. */ |
Line 1092... | Line 1135... | ||
1092 | if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16) |
1135 | if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14) |
Line 1093... | Line -... | ||
1093 | return NULL; |
- | |
1094 | - | ||
1095 | ptr = buffer; |
- | |
1096 | - | ||
1097 | /* We do not bother to check the version number. |
1136 | return NULL; |
1098 | version = H_GET_16 (abfd, ptr); */ |
1137 | |
Line 1099... | Line 1138... | ||
1099 | ptr += 2; |
1138 | ptr = buffer; |
1100 | 1139 | ||
Line 1246... | Line 1285... | ||
1246 | } |
1285 | } |
Line 1247... | Line 1286... | ||
1247 | 1286 | ||
1248 | return abfd->xvec; |
1287 | return abfd->xvec; |
Line -... | Line 1288... | ||
- | 1288 | } |
|
- | 1289 | ||
- | 1290 | static void |
|
- | 1291 | pe_bfd_read_buildid(bfd *abfd) |
|
- | 1292 | { |
|
- | 1293 | pe_data_type *pe = pe_data (abfd); |
|
- | 1294 | struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; |
|
- | 1295 | asection *section; |
|
- | 1296 | bfd_byte *data = 0; |
|
- | 1297 | bfd_size_type dataoff; |
|
- | 1298 | unsigned int i; |
|
- | 1299 | ||
- | 1300 | bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress; |
|
- | 1301 | bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size; |
|
- | 1302 | ||
- | 1303 | if (size == 0) |
|
- | 1304 | return; |
|
- | 1305 | ||
- | 1306 | addr += extra->ImageBase; |
|
- | 1307 | ||
- | 1308 | /* Search for the section containing the DebugDirectory */ |
|
- | 1309 | for (section = abfd->sections; section != NULL; section = section->next) |
|
- | 1310 | { |
|
- | 1311 | if ((addr >= section->vma) && (addr < (section->vma + section->size))) |
|
- | 1312 | break; |
|
- | 1313 | } |
|
- | 1314 | ||
- | 1315 | if (section == NULL) |
|
- | 1316 | { |
|
- | 1317 | return; |
|
- | 1318 | } |
|
- | 1319 | else if (!(section->flags & SEC_HAS_CONTENTS)) |
|
- | 1320 | { |
|
- | 1321 | return; |
|
- | 1322 | } |
|
- | 1323 | ||
- | 1324 | dataoff = addr - section->vma; |
|
- | 1325 | ||
- | 1326 | /* Read the whole section. */ |
|
- | 1327 | if (!bfd_malloc_and_get_section (abfd, section, &data)) |
|
- | 1328 | { |
|
- | 1329 | if (data != NULL) |
|
- | 1330 | free (data); |
|
- | 1331 | return; |
|
- | 1332 | } |
|
- | 1333 | ||
- | 1334 | /* Search for a CodeView entry in the DebugDirectory */ |
|
- | 1335 | for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++) |
|
- | 1336 | { |
|
- | 1337 | struct external_IMAGE_DEBUG_DIRECTORY *ext |
|
- | 1338 | = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i]; |
|
- | 1339 | struct internal_IMAGE_DEBUG_DIRECTORY idd; |
|
- | 1340 | ||
- | 1341 | _bfd_XXi_swap_debugdir_in (abfd, ext, &idd); |
|
- | 1342 | ||
- | 1343 | if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW) |
|
- | 1344 | { |
|
- | 1345 | char buffer[256 + 1]; |
|
- | 1346 | CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer; |
|
- | 1347 | ||
- | 1348 | /* |
|
- | 1349 | The debug entry doesn't have to have to be in a section, in which |
|
- | 1350 | case AddressOfRawData is 0, so always use PointerToRawData. |
|
- | 1351 | */ |
|
- | 1352 | if (_bfd_XXi_slurp_codeview_record (abfd, |
|
- | 1353 | (file_ptr) idd.PointerToRawData, |
|
- | 1354 | idd.SizeOfData, cvinfo)) |
|
- | 1355 | { |
|
- | 1356 | struct bfd_build_id* build_id = bfd_alloc(abfd, |
|
- | 1357 | sizeof(struct bfd_build_id) + cvinfo->SignatureLength); |
|
- | 1358 | if (build_id) |
|
- | 1359 | { |
|
- | 1360 | build_id->size = cvinfo->SignatureLength; |
|
- | 1361 | memcpy(build_id->data, cvinfo->Signature, |
|
- | 1362 | cvinfo->SignatureLength); |
|
- | 1363 | abfd->build_id = build_id; |
|
- | 1364 | } |
|
- | 1365 | } |
|
- | 1366 | break; |
|
- | 1367 | } |
|
- | 1368 | } |
|
1249 | } |
1369 | } |
1250 | 1370 | ||
1251 | static const bfd_target * |
1371 | static const bfd_target * |
1252 | pe_bfd_object_p (bfd * abfd) |
1372 | pe_bfd_object_p (bfd * abfd) |
1253 | { |
1373 | { |
1254 | bfd_byte buffer[4]; |
1374 | bfd_byte buffer[6]; |
1255 | struct external_PEI_DOS_hdr dos_hdr; |
1375 | struct external_PEI_DOS_hdr dos_hdr; |
1256 | struct external_PEI_IMAGE_hdr image_hdr; |
1376 | struct external_PEI_IMAGE_hdr image_hdr; |
1257 | struct internal_filehdr internal_f; |
1377 | struct internal_filehdr internal_f; |
1258 | struct internal_aouthdr internal_a; |
1378 | struct internal_aouthdr internal_a; |
- | 1379 | file_ptr opt_hdr_size; |
|
Line 1259... | Line 1380... | ||
1259 | file_ptr opt_hdr_size; |
1380 | file_ptr offset; |
- | 1381 | const bfd_target *result; |
|
1260 | file_ptr offset; |
1382 | |
1261 | 1383 | /* Detect if this a Microsoft Import Library Format element. */ |
|
1262 | /* Detect if this a Microsoft Import Library Format element. */ |
1384 | /* First read the beginning of the header. */ |
1263 | if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 |
1385 | if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 |
1264 | || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4) |
1386 | || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6) |
1265 | { |
1387 | { |
1266 | if (bfd_get_error () != bfd_error_system_call) |
1388 | if (bfd_get_error () != bfd_error_system_call) |
Line -... | Line 1389... | ||
- | 1389 | bfd_set_error (bfd_error_wrong_format); |
|
1267 | bfd_set_error (bfd_error_wrong_format); |
1390 | return NULL; |
- | 1391 | } |
|
1268 | return NULL; |
1392 | |
Line 1269... | Line 1393... | ||
1269 | } |
1393 | /* Then check the magic and the version (only 0 is supported). */ |
1270 | 1394 | if (H_GET_32 (abfd, buffer) == 0xffff0000 |
|
1271 | if (H_GET_32 (abfd, buffer) == 0xffff0000) |
1395 | && H_GET_16 (abfd, buffer + 4) == 0) |
Line 1312... | Line 1436... | ||
1312 | return NULL; |
1436 | return NULL; |
1313 | } |
1437 | } |
Line 1314... | Line 1438... | ||
1314 | 1438 | ||
1315 | /* Swap file header, so that we get the location for calling |
1439 | /* Swap file header, so that we get the location for calling |
1316 | real_object_p. */ |
1440 | real_object_p. */ |
Line 1317... | Line 1441... | ||
1317 | bfd_coff_swap_filehdr_in (abfd, (PTR)&image_hdr, &internal_f); |
1441 | bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f); |
1318 | 1442 | ||
1319 | if (! bfd_coff_bad_format_hook (abfd, &internal_f) |
1443 | if (! bfd_coff_bad_format_hook (abfd, &internal_f) |
1320 | || internal_f.f_opthdr > bfd_coff_aoutsz (abfd)) |
1444 | || internal_f.f_opthdr > bfd_coff_aoutsz (abfd)) |
Line 1326... | Line 1450... | ||
1326 | /* Read the optional header, which has variable size. */ |
1450 | /* Read the optional header, which has variable size. */ |
1327 | opt_hdr_size = internal_f.f_opthdr; |
1451 | opt_hdr_size = internal_f.f_opthdr; |
Line 1328... | Line 1452... | ||
1328 | 1452 | ||
1329 | if (opt_hdr_size != 0) |
1453 | if (opt_hdr_size != 0) |
- | 1454 | { |
|
1330 | { |
1455 | bfd_size_type amt = opt_hdr_size; |
- | 1456 | void * opthdr; |
|
- | 1457 | ||
- | 1458 | /* PR 17521 file: 230-131433-0.004. */ |
|
- | 1459 | if (amt < sizeof (PEAOUTHDR)) |
|
Line 1331... | Line 1460... | ||
1331 | PTR opthdr; |
1460 | amt = sizeof (PEAOUTHDR); |
1332 | 1461 | ||
1333 | opthdr = bfd_alloc (abfd, opt_hdr_size); |
1462 | opthdr = bfd_zalloc (abfd, amt); |
1334 | if (opthdr == NULL) |
1463 | if (opthdr == NULL) |
1335 | return NULL; |
1464 | return NULL; |
1336 | if (bfd_bread (opthdr, opt_hdr_size, abfd) |
1465 | if (bfd_bread (opthdr, opt_hdr_size, abfd) |
Line -... | Line 1466... | ||
- | 1466 | != (bfd_size_type) opt_hdr_size) |
|
1337 | != (bfd_size_type) opt_hdr_size) |
1467 | return NULL; |
- | 1468 | ||
- | 1469 | bfd_set_error (bfd_error_no_error); |
|
1338 | return NULL; |
1470 | bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a); |
Line -... | Line 1471... | ||
- | 1471 | if (bfd_get_error () != bfd_error_no_error) |
|
1339 | 1472 | return NULL; |
|
1340 | bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a); |
1473 | } |
1341 | } |
1474 | |
1342 | 1475 | ||
- | 1476 | result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f, |
|
- | 1477 | (opt_hdr_size != 0 |
|
- | 1478 | ? &internal_a |
|
- | 1479 | : (struct internal_aouthdr *) NULL)); |
|
- | 1480 | ||
- | 1481 | ||
- | 1482 | if (result) |
|
- | 1483 | { |
|
- | 1484 | /* Now the whole header has been processed, see if there is a build-id */ |
|
1343 | return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f, |
1485 | pe_bfd_read_buildid(abfd); |
Line 1344... | Line 1486... | ||
1344 | (opt_hdr_size != 0 |
1486 | } |
1345 | ? &internal_a |
1487 |