summaryrefslogtreecommitdiff
path: root/ldso/ldso/dl-elf.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2011-04-11 13:21:23 +0200
committerBernd Schmidt <bernds@codesourcery.com>2011-04-11 13:27:03 +0200
commitfeb7ce46ef24f74ebf0235f10127bd49f0c7e675 (patch)
tree3369d611fd697300b39b9f9b6f0cea4f06bd8ae7 /ldso/ldso/dl-elf.c
parenteff2d0ba5890b517ef5bc9d0269d6149556c12c8 (diff)
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 <bernds@codesourcery.com>
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r--ldso/ldso/dl-elf.c34
1 files changed, 29 insertions, 5 deletions
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) {