From dc0f822bfed430e5b4f87f27c2e63171fa5fba28 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 2 Nov 2004 08:14:49 +0000 Subject: - Remove dynamic_size from struct elf_resolve. - Replace all open coded dynamic handling with a function. Reduces size. - Fold special MIPS dynamic code into the dynamic_info item. - Add RELRO support. - Support linking with "-z now". - prepare for DT_RELACOUNT/DT_RELCOUNT optimization. - Add -z now to ld.so linking, this is what ld.so does anyway so let the linker know that. --- ldso/include/dl-elf.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- ldso/include/dl-hash.h | 11 +++-------- 2 files changed, 51 insertions(+), 9 deletions(-) (limited to 'ldso/include') diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index d70d84ae4..a1237b09f 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -33,7 +33,7 @@ extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full int trace_loaded_objects); extern int _dl_linux_resolve(void); extern int _dl_fixup(struct dyn_elf *rpnt, int flag); - +extern void _dl_protect_relro (struct elf_resolve *l); /* * Datatype of a relocation on this platform @@ -42,16 +42,63 @@ extern int _dl_fixup(struct dyn_elf *rpnt, int flag); # define ELF_RELOC ElfW(Rela) # define DT_RELOC_TABLE_ADDR DT_RELA # define DT_RELOC_TABLE_SIZE DT_RELASZ +# define DT_RELOCCOUNT DT_RELACOUNT # define UNSUPPORTED_RELOC_TYPE DT_REL # define UNSUPPORTED_RELOC_STR "REL" #else # define ELF_RELOC ElfW(Rel) # define DT_RELOC_TABLE_ADDR DT_REL # define DT_RELOC_TABLE_SIZE DT_RELSZ +# define DT_RELOCCOUNT DT_RELCOUNT # define UNSUPPORTED_RELOC_TYPE DT_RELA # define UNSUPPORTED_RELOC_STR "RELA" #endif +/* OS and/or GNU dynamic extensions */ +#define OS_NUM 1 +#define DT_RELCONT_IDX DT_NUM + +#ifndef ARCH_DYNAMIC_INFO + /* define in arch specific code, if needed */ +# define ARCH_NUM 0 +#endif + +#define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM) + +extern void _dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr); + +static inline __attribute__((always_inline)) +void __dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr) +{ + for (; dpnt->d_tag; dpnt++) { + if (dpnt->d_tag < DT_NUM) { + dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val; +#ifndef __mips__ + if (dpnt->d_tag == DT_DEBUG) + dpnt->d_un.d_val = (unsigned long)debug_addr; +#endif + if (dpnt->d_tag == DT_BIND_NOW) + dynamic_info[DT_BIND_NOW] = 1; + if (dpnt->d_tag == DT_FLAGS && + (dpnt->d_un.d_val & DF_BIND_NOW)) + dynamic_info[DT_BIND_NOW] = 1; + if (dpnt->d_tag == DT_TEXTREL) + dynamic_info[DT_TEXTREL] = 1; + } else if (dpnt->d_tag < DT_LOPROC) { + if (dpnt->d_tag == DT_RELOCCOUNT) + dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val; + if (dpnt->d_tag == DT_FLAGS_1 && + (dpnt->d_un.d_val & DF_1_NOW)) + dynamic_info[DT_BIND_NOW] = 1; + } +#ifdef ARCH_DYNAMIC_INFO + else { + ARCH_DYNAMIC_INFO(dpnt, dynamic_info, debug_addr); + } +#endif + } +} + /* Reloc type classes as returned by elf_machine_type_class(). ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index 67484d260..60fdd2856 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -41,18 +41,13 @@ struct elf_resolve{ */ unsigned long nchain; unsigned long * chains; - unsigned long dynamic_info[24]; + unsigned long dynamic_info[DYNAMIC_SIZE]; - unsigned long dynamic_size; unsigned long n_phent; Elf32_Phdr * ppnt; -#if defined(__mips__) - /* Needed for MIPS relocation */ - unsigned long mips_gotsym; - unsigned long mips_local_gotno; - unsigned long mips_symtabno; -#endif + ElfW(Addr) relro_addr; + size_t relro_size; #ifdef __powerpc__ /* this is used to store the address of relocation data words, so -- cgit v1.2.3