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.
This patch implements it; it requires the previously posted nommu
DT_TEXTREL patch. Ok to install?
Bernd
diff --git a/ldso/ldso/c6x/elfinterp.c b/ldso/ldso/c6x/elfinterp.c
index 7c79171..f5d3ad4 100644
--- a/ldso/ldso/c6x/elfinterp.c
+++ b/ldso/ldso/c6x/elfinterp.c
@@ -198,6 +198,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf
*scope,
new_val = sym_val;
*reloc_addr = sym_val;
break;
+ case R_C6000_DSBT_INDEX:
+ new_val = (old_val & ~0x007fff00) |
((tpnt->loadaddr.map->dsbt_index & 0x7fff) << 8);
+ *reloc_addr = new_val;
+ break;
case R_C6000_ABS_L16:
new_val = (old_val & ~0x007fff80) | ((sym_val & 0xffff) << 7);
*reloc_addr = new_val;
@@ -224,7 +228,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf
*scope,
(char *)symbol_addr,
symtab[symtab_index].st_size);
}
- break;
+ return 0;
default:
return -1; /*call _dl_exit(1) */
}
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 5336c9a..ca73f3c 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -814,20 +814,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) {
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc