diff options
| -rw-r--r-- | extra/Configs/Config.nios2 | 1 | ||||
| -rw-r--r-- | ldso/ldso/dl-startup.c | 12 | ||||
| -rw-r--r-- | ldso/ldso/nios2/dl-startup.h | 96 | 
3 files changed, 98 insertions, 11 deletions
diff --git a/extra/Configs/Config.nios2 b/extra/Configs/Config.nios2 index 958607cb3..8fcb01be7 100644 --- a/extra/Configs/Config.nios2 +++ b/extra/Configs/Config.nios2 @@ -11,4 +11,3 @@ config FORCE_OPTIONS_FOR_ARCH  	bool  	default y  	select ARCH_LITTLE_ENDIAN -	select ARCH_HAS_NO_LDSO diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 87f564f48..218b20f53 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -99,6 +99,10 @@  extern ElfW(Addr) _begin[] attribute_hidden;  #endif +#ifdef LDSO_NEED_DPNT +ElfW(Dyn) *_dl_saved_dpnt = 0; +#endif +  /* Static declarations */  static int (*_dl_elf_main) (int, char **, char **); @@ -341,6 +345,14 @@ DL_START(unsigned long args)  	   fixed up by now.  Still no function calls outside of this library,  	   since the dynamic resolver is not yet ready. */ +#ifdef LDSO_NEED_DPNT +/*XXX TODO this crashes on nios2: it translates to + * [r5] := (value of the local variable dpnt) + * but r5 is a NULL pointer at this place, which was + * retrieved from the GOT a few instructions further above. + */ +	_dl_saved_dpnt = dpnt; +#endif  	__rtld_stack_end = (void *)(argv - 1);  	_dl_elf_main = (int (*)(int, char **, char **)) diff --git a/ldso/ldso/nios2/dl-startup.h b/ldso/ldso/nios2/dl-startup.h index 982e55532..fb4fc7caf 100644 --- a/ldso/ldso/nios2/dl-startup.h +++ b/ldso/ldso/nios2/dl-startup.h @@ -1,13 +1,86 @@ -__asm__ ("\ -	.text\n\ -	.globl _start\n\ -	.type _start, %function\n\ -_start:\n\ -        mov r4, sp\n\ -        br _dl_start\n\ -	mov r16, r4\n\ -        jmp r16\n\ -"); +#define LDSO_NEED_DPNT + +unsigned int _dl_nios2_get_gp_value(ElfW(Dyn) *dpnt); + +unsigned int +_dl_nios2_get_gp_value (ElfW(Dyn) *dpnt) +{  +	while (dpnt->d_tag != DT_NULL) { +		if (dpnt->d_tag == DT_NIOS2_GP) { +			return (unsigned int)(dpnt->d_un.d_ptr); +		} +		++dpnt; +	} +	return 0; +} + +__asm__ ( +".text\n" +".globl _start\n" +".type _start, %function\n" +"_start:\n" +"        /* At start time, all the args are on the stack.  */\n" +"        mov r4, sp\n" +"\n" +"        /* Start the calculation of the GOT pointer.  */\n" +"        nextpc r22\n" +"1:      movhi r8, %hiadj(_gp_got - 1b)\n" +"        addi r8, r8, %lo(_gp_got - 1b)\n" +"\n" +"        /* Figure out where _dl_start will need to return to.  */\n" +"        movhi ra, %hiadj(2f - 1b)\n" +"        addi ra, ra, %lo(2f - 1b)\n" +"        add ra, ra, r22\n" +"\n" +"        /* Finish the calculation of the GOT pointer.  */\n" +"        add r22, r22, r8\n" +"\n" +"        br _dl_start\n" +"\n" +"        /* Save the returned user entry point.  */\n" +"2:      mov r16, r2\n" +"\n" +"        /* Initialize gp.  */\n" +"        ldw r4, %got(_dl_saved_dpnt)(r22)\n" +"        ldw r8, %call(_dl_nios2_get_gp_value)(r22)\n" +"        callr r8\n" +"        mov gp, r2\n" +"\n" +"        /* Find the number of arguments to skip.  */\n" +"        ldw r8, %got(_dl_skip_args)(r22)\n" +"        ldw r8, 0(r8)\n" +"\n" +"        /* Find argc.  */\n" +"        ldw r5, 0(sp)\n" +"        sub r5, r5, r8\n" +"        stw r5, 0(sp)\n" +"\n" +"        /* Find the first unskipped argument.  */\n" +"        slli r8, r8, 2\n" +"        addi r6, sp, 4\n" +"        add r9, r6, r8\n" +"        mov r10, r6\n" +"\n" +"        /* Shuffle envp down.  */\n" +"        mov r7, r10\n" +"3:      ldw r11, 0(r9)\n" +"        stw r11, 0(r10)\n" +"        addi r9, r9, 4\n" +"        addi r10, r10, 4\n" +"        bne r11, zero, 3b\n" +"\n" +"        /* Shuffle auxv down.  */\n" +"4:      ldw r11, 4(r9)\n" +"        stw r11, 4(r10)\n" +"        ldw r11, 0(r9)\n" +"        stw r11, 0(r10)\n" +"        addi r9, r9, 8\n" +"        addi r10, r10, 8\n" +"        bne r11, zero, 4b\n" +"\n" +"        /* Jump to the user's entry point.  */\n" +"        jmp r16\n" +);  /*   * Get a pointer to the argv array.  On many platforms this can be just @@ -16,6 +89,9 @@ _start:\n\   */  #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1) +/* We can't call functions earlier in the dl startup process */ +#define NO_FUNCS_BEFORE_BOOTSTRAP +  /* The ld.so library requires relocations */  #define ARCH_NEEDS_BOOTSTRAP_RELOCS  | 
