diff options
-rw-r--r-- | bfd/ChangeLog | 19 | ||||
-rw-r--r-- | bfd/bfd.c | 25 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 4 | ||||
-rw-r--r-- | bfd/elf-properties.c | 215 | ||||
-rw-r--r-- | binutils/ChangeLog | 14 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494a-x32.d | 11 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494a.d | 11 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494a.s | 92 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494b-x32.d | 5 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494b.d | 5 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494b.s | 30 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494c-x32.d | 10 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494c.d | 10 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494d-x32.d | 11 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/pr23494d.d | 11 |
15 files changed, 398 insertions, 75 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index dfa305d4885..d4bed23e582 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,24 @@ 2018-08-08 H.J. Lu <hongjiu.lu@intel.com> + PR binutils/23494 + * bfd.c (bfd_convert_section_size): Check BFD_DECOMPRESS after + calling _bfd_elf_convert_gnu_property_size to convert + .note.gnu.property section size. + (bfd_convert_section_contents): Check BFD_DECOMPRESS after + calling _bfd_elf_convert_gnu_properties to convert + .note.gnu.property section. + * elf-bfd.h (_bfd_elf_convert_gnu_property_size): New prototype. + (_bfd_elf_convert_gnu_properties): Likewise. + * elf-properties.c (elf_get_gnu_property_section_size): New + function. + (elf_write_gnu_properties): Likewise. + (_bfd_elf_convert_gnu_property_size): Likewise. + (_bfd_elf_convert_gnu_properties): Likewise. + (_bfd_elf_link_setup_gnu_properties): Use + elf_get_gnu_property_section_size and elf_write_gnu_properties. + +2018-08-08 H.J. Lu <hongjiu.lu@intel.com> + PR ld/23486 * elfxx-x86.c (_bfd_x86_elf_merge_gnu_properties): Remove GNU_PROPERTY_X86_ISA_1_USED if an input file doesn't have it. diff --git a/bfd/bfd.c b/bfd/bfd.c index 851710401e0..15becd7ae82 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -2469,10 +2469,6 @@ bfd_convert_section_size (bfd *ibfd, sec_ptr isec, bfd *obfd, { bfd_size_type hdr_size; - /* Do nothing if input file will be decompressed. */ - if ((ibfd->flags & BFD_DECOMPRESS)) - return size; - /* Do nothing if either input or output aren't ELF. */ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) @@ -2483,6 +2479,14 @@ bfd_convert_section_size (bfd *ibfd, sec_ptr isec, bfd *obfd, == get_elf_backend_data (obfd)->s->elfclass) return size; + /* Convert GNU property size. */ + if (CONST_STRNEQ (isec->name, NOTE_GNU_PROPERTY_SECTION_NAME)) + return _bfd_elf_convert_gnu_property_size (ibfd, obfd); + + /* Do nothing if input file will be decompressed. */ + if ((ibfd->flags & BFD_DECOMPRESS)) + return size; + /* Do nothing if the input section isn't a SHF_COMPRESSED section. */ hdr_size = bfd_get_compression_header_size (ibfd, isec); if (hdr_size == 0) @@ -2523,10 +2527,6 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd, Elf_Internal_Chdr chdr; bfd_boolean use_memmove; - /* Do nothing if input file will be decompressed. */ - if ((ibfd->flags & BFD_DECOMPRESS)) - return TRUE; - /* Do nothing if either input or output aren't ELF. */ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) @@ -2537,6 +2537,15 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd, == get_elf_backend_data (obfd)->s->elfclass) return TRUE; + /* Convert GNU properties. */ + if (CONST_STRNEQ (isec->name, NOTE_GNU_PROPERTY_SECTION_NAME)) + return _bfd_elf_convert_gnu_properties (ibfd, isec, obfd, ptr, + ptr_size); + + /* Do nothing if input file will be decompressed. */ + if ((ibfd->flags & BFD_DECOMPRESS)) + return TRUE; + /* Do nothing if the input section isn't a SHF_COMPRESSED section. */ ihdr_size = bfd_get_compression_header_size (ibfd, isec); if (ihdr_size == 0) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index ba1b495a09b..530679f9c8e 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2705,6 +2705,10 @@ extern elf_property * _bfd_elf_get_property (bfd *, unsigned int, unsigned int); extern bfd *_bfd_elf_link_setup_gnu_properties (struct bfd_link_info *); +extern bfd_size_type _bfd_elf_convert_gnu_property_size + (bfd *, bfd *); +extern bfd_boolean _bfd_elf_convert_gnu_properties + (bfd *, asection *, bfd *, bfd_byte **, bfd_size_type *); /* The linker may need to keep track of the number of relocs that it decides to copy as dynamic relocs in check_relocs for each symbol. diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index 50c0e9d7035..0ac055534d9 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -304,6 +304,94 @@ elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *abfd, } } +/* Get GNU property section size. */ + +static bfd_size_type +elf_get_gnu_property_section_size (elf_property_list *list, + unsigned int align_size) +{ + bfd_size_type size; + unsigned int descsz; + + /* Compute the output section size. */ + descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]); + descsz = (descsz + 3) & -(unsigned int) 4; + size = descsz; + for (; list != NULL; list = list->next) + { + /* There are 4 byte type + 4 byte datasz for each property. */ + size += 4 + 4 + list->property.pr_datasz; + /* Align each property. */ + size = (size + (align_size - 1)) & ~(align_size - 1); + } + + return size; +} + +/* Write GNU properties. */ + +static void +elf_write_gnu_properties (bfd *abfd, bfd_byte *contents, + elf_property_list *list, unsigned int size, + unsigned int align_size) +{ + unsigned int descsz; + Elf_External_Note *e_note; + + e_note = (Elf_External_Note *) contents; + descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]); + descsz = (descsz + 3) & -(unsigned int) 4; + bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz); + bfd_h_put_32 (abfd, size - descsz, &e_note->descsz); + bfd_h_put_32 (abfd, NT_GNU_PROPERTY_TYPE_0, &e_note->type); + memcpy (e_note->name, "GNU", sizeof "GNU"); + + size = descsz; + for (; list != NULL; list = list->next) + { + /* There are 4 byte type + 4 byte datasz for each property. */ + bfd_h_put_32 (abfd, list->property.pr_type, + contents + size); + bfd_h_put_32 (abfd, list->property.pr_datasz, + contents + size + 4); + size += 4 + 4; + + /* Write out property value. */ + switch (list->property.pr_kind) + { + case property_number: + switch (list->property.pr_datasz) + { + default: + /* Never should happen. */ + abort (); + + case 0: + break; + + case 4: + bfd_h_put_32 (abfd, list->property.u.number, + contents + size); + break; + + case 8: + bfd_h_put_64 (abfd, list->property.u.number, + contents + size); + break; + } + break; + + default: + /* Never should happen. */ + abort (); + } + size += list->property.pr_datasz; + + /* Align each property. */ + size = (size + (align_size - 1)) & ~ (align_size - 1); + } +} + /* Set up GNU properties. Return the first relocatable ELF input with GNU properties if found. Otherwise, return NULL. */ @@ -390,10 +478,8 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) always sorted by type even if input GNU properties aren't sorted. */ if (first_pbfd != NULL) { - unsigned int size; - unsigned int descsz; + bfd_size_type size; bfd_byte *contents; - Elf_External_Note *e_note; unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4; sec = bfd_get_section_by_name (first_pbfd, @@ -427,75 +513,15 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) } /* Compute the section size. */ - descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]); - descsz = (descsz + 3) & -(unsigned int) 4; - size = descsz; - for (list = elf_properties (first_pbfd); - list != NULL; - list = list->next) - { - /* There are 4 byte type + 4 byte datasz for each property. */ - size += 4 + 4 + list->property.pr_datasz; - /* Align each property. */ - size = (size + (align_size - 1)) & ~(align_size - 1); - } + list = elf_properties (first_pbfd); + size = elf_get_gnu_property_section_size (list, align_size); /* Update .note.gnu.property section now. */ sec->size = size; contents = (bfd_byte *) bfd_zalloc (first_pbfd, size); - e_note = (Elf_External_Note *) contents; - bfd_h_put_32 (first_pbfd, sizeof "GNU", &e_note->namesz); - bfd_h_put_32 (first_pbfd, size - descsz, &e_note->descsz); - bfd_h_put_32 (first_pbfd, NT_GNU_PROPERTY_TYPE_0, &e_note->type); - memcpy (e_note->name, "GNU", sizeof "GNU"); - - size = descsz; - for (list = elf_properties (first_pbfd); - list != NULL; - list = list->next) - { - /* There are 4 byte type + 4 byte datasz for each property. */ - bfd_h_put_32 (first_pbfd, list->property.pr_type, - contents + size); - bfd_h_put_32 (first_pbfd, list->property.pr_datasz, - contents + size + 4); - size += 4 + 4; - - /* Write out property value. */ - switch (list->property.pr_kind) - { - case property_number: - switch (list->property.pr_datasz) - { - default: - /* Never should happen. */ - abort (); - - case 0: - break; - - case 4: - bfd_h_put_32 (first_pbfd, list->property.u.number, - contents + size); - break; - - case 8: - bfd_h_put_64 (first_pbfd, list->property.u.number, - contents + size); - break; - } - break; - - default: - /* Never should happen. */ - abort (); - } - size += list->property.pr_datasz; - - /* Align each property. */ - size = (size + (align_size - 1)) & ~ (align_size - 1); - } + elf_write_gnu_properties (first_pbfd, contents, list, size, + align_size); /* Cache the section contents for elf_link_input_bfd. */ elf_section_data (sec)->this_hdr.contents = contents; @@ -508,3 +534,58 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info) return first_pbfd; } + +/* Convert GNU property size. */ + +bfd_size_type +_bfd_elf_convert_gnu_property_size (bfd *ibfd, bfd *obfd) +{ + unsigned int align_size; + const struct elf_backend_data *bed; + elf_property_list *list = elf_properties (ibfd); + + bed = get_elf_backend_data (obfd); + align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4; + + /* Get the output .note.gnu.property section size. */ + return elf_get_gnu_property_section_size (list, align_size); +} + +/* Convert GNU properties. */ + +bfd_boolean +_bfd_elf_convert_gnu_properties (bfd *ibfd, asection *isec, + bfd *obfd, bfd_byte **ptr, + bfd_size_type *ptr_size) +{ + unsigned int size; + bfd_byte *contents; + unsigned int align_shift; + const struct elf_backend_data *bed; + elf_property_list *list = elf_properties (ibfd); + + bed = get_elf_backend_data (obfd); + align_shift = bed->s->elfclass == ELFCLASS64 ? 3 : 2; + + /* Get the output .note.gnu.property section size. */ + size = bfd_get_section_size (isec->output_section); + + /* Update the output .note.gnu.property section alignment. */ + bfd_set_section_alignment (obfd, isec->output_section, align_shift); + + if (size > bfd_get_section_size (isec)) + { + contents = (bfd_byte *) bfd_malloc (size); + free (*ptr); + *ptr = contents; + } + else + contents = *ptr; + + *ptr_size = size; + + /* Generate the output .note.gnu.property section. */ + elf_write_gnu_properties (ibfd, contents, list, size, 1 << align_shift); + + return TRUE; +} diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6ed758b9b77..8dd2d78d530 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2018-08-08 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/23494 + * testsuite/binutils-all/x86-64/pr23494a-x32.d: New file. + * testsuite/binutils-all/x86-64/pr23494a.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494a.s: Likewise. + * testsuite/binutils-all/x86-64/pr23494b-x32.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494b.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494b.s: Likewise. + * testsuite/binutils-all/x86-64/pr23494c-x32.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494c.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494d-x32.d: Likewise. + * testsuite/binutils-all/x86-64/pr23494d.d: Likewise. + 2018-08-08 Kevin Buettner <kevinb@redhat.com> * dwarf.c (decode_location_expresion): Add case for diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494a-x32.d b/binutils/testsuite/binutils-all/x86-64/pr23494a-x32.d new file mode 100644 index 00000000000..6171e3c80c0 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494a-x32.d @@ -0,0 +1,11 @@ +#source: pr23494a.s +#PROG: objcopy +#as: --x32 +#objcopy: -O elf64-x86-64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: SSE3, SSE4_1 diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494a.d b/binutils/testsuite/binutils-all/x86-64/pr23494a.d new file mode 100644 index 00000000000..5e8b0b61c75 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494a.d @@ -0,0 +1,11 @@ +#source: pr23494a.s +#PROG: objcopy +#as: --64 -defsym __64_bit__=1 +#objcopy: -O elf32-x86-64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: SSE3, SSE4_1 diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494a.s b/binutils/testsuite/binutils-all/x86-64/pr23494a.s new file mode 100644 index 00000000000..77185bdc1a7 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494a.s @@ -0,0 +1,92 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length. */ + .long 3f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0 */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + /* GNU_PROPERTY_X86_ISA_1_USED */ + .long 0xc0000000 /* pr_type. */ + .long 5f - 4f /* pr_datasz. */ +4: + .long 0xa +5: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +3: + + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length. */ + .long 3f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0 */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + /* GNU_PROPERTY_X86_ISA_1_NEEDED */ + .long 0xc0000001 /* pr_type. */ + .long 5f - 4f /* pr_datasz. */ +4: + .long 0xa0 +5: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +3: + + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length. */ + .long 3f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0 */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + /* GNU_PROPERTY_X86_ISA_1_USED */ + .long 0xc0000000 /* pr_type. */ + .long 5f - 4f /* pr_datasz. */ +4: + .long 0xa0 +5: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +3: diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494b-x32.d b/binutils/testsuite/binutils-all/x86-64/pr23494b-x32.d new file mode 100644 index 00000000000..e0b351b51d7 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494b-x32.d @@ -0,0 +1,5 @@ +#source: pr23494a.s +#PROG: objcopy +#as: --x32 +#objcopy: -O elf64-x86-64 -R .note.gnu.property +#readelf: -n diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494b.d b/binutils/testsuite/binutils-all/x86-64/pr23494b.d new file mode 100644 index 00000000000..69c53407101 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494b.d @@ -0,0 +1,5 @@ +#source: pr23494a.s +#PROG: objcopy +#as: --64 -defsym __64_bit__=1 +#objcopy: -O elf32-x86-64 -R .note.gnu.property +#readelf: -n diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494b.s b/binutils/testsuite/binutils-all/x86-64/pr23494b.s new file mode 100644 index 00000000000..239477b082b --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494b.s @@ -0,0 +1,30 @@ + .section ".note.gnu.property", "a" +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + .long 1f - 0f /* name length. */ + .long 3f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0 */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif + /* GNU_PROPERTY_X86_ISA_1_USED */ + .long 0xc0000000 /* pr_type. */ + .long 5f - 4f /* pr_datasz. */ +4: + .long 0xa +5: +.ifdef __64_bit__ + .p2align 3 +.else + .p2align 2 +.endif +3: diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494c-x32.d b/binutils/testsuite/binutils-all/x86-64/pr23494c-x32.d new file mode 100644 index 00000000000..3f213dcd913 --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494c-x32.d @@ -0,0 +1,10 @@ +#source: pr23494b.s +#PROG: objcopy +#as: --x32 +#objcopy: -O elf64-x86-64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494c.d b/binutils/testsuite/binutils-all/x86-64/pr23494c.d new file mode 100644 index 00000000000..62500a8382a --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494c.d @@ -0,0 +1,10 @@ +#source: pr23494b.s +#PROG: objcopy +#as: --64 -defsym __64_bit__=1 +#objcopy: -O elf32-x86-64 +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494d-x32.d b/binutils/testsuite/binutils-all/x86-64/pr23494d-x32.d new file mode 100644 index 00000000000..106e6c05cbd --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494d-x32.d @@ -0,0 +1,11 @@ +#PROG: objcopy +#source: pr23494a.s +#as: --x32 +#objcopy: -O elf64-x86-64 --decompress-debug-sections +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: SSE3, SSE4_1 diff --git a/binutils/testsuite/binutils-all/x86-64/pr23494d.d b/binutils/testsuite/binutils-all/x86-64/pr23494d.d new file mode 100644 index 00000000000..bcbcbc5c1fd --- /dev/null +++ b/binutils/testsuite/binutils-all/x86-64/pr23494d.d @@ -0,0 +1,11 @@ +#PROG: objcopy +#source: pr23494a.s +#as: --64 -defsym __64_bit__=1 +#objcopy: -O elf32-x86-64 --decompress-debug-sections +#readelf: -n + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: x86 ISA used: 586, SSE, SSE3, SSE4_1 + x86 ISA needed: SSE3, SSE4_1 |