diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-06-18 07:18:02 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-06-18 07:19:01 -0700 |
commit | 5a767724d7e4d8dfe70a82edceaeaa6d57ff2b84 (patch) | |
tree | 003f3353aeeda64e64ce591c1a70d66380f4195e /bfd/elf-properties.c | |
parent | 982c3a65ca5dbea8d6de3afd934f0a06fef54383 (diff) | |
download | gdb-5a767724d7e4d8dfe70a82edceaeaa6d57ff2b84.zip gdb-5a767724d7e4d8dfe70a82edceaeaa6d57ff2b84.tar.gz gdb-5a767724d7e4d8dfe70a82edceaeaa6d57ff2b84.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf-properties.c')
-rw-r--r-- | bfd/elf-properties.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c index 25b9a40..56ee91d 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: <corrupt property (0x%x) size: 0x%x>"), + 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 (); } |