diff options
author | Filippo Arcidiacono <filippo.arcidiacono@st.com> | 2009-07-31 14:56:38 +0200 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2010-09-17 13:06:58 +0200 |
commit | 637e2b2440f69e22932edd71bd2f0b1210dc32ea (patch) | |
tree | 24d396c7f3730ad50426bfffcd113186265d18b2 /ldso/ldso/dl-elf.c | |
parent | ef65e97083363ffaeeb5fcf3a37d074b74eafb0d (diff) |
ldso: Add implementation of ld.so standalone execution
The dynamic linker can be run either indirectly through running some
dynamically linked program or library (in which case no command line options
to the dynamic linker can be passed and, in the ELF case, the dynamic linker
which is stored in the .interp section of the program is executed)
or directly by running:
/lib/ld-uClibc.so.* [OPTIONS] [PROGRAM [ARGUMENTS]]
Stand-alone execution is a prerequisite for adding prelink capabilities
to uClibc dynamic linker, as well useful for testing an updated version
of the dynamic linker without breaking the whole system.
Currently supported option:
--library-path PATH use given PATH instead of content of the environment
variable LD_LIBRARY_PATH
(Mandatory for prelinking)
Not supported options:
--list list all dependencies and how they are resolved
--verify verify that given object really is a dynamically linked
object we can handle
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names
in LIST
This feature can be enabled by setting LDSO_STANDALONE_SUPPORT=y
Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Diffstat (limited to 'ldso/ldso/dl-elf.c')
-rw-r--r-- | ldso/ldso/dl-elf.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 5562e0784..2a77587db 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -322,7 +322,7 @@ goof: */ struct elf_resolve *_dl_load_elf_shared_library(int secure, - struct dyn_elf **rpnt, char *libname) + struct dyn_elf **rpnt, const char *libname) { ElfW(Ehdr) *epnt; unsigned long dynamic_addr = 0; @@ -397,11 +397,15 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, return NULL; } - if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 + if ((epnt->e_type != ET_DYN +#ifdef __LDSO_STANDALONE_SUPPORT__ + && epnt->e_type != ET_EXEC +#endif + ) || (epnt->e_machine != MAGIC1 #ifdef MAGIC2 && epnt->e_machine != MAGIC2 #endif - )) + )) { _dl_internal_error_number = (epnt->e_type != ET_DYN ? LD_ERROR_NOTDYN : LD_ERROR_NOTMAGIC); @@ -462,6 +466,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, ppnt++; } +#ifdef __LDSO_STANDALONE_SUPPORT__ + if (epnt->e_type == ET_EXEC) + piclib = 0; +#endif + DL_CHECK_LIB_TYPE (epnt, piclib, _dl_progname, libname); maxvma = (maxvma + ADDR_ALIGN) & PAGE_ALIGN; @@ -701,7 +710,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, dpnt = (ElfW(Dyn) *) dynamic_addr; _dl_memset(dynamic_info, 0, sizeof(dynamic_info)); +#ifdef __LDSO_STANDALONE_SUPPORT__ + rtld_flags = _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, piclib ? lib_loadaddr : 0); +#else rtld_flags = _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr); +#endif /* If the TEXTREL is set, this means that we need to make the pages writable before we perform relocations. Do this now. They get set back again later. */ @@ -734,6 +747,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->loadaddr, epnt->e_phoff); tpnt->n_phent = epnt->e_phnum; tpnt->rtld_flags |= rtld_flags; +#ifdef __LDSO_STANDALONE_SUPPORT__ + tpnt->l_entry = epnt->e_entry; +#endif #if defined(USE_TLS) && USE_TLS if (tlsppnt) { @@ -755,7 +771,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, tpnt->l_tls_modid = _dl_next_tls_modid (); /* We know the load address, so add it to the offset. */ +#ifdef __LDSO_STANDALONE_SUPPORT__ + if ((tpnt->l_tls_initimage != NULL) && piclib) +#else if (tpnt->l_tls_initimage != NULL) +#endif { # ifdef __SUPPORT_LD_DEBUG_EARLY__ unsigned int tmp = (unsigned int) tpnt->l_tls_initimage; @@ -772,7 +792,12 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, /* * Add this object into the symbol chain */ - if (*rpnt) { + if (*rpnt +#ifdef __LDSO_STANDALONE_SUPPORT__ + /* Do not create a new chain entry for the main executable */ + && (*rpnt)->dyn +#endif + ) { (*rpnt)->next = _dl_malloc(sizeof(struct dyn_elf)); _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf)); (*rpnt)->next->prev = (*rpnt); @@ -791,7 +816,11 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, (*rpnt)->dyn = tpnt; tpnt->symbol_scope = _dl_symbol_tables; tpnt->usage_count++; +#ifdef __LDSO_STANDALONE_SUPPORT__ + tpnt->libtype = (epnt->e_type == ET_DYN) ? elf_lib : elf_executable; +#else tpnt->libtype = elf_lib; +#endif /* * OK, the next thing we need to do is to insert the dynamic linker into |