diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-11-02 08:14:49 +0000 |
---|---|---|
committer | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-11-02 08:14:49 +0000 |
commit | dc0f822bfed430e5b4f87f27c2e63171fa5fba28 (patch) | |
tree | 01eda5fa3c42d0c8b114f76622b4794a7735aa41 /ldso/include/dl-elf.h | |
parent | f8f7b102217864ea382a46bb9ad173b3493e5cae (diff) |
- 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.
Diffstat (limited to 'ldso/include/dl-elf.h')
-rw-r--r-- | ldso/include/dl-elf.h | 49 |
1 files changed, 48 insertions, 1 deletions
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 |