This adds support for DSBT ELF to ld.so. This uses loadmaps like FD-PIC.
Some code is added in ld.so to initialize the DSBT tables, and there's
also a new target macro FINISH_BOOTSTRAP_RELOC.
Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Aurelien Jacquiot <a-jacquiot@ti.com>
Signed-off-by: Bernd Schmidt <bernds@codesourcery.com>
/* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects.
- Copyright (C) 1995-2001, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-2001, 2004, 2005, 2006, 2010 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
#ifdef __FDPIC__
# include <bits/elf-fdpic.h>
#endif
+#ifdef __DSBT__
+# include <bits/elf-dsbt.h>
+#endif
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
members form a chain of all the shared objects loaded at startup.
#ifdef __FDPIC__
struct elf32_fdpic_loadaddr l_addr;
#else
+#ifdef __DSBT__
+ struct elf32_dsbt_loadaddr l_addr;
+#else
ElfW(Addr) l_addr; /* Base address shared object is loaded at. */
#endif
+#endif
char *l_name; /* Absolute file name object was found in. */
ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */
struct link_map *l_next, *l_prev; /* Chain of loaded objects. */
#ifdef __FDPIC__
struct elf32_fdpic_loadaddr dlpi_addr;
#else
+#ifdef __DSBT__
+ struct elf32_dsbt_loadaddr dlpi_addr;
+#else
ElfW(Addr) dlpi_addr;
#endif
+#endif
const char *dlpi_name;
const ElfW(Phdr) *dlpi_phdr;
ElfW(Half) dlpi_phnum;
_dl_find_hash for this reloc TYPE. TPNT is the module in which the
matching SYM was found. */
#ifndef DL_FIND_HASH_VALUE
-# define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
+# define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value))
#endif
/* Unmap all previously-mapped segments accumulated in LOADADDR.
/* Don't adjust .dynamic unnecessarily. For FDPIC targets,
we'd have to walk all the loadsegs to find out if it was
actually unnecessary, so skip this optimization. */
-#ifndef __FDPIC__
+#if !defined __FDPIC__ && !defined __DSBT__
if (load_off != 0)
#endif
{
ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
#endif
}
+#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 = 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;
}
unsigned long _dl_internal_error_number;
struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
- struct elf_resolve *tpnt, char *full_libname, int __attribute__((unused)) trace_loaded_objects)
+ struct elf_resolve *tpnt, char *full_libname, int attribute_unused trace_loaded_objects)
{
char *pnt;
struct elf_resolve *tpnt1;
INIT_GOT(lpnt, tpnt);
}
+#ifdef __DSBT__
+ /* Handle DSBT initialization */
+ {
+ struct elf_resolve *t, *ref = NULL;
+ int idx = tpnt->loadaddr.map->dsbt_index;
+ unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
+
+ /*
+ * Setup dsbt slot for this module in dsbt of all modules.
+ */
+ for (t = _dl_loaded_modules; t; t = t->next) {
+ /* find a dsbt table from another module */
+ if (ref == NULL && t != tpnt)
+ ref = t;
+ 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 *));
+ }
+#endif
_dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
_dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, DL_LOADADDR_BASE(lib_loadaddr));
_dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n",
ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
int j;
-
+#ifdef __DSBT__
+ struct elf_resolve *ref = _dl_loaded_modules;
+ _dl_if_debug_dprint("ref is %x, dsbt %x, ref-dsbt %x size %x\n",
+ ref, tpnt->loadaddr.map->dsbt_table,
+ ref->loadaddr.map->dsbt_table,
+ tpnt->loadaddr.map->dsbt_size);
+
+ _dl_memcpy(tpnt->loadaddr.map->dsbt_table, ref->loadaddr.map->dsbt_table,
+ tpnt->loadaddr.map->dsbt_size * sizeof(unsigned *));
+#endif
tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
tpnt->dynamic_info,
(unsigned long)tpnt->dynamic_addr,
/* This entry describes this statically-linked program itself. */
struct dl_phdr_info info;
int ret;
-#ifdef __FDPIC__
+#if defined(__FDPIC__)
info.dlpi_addr.map = NULL;
info.dlpi_addr.got_value = NULL;
+#elif defined(__DSBT__)
+ info.dlpi_addr.map = NULL;
#else
info.dlpi_addr = 0;
#endif