summaryrefslogtreecommitdiff
path: root/ldso/include
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/include')
-rw-r--r--ldso/include/dl-elf.h21
-rw-r--r--ldso/include/dl-hash.h25
-rw-r--r--ldso/include/ldso.h10
3 files changed, 53 insertions, 3 deletions
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 9d8da0d13..3e418622d 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -84,8 +84,11 @@ extern void _dl_protect_relro (struct elf_resolve *l);
#endif
/* OS and/or GNU dynamic extensions */
-#define OS_NUM 1
-#define DT_RELCONT_IDX DT_NUM
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+# define OS_NUM 2 /* for DT_RELOCCOUNT and DT_GNU_HASH entries */
+#else
+# define OS_NUM 1 /* for DT_RELOCCOUNT entry */
+#endif
#ifndef ARCH_DYNAMIC_INFO
/* define in arch specific code, if needed */
@@ -93,6 +96,13 @@ extern void _dl_protect_relro (struct elf_resolve *l);
#endif
#define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM)
+/* Keep ARCH specific entries into dynamic section at the end of the array */
+#define DT_RELCONT_IDX (DYNAMIC_SIZE - OS_NUM - ARCH_NUM)
+
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+/* GNU hash comes just after the relocation count */
+# define DT_GNU_HASH_IDX (DT_RELCONT_IDX + 1)
+#endif
extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
void *debug_addr, DL_LOADADDR_TYPE load_off);
@@ -131,6 +141,10 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
if (dpnt->d_tag == DT_FLAGS_1 &&
(dpnt->d_un.d_val & DF_1_NOW))
dynamic_info[DT_BIND_NOW] = 1;
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+ if (dpnt->d_tag == DT_GNU_HASH)
+ dynamic_info[DT_GNU_HASH_IDX] = dpnt->d_un.d_ptr;
+#endif
}
#ifdef ARCH_DYNAMIC_INFO
else {
@@ -149,6 +163,9 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
ADJUST_DYN_INFO(DT_SYMTAB, load_off);
ADJUST_DYN_INFO(DT_RELOC_TABLE_ADDR, load_off);
ADJUST_DYN_INFO(DT_JMPREL, load_off);
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+ ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
+#endif
#undef ADJUST_DYN_INFO
}
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index c21094020..5239467c1 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -40,14 +40,39 @@ struct elf_resolve {
unsigned short int init_flag;
unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
Elf_Symndx nbucket;
+
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+ /* Data needed to support GNU hash style */
+ Elf32_Word l_gnu_bitmask_idxbits;
+ Elf32_Word l_gnu_shift;
+ const ElfW(Addr) *l_gnu_bitmask;
+
+ union
+ {
+ const Elf32_Word *l_gnu_chain_zero;
+ const Elf_Symndx *elf_buckets;
+ };
+#else
Elf_Symndx *elf_buckets;
+#endif
+
struct init_fini_list *init_fini;
struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
/*
* These are only used with ELF style shared libraries
*/
Elf_Symndx nchain;
+
+#ifdef __LDSO_GNU_HASH_SUPPORT__
+ union
+ {
+ const Elf32_Word *l_gnu_buckets;
+ const Elf_Symndx *chains;
+ };
+#else
Elf_Symndx *chains;
+#endif
+
unsigned long dynamic_info[DYNAMIC_SIZE];
unsigned long n_phent;
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h
index 40ac12a57..d96d137e9 100644
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -66,9 +66,17 @@ extern int _dl_debug_file;
_dl_dprintf(_dl_debug_file, "%s:%i: " fmt, __FUNCTION__, __LINE__, ## args);
# define _dl_if_debug_dprint(fmt, args...) \
do { if (_dl_debug) __dl_debug_dprint(fmt, ## args); } while (0)
+# define _dl_assert(expr) \
+ do { \
+ if (!(expr)) { \
+ __dl_debug_dprint("assert(%s)\n", #expr); \
+ _dl_exit(45); \
+ } \
+ } while (0)
#else
-# define _dl_debug_dprint(fmt, args...)
+# define __dl_debug_dprint(fmt, args...)
# define _dl_if_debug_dprint(fmt, args...)
+# define _dl_assert(expr)
# define _dl_debug_file 2
#endif /* __SUPPORT_LD_DEBUG__ */