diff mbox

ldso: fix standalone execution on x86_64 architecture

Message ID 20140326133056.GA32517@reddwarf.lablan
State Superseded
Headers show

Commit Message

vincent March 26, 2014, 1:31 p.m. UTC
If the dynamic linker is built with LDSO_STANDALONE_SUPPORT=y, it can
load then run a dynamically linked program when explicitly invoked
from the command line.  This is used for test and prelink purposes,
and also by other tools like PRoot to force the kernel to load the
right ELF interpreter.

This feature is currently broken on x86_64 since the number of command
line arguments (ie. argc) passed from the kernel is an "elf_addr_t"
(64 bit on x86_64), whereas it is read as an "unsigned int" (32 bit on
x86_64).

Ref: https://github.com/cedric-vincent/PRoot/issues/45
Signed-off-by: Cédric VINCENT <cedric.vincent@st.com>
---
 ldso/ldso/ldso.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Filippo Arcidiacono March 27, 2014, 7:59 a.m. UTC | #1
Good catch.
Thanks to have fixed it.

On 3/26/2014 2:31 PM, cedric.vincent@st.com wrote:
> If the dynamic linker is built with LDSO_STANDALONE_SUPPORT=y, it can
> load then run a dynamically linked program when explicitly invoked
> from the command line.  This is used for test and prelink purposes,
> and also by other tools like PRoot to force the kernel to load the
> right ELF interpreter.
>
> This feature is currently broken on x86_64 since the number of command
> line arguments (ie. argc) passed from the kernel is an "elf_addr_t"
> (64 bit on x86_64), whereas it is read as an "unsigned int" (32 bit on
> x86_64).
>
> Ref: https://github.com/cedric-vincent/PRoot/issues/45
> Signed-off-by: Cédric VINCENT <cedric.vincent@st.com>
> ---
>   ldso/ldso/ldso.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
> index becabd3..89a0126 100644
> --- a/ldso/ldso/ldso.c
> +++ b/ldso/ldso/ldso.c
> @@ -526,8 +526,8 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
>   
>   #ifdef __LDSO_STANDALONE_SUPPORT__
>   	if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
> -		unsigned int *aux_dat = (unsigned int *) argv;
> -		int argc = aux_dat[-1];
> +		unsigned long *aux_dat = (unsigned long *) argv;
> +		long argc = aux_dat[-1];
>   
>   		tpnt->libname = argv[0];
>   		while (argc > 1)
Bernhard Reutner-Fischer April 1, 2014, 9:50 a.m. UTC | #2
On Wed, Mar 26, 2014 at 02:31:11PM +0100, cedric.vincent@st.com wrote:
> If the dynamic linker is built with LDSO_STANDALONE_SUPPORT=y, it can
> load then run a dynamically linked program when explicitly invoked
> from the command line.  This is used for test and prelink purposes,
> and also by other tools like PRoot to force the kernel to load the
> right ELF interpreter.
> 
> This feature is currently broken on x86_64 since the number of command
> line arguments (ie. argc) passed from the kernel is an "elf_addr_t"
> (64 bit on x86_64), whereas it is read as an "unsigned int" (32 bit on
> x86_64).

so shouldn't this be ElfW(Addr) instead?
thanks,
> 
> Ref: https://github.com/cedric-vincent/PRoot/issues/45
> Signed-off-by: Cédric VINCENT <cedric.vincent@st.com>
> ---
>  ldso/ldso/ldso.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
> index becabd3..89a0126 100644
> --- a/ldso/ldso/ldso.c
> +++ b/ldso/ldso/ldso.c
> @@ -526,8 +526,8 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
>  
>  #ifdef __LDSO_STANDALONE_SUPPORT__
>  	if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
> -		unsigned int *aux_dat = (unsigned int *) argv;
> -		int argc = aux_dat[-1];
> +		unsigned long *aux_dat = (unsigned long *) argv;
> +		long argc = aux_dat[-1];
>  
>  		tpnt->libname = argv[0];
>  		while (argc > 1)
> -- 
> 1.8.4
> 
> _______________________________________________
> uClibc mailing list
> uClibc@uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc
diff mbox

Patch

diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index becabd3..89a0126 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -526,8 +526,8 @@  void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 
 #ifdef __LDSO_STANDALONE_SUPPORT__
 	if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
-		unsigned int *aux_dat = (unsigned int *) argv;
-		int argc = aux_dat[-1];
+		unsigned long *aux_dat = (unsigned long *) argv;
+		long argc = aux_dat[-1];
 
 		tpnt->libname = argv[0];
 		while (argc > 1)