From 95adc01517efce365da4e40e0d2a081ec4497928 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Wed, 23 Feb 2011 12:56:43 +0100 Subject: Add support for DSBT ELF to ld.so 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 Signed-off-by: Aurelien Jacquiot Signed-off-by: Bernd Schmidt --- ldso/include/dl-defs.h | 2 +- ldso/include/dl-elf.h | 11 ++++++++++- ldso/ldso/dl-elf.c | 23 ++++++++++++++++++++++- ldso/ldso/ldso.c | 11 ++++++++++- 4 files changed, 43 insertions(+), 4 deletions(-) (limited to 'ldso') diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index 2d6303cfe..be0a81da3 100644 --- a/ldso/include/dl-defs.h +++ b/ldso/include/dl-defs.h @@ -212,7 +212,7 @@ typedef struct { _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. diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 5aec64f0d..7fbb373b4 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -165,7 +165,7 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info /* 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 { @@ -179,6 +179,15 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info 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; } diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 61d495974..4cbd3382f 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -188,7 +188,7 @@ unsigned long _dl_error_number; 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; @@ -806,6 +806,27 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, 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", diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 4d79d4665..7ee925706 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -868,7 +868,16 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, 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, -- cgit v1.2.3