diff options
Diffstat (limited to 'elf')
| -rw-r--r-- | elf/Makefile | 17 | ||||
| -rw-r--r-- | elf/dl-addr.c | 3 | ||||
| -rw-r--r-- | elf/dl-lookup.c | 9 | ||||
| -rw-r--r-- | elf/elf.h | 3 | ||||
| -rw-r--r-- | elf/sprof.c | 6 | ||||
| -rw-r--r-- | elf/tst-secondary.h | 3 | ||||
| -rw-r--r-- | elf/tst-secondary1.c | 13 | ||||
| -rw-r--r-- | elf/tst-secondary1mod.c | 4 | ||||
| -rw-r--r-- | elf/tst-secondary2.c | 13 | ||||
| -rw-r--r-- | elf/tst-secondary2mod.c | 12 | ||||
| -rw-r--r-- | elf/tst-secondary3.c | 13 | ||||
| -rw-r--r-- | elf/tst-secondary3mod.c | 13 | ||||
| -rw-r--r-- | elf/tst-secondarymod.c | 9 |
13 files changed, 113 insertions, 5 deletions
diff --git a/elf/Makefile b/elf/Makefile index e5b142c7c6..15945367ec 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -254,6 +254,12 @@ modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 endif endif +ifeq (yes,$(have-secondary)) +tests += tst-secondary1 tst-secondary2 tst-secondary3 +modules-names += tst-secondarymod tst-secondary1mod tst-secondary2mod \ + tst-secondary3mod +endif + ifeq (yes,$(build-shared)) ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out @@ -1120,6 +1126,17 @@ $(objpfx)ifuncmain5static: $(addprefix $(objpfx),ifuncdep5.o) $(objpfx)ifuncmain5staticpic: $(addprefix $(objpfx),ifuncdep5pic.o) $(objpfx)ifuncmain5picstatic: $(addprefix $(objpfx),ifuncdep5pic.o) +LDFLAGS-tst-secondarymod.so = -Wl,-z,secondary + +$(objpfx)tst-secondary1: $(objpfx)tst-secondarymod.so \ + $(objpfx)tst-secondary1mod.so + +$(objpfx)tst-secondary2: $(objpfx)tst-secondarymod.so \ + $(objpfx)tst-secondary2mod.so + +$(objpfx)tst-secondary3: $(objpfx)tst-secondarymod.so \ + $(objpfx)tst-secondary3mod.so + $(objpfx)tst-unique1: $(libdl) $(objpfx)tst-unique1.out: $(objpfx)tst-unique1mod1.so \ $(objpfx)tst-unique1mod2.so diff --git a/elf/dl-addr.c b/elf/dl-addr.c index a025652c08..b4dd8887f5 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -87,7 +87,8 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, for (; (void *) symtab < (void *) symtabend; ++symtab) if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL - || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK) + || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK + || ELFW(ST_BIND) (symtab->st_info) == STB_SECONDARY) && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS && (symtab->st_shndx != SHN_UNDEF || symtab->st_value != 0) diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 5fa76ba675..91f5abe93f 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -465,10 +465,15 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, found_it: switch (ELFW(ST_BIND) (sym->st_info)) { + case STB_SECONDARY: + /* Secondary definition. Use this value if we don't find + another. */ + goto dynamic_weak; case STB_WEAK: /* Weak definition. Use this value if we don't find another. */ if (__glibc_unlikely (GLRO(dl_dynamic_weak))) { +dynamic_weak: if (! result->s) { result->s = sym; @@ -803,7 +808,9 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, if (__glibc_unlikely (current_value.s == NULL)) { - if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) + if ((*ref == NULL + || (ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK + && ELFW(ST_BIND) ((*ref)->st_info) != STB_SECONDARY)) && skip_map == NULL && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)) { @@ -447,7 +447,8 @@ typedef struct #define STB_LOCAL 0 /* Local symbol */ #define STB_GLOBAL 1 /* Global symbol */ #define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ +#define STB_SECONDARY 3 /* Secondary symbol */ +#define STB_NUM 4 /* Number of defined types. */ #define STB_LOOS 10 /* Start of OS-specific */ #define STB_GNU_UNIQUE 10 /* Unique symbol. */ #define STB_HIOS 12 /* End of OS-specific */ diff --git a/elf/sprof.c b/elf/sprof.c index 380b8d5437..3fdae4b019 100644 --- a/elf/sprof.c +++ b/elf/sprof.c @@ -1082,7 +1082,8 @@ read_symbols (struct shobj *shobj) newsym->name = &shobj->strtab[sym->st_name]; newsym->addr = sym->st_value; newsym->size = sym->st_size; - newsym->weak = ELFW(ST_BIND) (sym->st_info) == STB_WEAK; + newsym->weak = (ELFW(ST_BIND) (sym->st_info) == STB_SECONDARY + || ELFW(ST_BIND) (sym->st_info) == STB_WEAK); newsym->hidden = (ELFW(ST_VISIBILITY) (sym->st_other) != STV_DEFAULT); newsym->ticks = 0; @@ -1140,7 +1141,8 @@ read_symbols (struct shobj *shobj) newsym->name = &strtab[symtab->st_name]; newsym->addr = symtab->st_value; newsym->size = symtab->st_size; - newsym->weak = ELFW(ST_BIND) (symtab->st_info) == STB_WEAK; + newsym->weak = (ELFW(ST_BIND) (symtab->st_info) == STB_SECONDARY + || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK); newsym->hidden = (ELFW(ST_VISIBILITY) (symtab->st_other) != STV_DEFAULT); newsym->ticks = 0; diff --git a/elf/tst-secondary.h b/elf/tst-secondary.h new file mode 100644 index 0000000000..0487e25c60 --- /dev/null +++ b/elf/tst-secondary.h @@ -0,0 +1,3 @@ +#define GLOBAL 1 +#define WEAK 2 +#define SECONDARY 3 diff --git a/elf/tst-secondary1.c b/elf/tst-secondary1.c new file mode 100644 index 0000000000..f4d6edd722 --- /dev/null +++ b/elf/tst-secondary1.c @@ -0,0 +1,13 @@ +/* Verify that secdonary function is called. */ + +#include "tst-secondary.h" + +extern int bar (void); +extern void foo (void); + +int +main (void) +{ + foo (); + return bar () != SECONDARY; +} diff --git a/elf/tst-secondary1mod.c b/elf/tst-secondary1mod.c new file mode 100644 index 0000000000..cd0130cacd --- /dev/null +++ b/elf/tst-secondary1mod.c @@ -0,0 +1,4 @@ +void +foo (void) +{ +} diff --git a/elf/tst-secondary2.c b/elf/tst-secondary2.c new file mode 100644 index 0000000000..3f221cb172 --- /dev/null +++ b/elf/tst-secondary2.c @@ -0,0 +1,13 @@ +/* Verify that global function is called. */ + +#include "tst-secondary.h" + +extern int bar (void); +extern void foo (void); + +int +main (void) +{ + foo (); + return bar () != GLOBAL; +} diff --git a/elf/tst-secondary2mod.c b/elf/tst-secondary2mod.c new file mode 100644 index 0000000000..f9407a9b1c --- /dev/null +++ b/elf/tst-secondary2mod.c @@ -0,0 +1,12 @@ +#include "tst-secondary.h" + +int +bar (void) +{ + return GLOBAL; +} + +void +foo (void) +{ +} diff --git a/elf/tst-secondary3.c b/elf/tst-secondary3.c new file mode 100644 index 0000000000..b55baea6d6 --- /dev/null +++ b/elf/tst-secondary3.c @@ -0,0 +1,13 @@ +/* Verify that weak function is called. */ + +#include "tst-secondary.h" + +extern int bar (void); +extern void foo (void); + +int +main (void) +{ + foo (); + return bar () != WEAK; +} diff --git a/elf/tst-secondary3mod.c b/elf/tst-secondary3mod.c new file mode 100644 index 0000000000..edfb25bbb2 --- /dev/null +++ b/elf/tst-secondary3mod.c @@ -0,0 +1,13 @@ +#include "tst-secondary.h" + +int +__attribute__ ((weak)) +bar (void) +{ + return WEAK; +} + +void +foo (void) +{ +} diff --git a/elf/tst-secondarymod.c b/elf/tst-secondarymod.c new file mode 100644 index 0000000000..5363e99654 --- /dev/null +++ b/elf/tst-secondarymod.c @@ -0,0 +1,9 @@ +#include "tst-secondary.h" + +asm (".secondary bar"); + +int +bar (void) +{ + return SECONDARY; +} |
