summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/include/dl-elf.h5
-rw-r--r--ldso/include/dl-hash.h6
-rw-r--r--ldso/include/ldso.h3
-rw-r--r--ldso/ldso/dl-elf.c70
-rw-r--r--ldso/ldso/dl-hash.c9
-rw-r--r--ldso/ldso/ldso.c14
6 files changed, 66 insertions, 41 deletions
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 29d1a007f..060ee3dfb 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -222,11 +222,6 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
#ifdef __DSBT__
/* Get the mapped address of the DSBT base. */
ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
-
- /* Initialize loadmap dsbt info. */
- load_off.map->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX];
- load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
- load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
#endif
#undef ADJUST_DYN_INFO
return rtld_flags;
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index c7effc588..7bccdca96 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -139,6 +139,12 @@ struct elf_resolve {
memory when the module is dlclose()d. */
struct funcdesc_ht *funcdesc_ht;
#endif
+#ifdef __DSBT__
+ /* Information for DSBT */
+ void **dsbt_table;
+ unsigned long dsbt_size;
+ unsigned long dsbt_index;
+#endif
};
#define RELOCS_DONE 0x000001
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h
index 6f3b728c3..cb7b12218 100644
--- a/ldso/include/ldso.h
+++ b/ldso/include/ldso.h
@@ -84,6 +84,9 @@ extern struct elf_resolve *_dl_trace_prelink_map; /* Library map for prelinking
#else
#define _dl_trace_prelink 0
#endif
+#ifdef __DSBT__
+extern void **_dl_ldso_dsbt;
+#endif
#if defined(USE_TLS) && USE_TLS
extern void _dl_add_to_slotinfo (struct link_map *l);
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 9e2a12ce7..31ba11ffa 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -851,10 +851,15 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
/* Handle DSBT initialization */
{
struct elf_resolve *t, *ref;
- int idx = tpnt->loadaddr.map->dsbt_index;
- unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
+ int idx = tpnt->dsbt_index;
+ void **dsbt = tpnt->dsbt_table;
- if (idx == 0) {
+ /*
+ * It is okay (required actually) to have zero idx for an executable.
+ * This is the case when running ldso standalone and the program
+ * is being mapped in via _dl_load_shared_library().
+ */
+ if (idx == 0 && tpnt->libtype != elf_executable) {
if (!dynamic_info[DT_TEXTREL]) {
/* This DSO has not been assigned an index. */
_dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n",
@@ -869,9 +874,9 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
break;
}
}
- idx = tpnt->loadaddr.map->dsbt_size;
+ idx = tpnt->dsbt_size;
while (idx-- > 0)
- if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL)
+ if (!ref || ref->dsbt_table[idx] == NULL)
break;
if (idx <= 0) {
_dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n",
@@ -880,43 +885,36 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
}
_dl_if_debug_dprint("\n\tfile='%s'; assigned index %d\n",
libname, idx);
- tpnt->loadaddr.map->dsbt_index = idx;
+ tpnt->dsbt_index = idx;
+ }
+ /* make sure index is not already used */
+ if (_dl_ldso_dsbt[idx]) {
+ struct elf_resolve *dup;
+ const char *dup_name;
+
+ for (dup = _dl_loaded_modules; dup; dup = dup->next)
+ if (dup != tpnt && dup->dsbt_index == idx)
+ break;
+ if (dup)
+ dup_name = dup->libname;
+ else if (idx == 1)
+ dup_name = "runtime linker";
+ else
+ dup_name = "unknown library";
+ _dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n",
+ _dl_progname, libname, idx, dup_name);
+ _dl_exit(1);
}
/*
* Setup dsbt slot for this module in dsbt of all modules.
*/
- ref = NULL;
- for (t = _dl_loaded_modules; t; t = t->next) {
- /* find a dsbt table from another module */
- if (ref == NULL && t != tpnt) {
- ref = t;
-
- /* make sure index is not already used */
- if (t->loadaddr.map->dsbt_table[idx]) {
- struct elf_resolve *dup;
- char *dup_name;
-
- for (dup = _dl_loaded_modules; dup; dup = dup->next)
- if (dup != tpnt && dup->loadaddr.map->dsbt_index == idx)
- break;
- if (dup)
- dup_name = dup->libname;
- else if (idx == 1)
- dup_name = "runtime linker";
- else
- dup_name = "unknown library";
- _dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n",
- _dl_progname, libname, idx, dup_name);
- _dl_exit(1);
- }
- }
- t->loadaddr.map->dsbt_table[idx] = (unsigned)dsbt;
- }
- if (ref)
- _dl_memcpy(dsbt, ref->loadaddr.map->dsbt_table,
- tpnt->loadaddr.map->dsbt_size * sizeof(unsigned *));
+ for (t = _dl_loaded_modules; t; t = t->next)
+ t->dsbt_table[idx] = dsbt;
+ _dl_ldso_dsbt[idx] = dsbt;
+ _dl_memcpy(dsbt, _dl_ldso_dsbt,
+ tpnt->dsbt_size * sizeof(tpnt->dsbt_table[0]));
}
#endif
_dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index 36ebec684..2c659dc58 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -115,6 +115,15 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;
tpnt->libtype = loaded_file;
+#ifdef __DSBT__
+ if (dynamic_info[DT_DSBT_BASE_IDX] != 0)
+ tpnt->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX];
+ if (dynamic_info[DT_DSBT_SIZE_IDX] != 0)
+ tpnt->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
+ if (dynamic_info[DT_DSBT_INDEX_IDX] != 0)
+ tpnt->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
+#endif /* __DSBT__ */
+
#ifdef __LDSO_GNU_HASH_SUPPORT__
if (dynamic_info[DT_GNU_HASH_IDX] != 0) {
Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX];
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 8cfb03f9a..f2ba628b3 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -77,6 +77,10 @@ char *_dl_debug_bindings = NULL;
int _dl_debug_file = 2;
#endif
+#ifdef __DSBT__
+void **_dl_ldso_dsbt = NULL;
+#endif
+
unsigned long attribute_hidden _dl_skip_args = 0;
const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
@@ -454,6 +458,11 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
_dl_progname = argv[0];
}
+#ifdef __DSBT__
+ _dl_ldso_dsbt = (void *)tpnt->dynamic_info[DT_DSBT_BASE_IDX];
+ _dl_ldso_dsbt[tpnt->dynamic_info[DT_DSBT_INDEX_IDX]] = _dl_ldso_dsbt;
+#endif
+
#ifndef __LDSO_STANDALONE_SUPPORT__
if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
_dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
@@ -688,6 +697,11 @@ of this helper program; chances are you did not intend to run this program.\n\
app_tpnt->mapaddr = app_mapaddr;
app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
app_tpnt->usage_count++;
+#ifdef __DSBT__
+ _dl_ldso_dsbt[0] = app_tpnt->dsbt_table;
+ _dl_memcpy(app_tpnt->dsbt_table, _dl_ldso_dsbt,
+ app_tpnt->dsbt_size * sizeof(tpnt->dsbt_table[0]));
+#endif
lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
#ifdef ALLOW_ZERO_PLTGOT
if (lpnt)