diff options
| -rw-r--r-- | ldso/include/dl-elf.h | 5 | ||||
| -rw-r--r-- | ldso/include/dl-hash.h | 6 | ||||
| -rw-r--r-- | ldso/include/ldso.h | 3 | ||||
| -rw-r--r-- | ldso/ldso/dl-elf.c | 70 | ||||
| -rw-r--r-- | ldso/ldso/dl-hash.c | 9 | ||||
| -rw-r--r-- | ldso/ldso/ldso.c | 14 | 
6 files changed, 66 insertions, 41 deletions
| diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 29d1a007f..060ee3dfb 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -222,11 +222,6 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info  #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 = (void *)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/include/dl-hash.h b/ldso/include/dl-hash.h index c7effc588..7bccdca96 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -139,6 +139,12 @@ struct elf_resolve {       memory when the module is dlclose()d.  */    struct funcdesc_ht *funcdesc_ht;  #endif +#ifdef __DSBT__ +  /* Information for DSBT */ +  void **dsbt_table; +  unsigned long dsbt_size; +  unsigned long dsbt_index; +#endif  };  #define RELOCS_DONE	    0x000001 diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 6f3b728c3..cb7b12218 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -84,6 +84,9 @@ extern struct elf_resolve *_dl_trace_prelink_map;	/* Library map for prelinking  #else  #define _dl_trace_prelink		0  #endif +#ifdef __DSBT__ +extern void **_dl_ldso_dsbt; +#endif  #if defined(USE_TLS) && USE_TLS  extern void _dl_add_to_slotinfo (struct link_map  *l); diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 9e2a12ce7..31ba11ffa 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -851,10 +851,15 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,  	/* Handle DSBT initialization */  	{  		struct elf_resolve *t, *ref; -		int idx = tpnt->loadaddr.map->dsbt_index; -		unsigned *dsbt = tpnt->loadaddr.map->dsbt_table; +		int idx = tpnt->dsbt_index; +		void **dsbt = tpnt->dsbt_table; -		if (idx == 0) { +		/* +		 * It is okay (required actually) to have zero idx for an executable. +		 * This is the case when running ldso standalone and the program +		 * is being mapped in via _dl_load_shared_library(). +		 */ +		if (idx == 0 && tpnt->libtype != elf_executable) {  			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", @@ -869,9 +874,9 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,  					break;  				}  			} -			idx = tpnt->loadaddr.map->dsbt_size; +			idx = tpnt->dsbt_size;  			while (idx-- > 0) -				if (!ref || ref->loadaddr.map->dsbt_table[idx] == NULL) +				if (!ref || ref->dsbt_table[idx] == NULL)  					break;  			if (idx <= 0) {  				_dl_dprintf(2, "%s: '%s' caused DSBT table overflow!\n", @@ -880,43 +885,36 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,  			}  			_dl_if_debug_dprint("\n\tfile='%s';  assigned index %d\n",  					    libname, idx); -			tpnt->loadaddr.map->dsbt_index = idx; +			tpnt->dsbt_index = idx; +		} +		/* make sure index is not already used */ +		if (_dl_ldso_dsbt[idx]) { +			struct elf_resolve *dup; +			const char *dup_name; + +			for (dup = _dl_loaded_modules; dup; dup = dup->next) +				if (dup != tpnt && dup->dsbt_index == idx) +					break; +			if (dup) +				dup_name = dup->libname; +			else if (idx == 1) +				dup_name = "runtime linker"; +			else +				dup_name = "unknown library"; +			_dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n", +				    _dl_progname, libname, idx, dup_name); +			_dl_exit(1);  		}  		/*  		 * 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) { -				ref = t; - -				/* make sure index is not already used */ -				if (t->loadaddr.map->dsbt_table[idx]) { -					struct elf_resolve *dup; -					char *dup_name; - -					for (dup = _dl_loaded_modules; dup; dup = dup->next) -						if (dup != tpnt && dup->loadaddr.map->dsbt_index == idx) -							break; -					if (dup) -						dup_name = dup->libname; -					else if (idx == 1) -						dup_name = "runtime linker"; -					else -						dup_name = "unknown library"; -					_dl_dprintf(2, "%s: '%s' dsbt index %d already used by %s!\n", -						    _dl_progname, libname, idx, dup_name); -					_dl_exit(1); -				} -			} -			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 *)); +		for (t = _dl_loaded_modules; t; t = t->next) +			t->dsbt_table[idx] = dsbt; +		_dl_ldso_dsbt[idx] = dsbt; +		_dl_memcpy(dsbt, _dl_ldso_dsbt, +			   tpnt->dsbt_size * sizeof(tpnt->dsbt_table[0]));  	}  #endif  	_dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname); diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c index 36ebec684..2c659dc58 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -115,6 +115,15 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,  	tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr;  	tpnt->libtype = loaded_file; +#ifdef __DSBT__ +	if (dynamic_info[DT_DSBT_BASE_IDX] != 0) +		tpnt->dsbt_table = (void *)dynamic_info[DT_DSBT_BASE_IDX]; +	if (dynamic_info[DT_DSBT_SIZE_IDX] != 0) +		tpnt->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX]; +	if (dynamic_info[DT_DSBT_INDEX_IDX] != 0) +		tpnt->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX]; +#endif /* __DSBT__ */ +  #ifdef __LDSO_GNU_HASH_SUPPORT__  	if (dynamic_info[DT_GNU_HASH_IDX] != 0) {  		Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX]; diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 8cfb03f9a..f2ba628b3 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -77,6 +77,10 @@ char *_dl_debug_bindings  = NULL;  int   _dl_debug_file      = 2;  #endif +#ifdef __DSBT__ +void **_dl_ldso_dsbt = NULL; +#endif +  unsigned long attribute_hidden _dl_skip_args = 0;  const char *_dl_progname = UCLIBC_LDSO;      /* The name of the executable being run */ @@ -454,6 +458,11 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,  		_dl_progname = argv[0];  	} +#ifdef __DSBT__ +	_dl_ldso_dsbt = (void *)tpnt->dynamic_info[DT_DSBT_BASE_IDX]; +	_dl_ldso_dsbt[tpnt->dynamic_info[DT_DSBT_INDEX_IDX]] = _dl_ldso_dsbt; +#endif +  #ifndef __LDSO_STANDALONE_SUPPORT__  	if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {  		_dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n"); @@ -688,6 +697,11 @@ of this helper program; chances are you did not intend to run this program.\n\  			app_tpnt->mapaddr = app_mapaddr;  			app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;  			app_tpnt->usage_count++; +#ifdef __DSBT__ +			_dl_ldso_dsbt[0] = app_tpnt->dsbt_table; +			_dl_memcpy(app_tpnt->dsbt_table, _dl_ldso_dsbt, +				   app_tpnt->dsbt_size * sizeof(tpnt->dsbt_table[0])); +#endif  			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);  #ifdef ALLOW_ZERO_PLTGOT  			if (lpnt) | 
