From feb7ce46ef24f74ebf0235f10127bd49f0c7e675 Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Mon, 11 Apr 2011 13:21:23 +0200 Subject: Support dynamic assignment of DSBT_INDEX For DSBT targets (C6X only at this point), we'd like to support the case where the user did not specify --dsbt-index at link time when building a shared library. The dynamic linker can still assign an index at runtime and fix up the DSBT_INDEX relocs, at the cost of startup time and memory space. Signed-off-by: Bernd Schmidt --- ldso/ldso/dl-elf.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'ldso/ldso/dl-elf.c') diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 91e8a97ca..7b5d75146 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -811,20 +811,44 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, #ifdef __DSBT__ /* Handle DSBT initialization */ { - struct elf_resolve *t, *ref = NULL; + struct elf_resolve *t, *ref; int idx = tpnt->loadaddr.map->dsbt_index; unsigned *dsbt = tpnt->loadaddr.map->dsbt_table; if (idx == 0) { - /* This DSO has not been assigned an index */ - _dl_dprintf(2, "%s: '%s' is missing a dsbt index assignment!\n", - _dl_progname, libname); - _dl_exit(1); + 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", + _dl_progname, libname); + _dl_exit(1); + } + /* Find a dsbt table from another module. */ + ref = NULL; + for (t = _dl_loaded_modules; t; t = t->next) { + if (ref == NULL && t != tpnt) { + ref = t; + break; + } + } + idx = tpnt->loadaddr.map->dsbt_size; + while (idx-- > 0) + if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL) + break; + if (idx <= 0) { + _dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n", + _dl_progname, libname); + _dl_exit(1); + } + _dl_if_debug_dprint("\n\tfile='%s'; assigned index %d\n", + libname, idx); + tpnt->loadaddr.map->dsbt_index = idx; + } /* * 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) { -- cgit v1.2.3