From aaf4cbd98fda76af93ebea5241f65291ff6bcaac Mon Sep 17 00:00:00 2001 From: Salvatore Cro Date: Wed, 12 Jan 2011 10:27:16 +0100 Subject: Add protected symbols support for all architectures Protected symbols are global symbols for which interposition is not allowed. We manage them in generic _dl_lookup_hash function. To handle protected symbols we need to get a reference to the module that defines the symbol itself. So we pass a new parameter 'struct symbol_ref' to the __dl_lookup_hash that is defined as below: struct symbol_ref { const ElfW(Sym) *sym; struct elf_resolve *tpnt; }; The tpnt field is used as an ouput parameter and refers to the module which defines the protected symbol. Further it can be used as output parameter for TLS relocations and FDPIC case. The sym field is instead used as an input parameter to detect the visibility of the symbol we are looking-up. In this way we get rid of different signatures for _dl_lookup_hash, allowing to remove the _dl_find_hash wrapper. This new structure is also suitable for prelink integration. Signed-off-by: Salvatore Cro Signed-off-by: Carmelo Amoroso --- ldso/ldso/dl-hash.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'ldso/ldso/dl-hash.c') diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c index 0048734ba..6db81a90c 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -269,7 +269,7 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long * relocations or when we call an entry in the PLT table for the first time. */ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, - int type_class, struct elf_resolve **tpntp) + int type_class, struct symbol_ref *sym_ref) { struct elf_resolve *tpnt = NULL; ElfW(Sym) *symtab; @@ -283,6 +283,11 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name); #endif + if ((sym_ref) && (sym_ref->sym) && (ELF32_ST_VISIBILITY(sym_ref->sym->st_other) == STV_PROTECTED)) { + sym = sym_ref->sym; + if (mytpnt) + tpnt = mytpnt; + } else for (; rpnt; rpnt = rpnt->next) { tpnt = rpnt->dyn; @@ -337,9 +342,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve /* At this point we have found the requested symbol, do binding */ #if defined(USE_TLS) && USE_TLS if (ELF_ST_TYPE(sym->st_info) == STT_TLS) { - _dl_assert(tpntp != NULL); - *tpntp = tpnt; - + _dl_assert(sym_ref != NULL); + sym_ref->tpnt = tpnt; return (char *)sym->st_value; } #endif @@ -355,8 +359,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve #endif case STB_GLOBAL: #ifdef __FDPIC__ - if (tpntp) - *tpntp = tpnt; + if (sym_ref) + sym_ref->tpnt = tpnt; #endif return (char *)DL_FIND_HASH_VALUE(tpnt, type_class, sym); default: /* Local symbols not handled here */ @@ -364,8 +368,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve } } #ifdef __FDPIC__ - if (tpntp) - *tpntp = tpnt; + if (sym_ref) + sym_ref->tpnt = tpnt; #endif return weak_result; } -- cgit v1.2.3 From 8fb5b1cffd576ba9cec8c42df028e8afd6933dcd Mon Sep 17 00:00:00 2001 From: Carmelo Amoroso Date: Wed, 12 Jan 2011 12:07:39 +0100 Subject: ldso: get rid of _dl_lookup_hash Now _dl_find_hash and _dl_lookup_hash are exactly the same, we can get rid of the _dl_lookup_hash, reverting the _dl_find_hash from a wrapper of _dl_lookup_hash to its original role. Signed-off-by: Carmelo Amoroso --- ldso/ldso/dl-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ldso/ldso/dl-hash.c') diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c index 6db81a90c..0454d61bf 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -268,7 +268,7 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long * This function resolves externals, and this is either called when we process * relocations or when we call an entry in the PLT table for the first time. */ -char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, +char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt, int type_class, struct symbol_ref *sym_ref) { struct elf_resolve *tpnt = NULL; -- cgit v1.2.3