From: H.J. Lu Date: Fri, 18 Jun 2021 14:18:02 +0000 (-0700) Subject: elf: Add GNU_PROPERTY_UINT32_AND_XXX/GNU_PROPERTY_UINT32_OR_XXX X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5a767724d7e4d8dfe70a82edceaeaa6d57ff2b84;p=binutils-gdb.git elf: Add GNU_PROPERTY_UINT32_AND_XXX/GNU_PROPERTY_UINT32_OR_XXX Implement GNU_PROPERTY_UINT32_AND_XXX/GNU_PROPERTY_UINT32_OR_XXX: https://sourceware.org/pipermail/gnu-gabi/2021q1/000467.html 1. GNU_PROPERTY_UINT32_AND_LO..GNU_PROPERTY_UINT32_AND_HI #define GNU_PROPERTY_UINT32_AND_LO 0xb0000000 #define GNU_PROPERTY_UINT32_AND_HI 0xb0007fff A bit in the output pr_data field is set only if it is set in all relocatable input pr_data fields. If all bits in the the output pr_data field are zero, this property should be removed from output. If the bit is 1, all input relocatables have the feature. If the bit is 0 or the property is missing, the info is unknown. 2. GNU_PROPERTY_UINT32_OR_LO..GNU_PROPERTY_UINT32_OR_HI #define GNU_PROPERTY_UINT32_OR_LO 0xb0008000 #define GNU_PROPERTY_UINT32_OR_HI 0xb000ffff A bit in the output pr_data field is set if it is set in any relocatable input pr_data fields. If all bits in the the output pr_data field are zero, this property should be removed from output. If the bit is 1, some input relocatables have the feature. If the bit is 0 or the property is missing, the info is unknown. bfd/ * elf-properties.c (_bfd_elf_parse_gnu_properties): Handle GNU_PROPERTY_UINT32_AND_LO, GNU_PROPERTY_UINT32_AND_HI, GNU_PROPERTY_UINT32_OR_LO and GNU_PROPERTY_UINT32_OR_HI. (elf_merge_gnu_properties): Likewise. binutils/ * readelf.c (print_gnu_property_note): Handle GNU_PROPERTY_UINT32_AND_LO, GNU_PROPERTY_UINT32_AND_HI, GNU_PROPERTY_UINT32_OR_LO and GNU_PROPERTY_UINT32_OR_HI. include/ * elf/common.h (GNU_PROPERTY_UINT32_AND_LO): New. (GNU_PROPERTY_UINT32_AND_HI): Likewise. (GNU_PROPERTY_UINT32_OR_LO): Likewise. (GNU_PROPERTY_UINT32_OR_HI): Likewise. ld/ * testsuite/ld-elf/property-and-1.d: New file. * testsuite/ld-elf/property-and-1.s: Likewise. * testsuite/ld-elf/property-and-2.d: Likewise. * testsuite/ld-elf/property-and-2.s: Likewise. * testsuite/ld-elf/property-and-3.d: Likewise. * testsuite/ld-elf/property-and-3.s: Likewise. * testsuite/ld-elf/property-and-4.d: Likewise. * testsuite/ld-elf/property-and-empty.s: Likewise. * testsuite/ld-elf/property-or-1.d: Likewise. * testsuite/ld-elf/property-or-1.s: Likewise. * testsuite/ld-elf/property-or-2.d: Likewise. * testsuite/ld-elf/property-or-2.s: Likewise. * testsuite/ld-elf/property-or-3.d: Likewise. * testsuite/ld-elf/property-or-3.s: Likewise. * testsuite/ld-elf/property-or-4.d: Likewise. * testsuite/ld-elf/property-or-empty.s: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ad63f9cacfb..29e41a31a9e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2021-06-18 H.J. Lu + + * elf-properties.c (_bfd_elf_parse_gnu_properties): Handle + GNU_PROPERTY_UINT32_AND_LO, GNU_PROPERTY_UINT32_AND_HI, + GNU_PROPERTY_UINT32_OR_LO and GNU_PROPERTY_UINT32_OR_HI. + (elf_merge_gnu_properties): Likewise. + 2021-06-11 Alan Modra PR 27952 diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index 25b9a40f630..56ee91d7786 100644 --- a/bfd/elf-properties.c +++ b/bfd/elf-properties.c @@ -178,6 +178,25 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note) goto next; default: + if ((type >= GNU_PROPERTY_UINT32_AND_LO + && type <= GNU_PROPERTY_UINT32_AND_HI) + || (type >= GNU_PROPERTY_UINT32_OR_LO + && type <= GNU_PROPERTY_UINT32_OR_HI)) + { + if (datasz != 4) + { + _bfd_error_handler + (_("error: %pB: "), + abfd, type, datasz); + /* Clear all properties. */ + elf_properties (abfd) = NULL; + return false; + } + prop = _bfd_elf_get_property (abfd, type, datasz); + prop->u.number |= bfd_h_get_32 (abfd, ptr); + prop->pr_kind = property_number; + goto next; + } break; } } @@ -203,6 +222,8 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd, { const struct elf_backend_data *bed = get_elf_backend_data (abfd); unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type; + unsigned int number; + bool updated; if (bed->merge_gnu_properties != NULL && pr_type >= GNU_PROPERTY_LOPROC @@ -229,6 +250,75 @@ elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd, return aprop == NULL; default: + updated = false; + if (pr_type >= GNU_PROPERTY_UINT32_OR_LO + && pr_type <= GNU_PROPERTY_UINT32_OR_HI) + { + if (aprop != NULL && bprop != NULL) + { + number = aprop->u.number; + aprop->u.number = number | bprop->u.number; + /* Remove the property if all bits are empty. */ + if (aprop->u.number == 0) + { + aprop->pr_kind = property_remove; + updated = true; + } + else + updated = number != (unsigned int) aprop->u.number; + } + else + { + /* Only one of APROP and BPROP can be NULL. */ + if (aprop != NULL) + { + if (aprop->u.number == 0) + { + /* Remove APROP if all bits are empty. */ + aprop->pr_kind = property_remove; + updated = true; + } + } + else + { + /* Return TRUE if APROP is NULL and all bits of BPROP + aren't empty to indicate that BPROP should be added + to ABFD. */ + updated = bprop->u.number != 0; + } + } + return updated; + } + else if (pr_type >= GNU_PROPERTY_UINT32_AND_LO + && pr_type <= GNU_PROPERTY_UINT32_AND_HI) + { + /* Only one of APROP and BPROP can be NULL: + 1. APROP & BPROP when both APROP and BPROP aren't NULL. + 2. If APROP is NULL, remove x86 feature. + 3. Otherwise, do nothing. + */ + if (aprop != NULL && bprop != NULL) + { + number = aprop->u.number; + aprop->u.number = number & bprop->u.number; + updated = number != (unsigned int) aprop->u.number; + /* Remove the property if all feature bits are cleared. */ + if (aprop->u.number == 0) + aprop->pr_kind = property_remove; + } + else + { + /* There should be no AND properties since some input + doesn't have them. */ + if (aprop != NULL) + { + aprop->pr_kind = property_remove; + updated = true; + } + } + return updated; + } + /* Never should happen. */ abort (); } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index af73112c81f..125dd2e1a31 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2021-06-18 H.J. Lu + + * readelf.c (print_gnu_property_note): Handle + GNU_PROPERTY_UINT32_AND_LO, GNU_PROPERTY_UINT32_AND_HI, + GNU_PROPERTY_UINT32_OR_LO and GNU_PROPERTY_UINT32_OR_HI. + 2021-06-15 Nick Clifton * readelf.c (get_note_type): Add support for NT_GO_BUILDID. diff --git a/binutils/readelf.c b/binutils/readelf.c index 20100f11ce6..f7c64329f37 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -19507,6 +19507,21 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) goto next; default: + if ((type >= GNU_PROPERTY_UINT32_AND_LO + && type <= GNU_PROPERTY_UINT32_AND_HI) + || (type >= GNU_PROPERTY_UINT32_OR_LO + && type <= GNU_PROPERTY_UINT32_OR_HI)) + { + if (type <= GNU_PROPERTY_UINT32_AND_HI) + printf (_("UINT32_AND (%#x): "), type); + else + printf (_("UINT32_OR (%#x): "), type); + if (datasz != 4) + printf (_(" "), datasz); + else + printf ("%#x", (unsigned int) byte_get (ptr, 4)); + goto next; + } break; } } diff --git a/include/ChangeLog b/include/ChangeLog index b6bf28aa7c6..2a5b16fbea1 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2021-06-18 H.J. Lu + + * elf/common.h (GNU_PROPERTY_UINT32_AND_LO): New. + (GNU_PROPERTY_UINT32_AND_HI): Likewise. + (GNU_PROPERTY_UINT32_OR_LO): Likewise. + (GNU_PROPERTY_UINT32_OR_HI): Likewise. + 2021-06-15 Nick Clifton * elf/common.h (NT_GO_BUILDID): Define. diff --git a/include/elf/common.h b/include/elf/common.h index 58b0936db3b..0cca28673dd 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -782,6 +782,16 @@ #define GNU_PROPERTY_STACK_SIZE 1 #define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 +/* A 4-byte unsigned integer property: A bit is set if it is set in all + relocatable inputs. */ +#define GNU_PROPERTY_UINT32_AND_LO 0xb0000000 +#define GNU_PROPERTY_UINT32_AND_HI 0xb0007fff + +/* A 4-byte unsigned integer property: A bit is set if it is set in any + relocatable inputs. */ +#define GNU_PROPERTY_UINT32_OR_LO 0xb0008000 +#define GNU_PROPERTY_UINT32_OR_HI 0xb000ffff + /* Processor-specific semantics, lo */ #define GNU_PROPERTY_LOPROC 0xc0000000 /* Processor-specific semantics, hi */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 37a373b5db1..27434d6faa9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2021-06-18 H.J. Lu + + * testsuite/ld-elf/property-and-1.d: New file. + * testsuite/ld-elf/property-and-1.s: Likewise. + * testsuite/ld-elf/property-and-2.d: Likewise. + * testsuite/ld-elf/property-and-2.s: Likewise. + * testsuite/ld-elf/property-and-3.d: Likewise. + * testsuite/ld-elf/property-and-3.s: Likewise. + * testsuite/ld-elf/property-and-4.d: Likewise. + * testsuite/ld-elf/property-and-empty.s: Likewise. + * testsuite/ld-elf/property-or-1.d: Likewise. + * testsuite/ld-elf/property-or-1.s: Likewise. + * testsuite/ld-elf/property-or-2.d: Likewise. + * testsuite/ld-elf/property-or-2.s: Likewise. + * testsuite/ld-elf/property-or-3.d: Likewise. + * testsuite/ld-elf/property-or-3.s: Likewise. + * testsuite/ld-elf/property-or-4.d: Likewise. + * testsuite/ld-elf/property-or-empty.s: Likewise. + 2021-06-17 H.J. Lu PR ld/27973 diff --git a/ld/testsuite/ld-elf/property-and-1.d b/ld/testsuite/ld-elf/property-and-1.d new file mode 100644 index 00000000000..480d16e3704 --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-1.d @@ -0,0 +1,6 @@ +#source: empty.s +#source: property-and-1.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] diff --git a/ld/testsuite/ld-elf/property-and-1.s b/ld/testsuite/ld-elf/property-and-1.s new file mode 100644 index 00000000000..3cff33da2d9 --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-1.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb0007fff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x3 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-and-2.d b/ld/testsuite/ld-elf/property-and-2.d new file mode 100644 index 00000000000..007ba482e65 --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-2.d @@ -0,0 +1,7 @@ +#source: property-and-1.s +#source: empty.s +#source: property-and-2.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] diff --git a/ld/testsuite/ld-elf/property-and-2.s b/ld/testsuite/ld-elf/property-and-2.s new file mode 100644 index 00000000000..7149cb2d52b --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-2.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb0007fff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x101 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-and-3.d b/ld/testsuite/ld-elf/property-and-3.d new file mode 100644 index 00000000000..8d5e57915ef --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-3.d @@ -0,0 +1,7 @@ +#source: property-and-1.s +#source: property-and-empty.s +#source: property-and-2.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] diff --git a/ld/testsuite/ld-elf/property-and-3.s b/ld/testsuite/ld-elf/property-and-3.s new file mode 100644 index 00000000000..2838c9aef30 --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-3.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb0007fff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1001 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-and-4.d b/ld/testsuite/ld-elf/property-and-4.d new file mode 100644 index 00000000000..84bf404383f --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-4.d @@ -0,0 +1,12 @@ +#source: property-and-1.s +#source: property-and-2.s +#source: property-and-3.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: UINT32_AND \(0xb0007fff\): 0x1 diff --git a/ld/testsuite/ld-elf/property-and-empty.s b/ld/testsuite/ld-elf/property-and-empty.s new file mode 100644 index 00000000000..02669adf1f8 --- /dev/null +++ b/ld/testsuite/ld-elf/property-and-empty.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb0007fff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x0 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-or-1.d b/ld/testsuite/ld-elf/property-or-1.d new file mode 100644 index 00000000000..f5392c42cf9 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-1.d @@ -0,0 +1,11 @@ +#source: empty.s +#source: property-or-1.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: UINT32_OR \(0xb000ffff\): 0x3 diff --git a/ld/testsuite/ld-elf/property-or-1.s b/ld/testsuite/ld-elf/property-or-1.s new file mode 100644 index 00000000000..a4714180c17 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-1.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb000ffff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x3 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-or-2.d b/ld/testsuite/ld-elf/property-or-2.d new file mode 100644 index 00000000000..85b754833cb --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-2.d @@ -0,0 +1,12 @@ +#source: property-or-1.s +#source: empty.s +#source: property-or-2.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: UINT32_OR \(0xb000ffff\): 0x103 diff --git a/ld/testsuite/ld-elf/property-or-2.s b/ld/testsuite/ld-elf/property-or-2.s new file mode 100644 index 00000000000..a26047dab32 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-2.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb000ffff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x101 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-or-3.d b/ld/testsuite/ld-elf/property-or-3.d new file mode 100644 index 00000000000..2d687db4a61 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-3.d @@ -0,0 +1,12 @@ +#source: property-or-1.s +#source: property-and-empty.s +#source: property-or-2.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: UINT32_OR \(0xb000ffff\): 0x103 diff --git a/ld/testsuite/ld-elf/property-or-3.s b/ld/testsuite/ld-elf/property-or-3.s new file mode 100644 index 00000000000..d3e7367ea49 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-3.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb000ffff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1001 +4: + .p2align ALIGN +5: diff --git a/ld/testsuite/ld-elf/property-or-4.d b/ld/testsuite/ld-elf/property-or-4.d new file mode 100644 index 00000000000..fee22b155c6 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-4.d @@ -0,0 +1,12 @@ +#source: property-or-1.s +#source: property-or-2.s +#source: property-or-3.s +#as: +#ld: -shared +#readelf: -n +#xfail: ![check_shared_lib_support] + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0 + Properties: UINT32_OR \(0xb000ffff\): 0x1103 diff --git a/ld/testsuite/ld-elf/property-or-empty.s b/ld/testsuite/ld-elf/property-or-empty.s new file mode 100644 index 00000000000..f37e1dc7d69 --- /dev/null +++ b/ld/testsuite/ld-elf/property-or-empty.s @@ -0,0 +1,15 @@ + .section ".note.gnu.property", "a" + .p2align ALIGN + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align ALIGN +2: .long 0xb000ffff /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x0 +4: + .p2align ALIGN +5: