Initial support for GNU_PROPERTY_1_NEEDED

1. Add GNU_PROPERTY_1_NEEDED:

 #define GNU_PROPERTY_1_NEEDED      GNU_PROPERTY_UINT32_OR_LO

to indicate the needed properties by the object file.
2. Add GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:

 #define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0)

to indicate that the object file requires canonical function pointers and
cannot be used with copy relocation.
3. Scan GNU_PROPERTY_1_NEEDED property and store it in l_1_needed.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
H.J. Lu 2021-06-18 11:53:55 -07:00
parent 1836bb2ebf
commit 1bd888d0b7
5 changed files with 43 additions and 7 deletions

View File

@ -1312,6 +1312,23 @@ typedef struct
/* No copy relocation on protected data symbol. */ /* No copy relocation on protected data symbol. */
#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 #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
/* The needed properties by the object file. */
#define GNU_PROPERTY_1_NEEDED GNU_PROPERTY_UINT32_OR_LO
/* Set if the object file requires canonical function pointers and
cannot be used with copy relocation. */
#define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0)
/* Processor-specific semantics, lo */ /* Processor-specific semantics, lo */
#define GNU_PROPERTY_LOPROC 0xc0000000 #define GNU_PROPERTY_LOPROC 0xc0000000
/* Processor-specific semantics, hi */ /* Processor-specific semantics, hi */

View File

@ -47,7 +47,14 @@ static inline int __attribute__ ((always_inline))
_dl_process_gnu_property (struct link_map *l, int fd, uint32_t type, _dl_process_gnu_property (struct link_map *l, int fd, uint32_t type,
uint32_t datasz, void *data) uint32_t datasz, void *data)
{ {
return 0; /* Continue until GNU_PROPERTY_1_NEEDED is found. */
if (type == GNU_PROPERTY_1_NEEDED)
{
if (datasz == 4)
l->l_1_needed = *(unsigned int *) data;
return 0;
}
return 1;
} }
#endif /* _DL_PROP_H */ #endif /* _DL_PROP_H */

View File

@ -1 +1,2 @@
/* No architecture specific definitions. */ /* GNU_PROPERTY_1_NEEDED of this object. */
unsigned int l_1_needed;

View File

@ -97,6 +97,7 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
const ElfW(Addr) start = (ElfW(Addr)) note; const ElfW(Addr) start = (ElfW(Addr)) note;
unsigned int needed_1 = 0;
unsigned int feature_1_and = 0; unsigned int feature_1_and = 0;
unsigned int isa_1_needed = 0; unsigned int isa_1_needed = 0;
unsigned int last_type = 0; unsigned int last_type = 0;
@ -141,7 +142,8 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
last_type = type; last_type = type;
if (type == GNU_PROPERTY_X86_FEATURE_1_AND if (type == GNU_PROPERTY_X86_FEATURE_1_AND
|| type == GNU_PROPERTY_X86_ISA_1_NEEDED) || type == GNU_PROPERTY_X86_ISA_1_NEEDED
|| type == GNU_PROPERTY_1_NEEDED)
{ {
/* The sizes of types which we are searching for are /* The sizes of types which we are searching for are
4 bytes. There is no point to continue if this 4 bytes. There is no point to continue if this
@ -151,12 +153,18 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
/* NB: Stop the scan only after seeing all types which /* NB: Stop the scan only after seeing all types which
we are searching for. */ we are searching for. */
_Static_assert ((GNU_PROPERTY_X86_ISA_1_NEEDED > _Static_assert (((GNU_PROPERTY_X86_ISA_1_NEEDED
GNU_PROPERTY_X86_FEATURE_1_AND), > GNU_PROPERTY_X86_FEATURE_1_AND)
&& (GNU_PROPERTY_X86_FEATURE_1_AND
> GNU_PROPERTY_1_NEEDED)),
"GNU_PROPERTY_X86_ISA_1_NEEDED > " "GNU_PROPERTY_X86_ISA_1_NEEDED > "
"GNU_PROPERTY_X86_FEATURE_1_AND"); "GNU_PROPERTY_X86_FEATURE_1_AND && "
"GNU_PROPERTY_X86_FEATURE_1_AND > "
"GNU_PROPERTY_1_NEEDED");
if (type == GNU_PROPERTY_X86_FEATURE_1_AND) if (type == GNU_PROPERTY_X86_FEATURE_1_AND)
feature_1_and = *(unsigned int *) ptr; feature_1_and = *(unsigned int *) ptr;
else if (type == GNU_PROPERTY_1_NEEDED)
needed_1 = *(unsigned int *) ptr;
else else
{ {
isa_1_needed = *(unsigned int *) ptr; isa_1_needed = *(unsigned int *) ptr;
@ -187,9 +195,10 @@ _dl_process_property_note (struct link_map *l, const ElfW(Nhdr) *note,
} }
/* We get here only if there is one or no GNU property note. */ /* We get here only if there is one or no GNU property note. */
if (isa_1_needed != 0 || feature_1_and != 0) if (needed_1 != 0 || isa_1_needed != 0 || feature_1_and != 0)
{ {
l->l_property = lc_property_valid; l->l_property = lc_property_valid;
l->l_1_needed = needed_1;
l->l_x86_isa_1_needed = isa_1_needed; l->l_x86_isa_1_needed = isa_1_needed;
l->l_x86_feature_1_and = feature_1_and; l->l_x86_feature_1_and = feature_1_and;
} }

View File

@ -29,3 +29,5 @@ unsigned int l_x86_feature_1_and;
/* GNU_PROPERTY_X86_ISA_1_NEEDED of this object. */ /* GNU_PROPERTY_X86_ISA_1_NEEDED of this object. */
unsigned int l_x86_isa_1_needed; unsigned int l_x86_isa_1_needed;
#include <sysdeps/generic/link_map.h>