summaryrefslogtreecommitdiff
path: root/ldso/include/dl-elf.h
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-02 08:14:49 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-02 08:14:49 +0000
commitdc0f822bfed430e5b4f87f27c2e63171fa5fba28 (patch)
tree01eda5fa3c42d0c8b114f76622b4794a7735aa41 /ldso/include/dl-elf.h
parentf8f7b102217864ea382a46bb9ad173b3493e5cae (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.h49
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