diff options
-rw-r--r-- | ldso/include/dl-elf.h | 5 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 6 | ||||
-rw-r--r-- | ldso/include/ldso.h | 3 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 70 | ||||
-rw-r--r-- | ldso/ldso/dl-hash.c | 9 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 14 |
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) |