Message ID | 20210708163255.812-2-vivek@collabora.com |
---|---|
State | New |
Headers | show |
Series | Implementation of RTLD_SHARED for dlmopen | expand |
On 08/07/2021 13:32, Vivek Das Mohapatra via Libc-alpha wrote: > Define a new flags section DT_GNU_FLAGS_1 (no more bits are available > in DT_GNU_FLAGS). > > One flag is currently defined: DF_GNU_1_UNIQUE. > > libc and its companion DSOs (libpthread et al) should have this > section and flag set. LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > elf/elf.h | 7 ++++++- > elf/get-dynamic-info.h | 12 ++++++++++++ > include/elf.h | 2 ++ > include/link.h | 1 + > 4 files changed, 21 insertions(+), 1 deletion(-) > > diff --git a/elf/elf.h b/elf/elf.h > index 2a62b98d4a..448c275d10 100644 > --- a/elf/elf.h > +++ b/elf/elf.h > @@ -896,6 +896,7 @@ typedef struct > Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's > approach. */ > #define DT_VALRNGLO 0x6ffffd00 > +#define DT_GNU_FLAGS_1 0x6ffffdf4 /* GNU extension flags */ > #define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ > #define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ > #define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ > @@ -910,7 +911,7 @@ typedef structselectable > #define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ > #define DT_VALRNGHI 0x6ffffdff > #define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ > -#define DT_VALNUM 12 > +#define DT_VALNUM 13 > > /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the > Dyn.d_un.d_ptr field of the Elf*_Dyn structure. Ok. > @@ -999,6 +1000,10 @@ typedef struct > #define DF_1_WEAKFILTER 0x20000000 > #define DF_1_NOCOMMON 0x40000000 > > +/* State flags selectable in the `d_un.d_val' element of the DT_GNU_FLAGS_1 > + entry in the dynamic section. */ > +#define DF_GNU_1_UNIQUE 0x00000001 /* Load max 1 copy of this DSO. */ > + > /* Flags for the feature selection in DT_FEATURE_1. */ > #define DTF_1_PARINIT 0x00000001 > #define DTF_1_CONFEXP 0x00000002 Ok. > diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h > index d8ec32377d..8082d84ba1 100644 > --- a/elf/get-dynamic-info.h > +++ b/elf/get-dynamic-info.h > @@ -175,6 +175,18 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) > if (l->l_flags_1 & DF_1_NOW) > info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; > } > + if (info[DT_VALTAGIDX (DT_GNU_FLAGS_1) > + + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM] != NULL) > + { > + l->l_gnu_flags_1 = info[DT_VALTAGIDX (DT_GNU_FLAGS_1) > + + DT_NUM + DT_THISPROCNUM > + + DT_VERSIONTAGNUM + DT_EXTRANUM]->d_un.d_val; > + > + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES) > + && l->l_gnu_flags_1 & ~DT_GNU_1_SUPPORTED_MASK) > + _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_GNU_FLAGS_1.\n", > + l->l_gnu_flags_1 & ~DT_GNU_1_SUPPORTED_MASK); > + } > if (info[DT_RUNPATH] != NULL) > /* If both RUNPATH and RPATH are given, the latter is ignored. */ > info[DT_RPATH] = NULL; Ok. > diff --git a/include/elf.h b/include/elf.h > index 14ed67ff67..5eee37c294 100644 > --- a/include/elf.h > +++ b/include/elf.h > @@ -25,5 +25,7 @@ > (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \ > | DF_1_ORIGIN | DF_1_NODEFLIB | DF_1_PIE) > > +#define DT_GNU_1_SUPPORTED_MASK DF_GNU_1_UNIQUE > + > #endif /* !_ISOMAC */ > #endif /* elf.h */ Ok. > diff --git a/include/link.h b/include/link.h > index 4af16cb596..6ed35eb808 100644 > --- a/include/link.h > +++ b/include/link.h > @@ -283,6 +283,7 @@ struct link_map > unsigned int l_used; > > /* Various flag words. */ > + ElfW(Word) l_gnu_flags_1; > ElfW(Word) l_feature_1; > ElfW(Word) l_flags_1; > ElfW(Word) l_flags; > OK.
diff --git a/elf/elf.h b/elf/elf.h index 2a62b98d4a..448c275d10 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -896,6 +896,7 @@ typedef struct Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's approach. */ #define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_FLAGS_1 0x6ffffdf4 /* GNU extension flags */ #define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ #define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ #define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ @@ -910,7 +911,7 @@ typedef struct #define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ #define DT_VALRNGHI 0x6ffffdff #define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -#define DT_VALNUM 12 +#define DT_VALNUM 13 /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the Dyn.d_un.d_ptr field of the Elf*_Dyn structure. @@ -999,6 +1000,10 @@ typedef struct #define DF_1_WEAKFILTER 0x20000000 #define DF_1_NOCOMMON 0x40000000 +/* State flags selectable in the `d_un.d_val' element of the DT_GNU_FLAGS_1 + entry in the dynamic section. */ +#define DF_GNU_1_UNIQUE 0x00000001 /* Load max 1 copy of this DSO. */ + /* Flags for the feature selection in DT_FEATURE_1. */ #define DTF_1_PARINIT 0x00000001 #define DTF_1_CONFEXP 0x00000002 diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index d8ec32377d..8082d84ba1 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -175,6 +175,18 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) if (l->l_flags_1 & DF_1_NOW) info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)]; } + if (info[DT_VALTAGIDX (DT_GNU_FLAGS_1) + + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM] != NULL) + { + l->l_gnu_flags_1 = info[DT_VALTAGIDX (DT_GNU_FLAGS_1) + + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM + DT_EXTRANUM]->d_un.d_val; + + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES) + && l->l_gnu_flags_1 & ~DT_GNU_1_SUPPORTED_MASK) + _dl_debug_printf ("\nWARNING: Unsupported flag value(s) of 0x%x in DT_GNU_FLAGS_1.\n", + l->l_gnu_flags_1 & ~DT_GNU_1_SUPPORTED_MASK); + } if (info[DT_RUNPATH] != NULL) /* If both RUNPATH and RPATH are given, the latter is ignored. */ info[DT_RPATH] = NULL; diff --git a/include/elf.h b/include/elf.h index 14ed67ff67..5eee37c294 100644 --- a/include/elf.h +++ b/include/elf.h @@ -25,5 +25,7 @@ (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \ | DF_1_ORIGIN | DF_1_NODEFLIB | DF_1_PIE) +#define DT_GNU_1_SUPPORTED_MASK DF_GNU_1_UNIQUE + #endif /* !_ISOMAC */ #endif /* elf.h */ diff --git a/include/link.h b/include/link.h index 4af16cb596..6ed35eb808 100644 --- a/include/link.h +++ b/include/link.h @@ -283,6 +283,7 @@ struct link_map unsigned int l_used; /* Various flag words. */ + ElfW(Word) l_gnu_flags_1; ElfW(Word) l_feature_1; ElfW(Word) l_flags_1; ElfW(Word) l_flags;