diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-02-17 10:55:59 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-02-17 10:55:59 +0000 |
commit | e5649e61768bfd26d48aa44076d2c1e801a3e8cb (patch) | |
tree | 948076ae77832a88ff4c774d34983b23dca769f3 /ldso | |
parent | 0dccbee4ebd749c5a3408be7594226db9f9c2005 (diff) |
Seperate out the startup stuff from the non-startup stuff.
Begin converting some big ugly macros to inline functions
instead
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/arm/dl-startup.h | 100 | ||||
-rw-r--r-- | ldso/ldso/arm/dl-sysdep.h | 128 | ||||
-rw-r--r-- | ldso/ldso/cris/dl-startup.h | 51 | ||||
-rw-r--r-- | ldso/ldso/cris/dl-sysdep.h | 53 | ||||
-rw-r--r-- | ldso/ldso/i386/dl-startup.h | 54 | ||||
-rw-r--r-- | ldso/ldso/i386/dl-sysdep.h | 66 | ||||
-rw-r--r-- | ldso/ldso/m68k/dl-startup.h | 68 | ||||
-rw-r--r-- | ldso/ldso/m68k/dl-sysdep.h | 57 | ||||
-rw-r--r-- | ldso/ldso/mips/dl-startup.h | 83 | ||||
-rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 123 | ||||
-rw-r--r-- | ldso/ldso/powerpc/dl-startup.h | 53 | ||||
-rw-r--r-- | ldso/ldso/powerpc/dl-sysdep.h | 51 | ||||
-rw-r--r-- | ldso/ldso/sh/dl-startup.h | 54 | ||||
-rw-r--r-- | ldso/ldso/sh/dl-sysdep.h | 61 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-startup.h | 135 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-sysdep.h | 138 | ||||
-rw-r--r-- | ldso/ldso/sparc/dl-startup.h | 57 | ||||
-rw-r--r-- | ldso/ldso/sparc/dl-sysdep.h | 58 |
18 files changed, 696 insertions, 694 deletions
diff --git a/ldso/ldso/arm/dl-startup.h b/ldso/ldso/arm/dl-startup.h index 6e3033959..d4a1ee79b 100644 --- a/ldso/ldso/arm/dl-startup.h +++ b/ldso/ldso/arm/dl-startup.h @@ -1,21 +1,95 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. */ +/* vi: set sw=4 ts=4: */ +/* + * Architecture specific code used by dl-startup.c + * Copyright (C) 2000-2004 by Erik Andersen <andersen@codpoet.org> + */ + /* Overrive the default _dl_boot function, and replace it with a bit of asm. * Then call the real _dl_boot function, which is now named _dl_boot2. */ - -asm("" \ -" .text\n" \ +asm("" \ +" .text\n" \ " .globl _dl_boot\n" \ "_dl_boot:\n" \ -" mov r7, sp\n" \ -" @ldr r0, [sp], #4\n" \ -" mov r0, sp\n" \ +" mov r7, sp\n" \ +" @ldr r0, [sp], #4\n" \ +" mov r0, sp\n" \ " bl _dl_boot2\n" \ -" mov r6, r0\n" \ -" mov r0, r7\n" \ -" mov pc, r6\n" \ +" mov r6, r0\n" \ +" mov r0, r7\n" \ +" mov pc, r6\n" \ ); -#define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) +#define DL_BOOT(X) static __attribute__ ((unused)) void* _dl_boot2 (X) + + +/* Get a pointer to the argv array. On many platforms this can be just + * the address if the first argument, on other platforms we need to + * do something a little more subtle here. */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS) + +/* Handle relocation of the symbols in the dynamic loader. */ +static inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) +{ + switch (ELF32_R_TYPE(rpnt->r_info)) { + case R_ARM_NONE: + break; + case R_ARM_ABS32: + *reloc_addr += symbol_addr; + break; + case R_ARM_PC24: + { + unsigned long addend; + long newvalue, topbits; + + addend = *reloc_addr & 0x00ffffff; + if (addend & 0x00800000) addend |= 0xff000000; + + newvalue = symbol_addr - (unsigned long)reloc_addr + (addend << 2); + topbits = newvalue & 0xfe000000; + if (topbits != 0xfe000000 && topbits != 0x00000000) + { +#if 0 + // Don't bother with this during ldso initilization... + newvalue = fix_bad_pc24(reloc_addr, symbol_addr) + - (unsigned long)reloc_addr + (addend << 2); + topbits = newvalue & 0xfe000000; + if (unlikely(topbits != 0xfe000000 && topbits != 0x00000000)) + { + SEND_STDERR("R_ARM_PC24 relocation out of range\n"); + _dl_exit(1); + } +#else + SEND_STDERR("R_ARM_PC24 relocation out of range\n"); + _dl_exit(1); +#endif + } + newvalue >>= 2; + symbol_addr = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff); + *reloc_addr = symbol_addr; + break; + } + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + *reloc_addr = symbol_addr; + break; + case R_ARM_RELATIVE: + *reloc_addr += load_addr; + break; + case R_ARM_COPY: + break; + default: + SEND_STDERR("Unsupported relocation type\n"); + _dl_exit(1); + } +} + + +/* Transfer control to the user's application, once the dynamic loader is + * done. This routine has to exit the current function, then call the + * _dl_elf_main function. */ +#define START() return _dl_elf_main; + + diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h index 96aa62678..ebd258a7f 100644 --- a/ldso/ldso/arm/dl-sysdep.h +++ b/ldso/ldso/arm/dl-sysdep.h @@ -1,123 +1,59 @@ +/* vi: set sw=4 ts=4: */ /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. + * Copyright (C) 2000-2004 by Erik Andersen <andersen@codpoet.org> */ -/* - * Define this if the system uses RELOCA. - */ +/* Define this if the system uses RELOCA. */ #undef ELF_USES_RELOCA -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS) - -/* - * Initialization sequence for a GOT. - */ +/* Initialization sequence for the GOT. */ #define INIT_GOT(GOT_BASE,MODULE) \ { \ GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ GOT_BASE[1] = (unsigned long) MODULE; \ } -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)){ \ - case R_ARM_ABS32: \ - *REL += SYMBOL; \ - break; \ - case R_ARM_PC24: \ - { long newvalue, topbits; \ - unsigned long addend = *REL & 0x00ffffff; \ - if (addend & 0x00800000) addend |= 0xff000000; \ - newvalue=SYMBOL-(unsigned long)REL+(addend<<2); \ - topbits = newvalue & 0xfe000000; \ - if (topbits!=0xfe000000&&topbits!=0x00000000){ \ - newvalue = fix_bad_pc24(REL, SYMBOL) \ - -(unsigned long)REL+(addend<<2); \ - topbits = newvalue & 0xfe000000; \ - if (topbits!=0xfe000000&&topbits!=0x00000000){ \ - SEND_STDERR("R_ARM_PC24 relocation out of range\n");\ - _dl_exit(1); } } \ - newvalue>>=2; \ - SYMBOL=(*REL&0xff000000)|(newvalue & 0x00ffffff); \ - *REL=SYMBOL; \ - } \ - break; \ - case R_ARM_GLOB_DAT: \ - case R_ARM_JUMP_SLOT: \ - *REL = SYMBOL; \ - break; \ - case R_ARM_RELATIVE: \ - *REL += (unsigned long) LOAD; \ - break; \ - case R_ARM_NONE: \ - break; \ - default: \ - SEND_STDERR("Aiieeee!"); \ - _dl_exit(1); \ +static inline unsigned long arm_modulus(unsigned long m, unsigned long p) +{ + unsigned long i,t,inc; + i=p; t=0; + while(!(i&(1<<31))) { + i<<=1; + t++; } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ - -#define START() return _dl_elf_main; - - + t--; + for(inc=t;inc>2;inc--) { + i=p<<inc; + if(i&(1<<31)) + break; + while(m>=i) { + m-=i; + i<<=1; + if(i&(1<<31)) + break; + if(i<p) + break; + } + } + while(m>=p) { + m-=p; + } + return m; +} +#define do_rem(result, n, base) result=arm_modulus(n,base); /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_ARM #undef MAGIC2 + /* Used for error messages */ #define ELF_TARGET "ARM" struct elf_resolve; unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); -static inline unsigned long arm_modulus(unsigned long m, unsigned long p) { - unsigned long i,t,inc; - i=p; t=0; - while(!(i&(1<<31))) { - i<<=1; - t++; - } - t--; - for(inc=t;inc>2;inc--) { - i=p<<inc; - if(i&(1<<31)) - break; - while(m>=i) { - m-=i; - i<<=1; - if(i&(1<<31)) - break; - if(i<p) - break; - } - } - while(m>=p) { - m-=p; - } - return m; -} - -#define do_rem(result, n, base) result=arm_modulus(n,base); - /* 4096 bytes alignment */ #define PAGE_ALIGN 0xfffff000 #define ADDR_ALIGN 0xfff diff --git a/ldso/ldso/cris/dl-startup.h b/ldso/ldso/cris/dl-startup.h index bf7714539..e910c235c 100644 --- a/ldso/ldso/cris/dl-startup.h +++ b/ldso/ldso/cris/dl-startup.h @@ -1,7 +1,9 @@ /* - * This code fix the stack pointer so that the dynamic linker - * can find argc, argv and auxvt (Auxillary Vector Table). + * Architecture specific code used by dl-startup.c */ + +/* This code fixes the stack pointer so that the dynamic linker + * can find argc, argv and auxvt (Auxillary Vector Table). */ asm("" \ " .text\n" \ " .globl _dl_boot\n" \ @@ -14,3 +16,48 @@ asm("" \ ); #define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) + + +/* Get a pointer to the argv array. On many platforms this can be just + * the address if the first argument, on other platforms we need to + * do something a little more subtle here. */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) + +/* Handle relocation of the symbols in the dynamic loader. */ +static inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) +{ + switch (ELF32_R_TYPE(rpnt->r_info)) { + case R_CRIS_GLOB_DAT: + case R_CRIS_JUMP_SLOT: + case R_CRIS_32: + *reloc_addr = symbol_addr; + break; + case R_CRIS_16_PCREL: + *(short *) *reloc_addr = symbol_addr + rpnt->r_addend - *reloc_addr - 2; + break; + case R_CRIS_32_PCREL: + *reloc_addr = symbol_addr + rpnt->r_addend - *reloc_addr - 4; + break; + case R_CRIS_NONE: + break; + case R_CRIS_RELATIVE: + *reloc_addr = load_addr + rpnt->r_addend; + break; + default: + _dl_exit(1); + break; + } +} + +/* Transfer control to the user's application, once the dynamic loader is + * done. This routine has to exit the current function, then call the + * _dl_elf_main function. */ +#define START() __asm__ volatile ("moveq 0,$r8\n\t" \ + "move $r8,$srp\n\t" \ + "move.d %1,$sp\n\t" \ + "jump %0\n\t" \ + : : "r" (_dl_elf_main), "r" (args)) + + diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index baad524ee..aec396441 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -1,63 +1,13 @@ /* CRIS can never use Elf32_Rel relocations. */ #define ELF_USES_RELOCA -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) - -/* - * Initialization sequence for a GOT. - */ +/* Initialization sequence for the GOT. */ #define INIT_GOT(GOT_BASE,MODULE) \ { \ GOT_BASE[1] = (unsigned long) MODULE; \ GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ } -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP, REL, SYMBOL, LOAD, SYMTAB) \ - switch (ELF32_R_TYPE((RELP)->r_info)) { \ - case R_CRIS_GLOB_DAT: \ - case R_CRIS_JUMP_SLOT: \ - case R_CRIS_32: \ - *REL = SYMBOL; \ - break; \ - case R_CRIS_16_PCREL: \ - *(short *) *REL = SYMBOL + (RELP)->r_addend - *REL - 2; \ - break; \ - case R_CRIS_32_PCREL: \ - *REL = SYMBOL + (RELP)->r_addend - *REL - 4; \ - break; \ - case R_CRIS_NONE: \ - break; \ - case R_CRIS_RELATIVE: \ - *REL = (unsigned long) LOAD + (RELP)->r_addend; \ - break; \ - default: \ - _dl_exit(1); \ - break; \ - } - -/* - * Transfer control to the user's application once the dynamic loader - * is done. This routine has to exit the current function, then call - * _dl_elf_main. - */ -#define START() __asm__ volatile ("moveq 0,$r8\n\t" \ - "move $r8,$srp\n\t" \ - "move.d %1,$sp\n\t" \ - "jump %0\n\t" \ - : : "r" (_dl_elf_main), "r" (args)) - /* Defined some magic numbers that this ld.so should accept. */ #define MAGIC1 EM_CRIS #undef MAGIC2 @@ -103,7 +53,6 @@ cris_mod(unsigned long m, unsigned long p) return m; } - #define do_rem(result, n, base) result = cris_mod(n, base); /* 8192 bytes alignment */ diff --git a/ldso/ldso/i386/dl-startup.h b/ldso/ldso/i386/dl-startup.h index 42c96a6f5..d57134d19 100644 --- a/ldso/ldso/i386/dl-startup.h +++ b/ldso/ldso/i386/dl-startup.h @@ -1,7 +1,51 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. +/* vi: set sw=4 ts=4: */ +/* + * Architecture specific code used by dl-startup.c + * Copyright (C) 2000-2004 by Erik Andersen <andersen@codpoet.org> */ -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) +/* For x86 we do not need any special setup so go right to _dl_boot() */ +#define DL_BOOT(X) __attribute__ ((unused)) void _dl_boot (X) + +/* Get a pointer to the argv array. On many platforms this can be just + * the address if the first argument, on other platforms we need to + * do something a little more subtle here. */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS) + +/* Handle relocation of the symbols in the dynamic loader. */ +static inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) +{ + switch (ELF32_R_TYPE(rpnt->r_info)) + { + case R_386_32: + *reloc_addr += symbol_addr; + break; + case R_386_PC32: + *reloc_addr += symbol_addr - (unsigned long) reloc_addr; + break; + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + *reloc_addr = symbol_addr; + break; + case R_386_RELATIVE: + *reloc_addr += load_addr; + break; + default: + _dl_exit(1); + } +} + + +/* Transfer control to the user's application, once the dynamic loader is + * done. This routine has to exit the current function, then call the + * _dl_elf_main function. */ +#define START() \ + __asm__ volatile ("leave\n\t" \ + "jmp *%%eax\n\t" \ + : "=a" (status) : "a" (_dl_elf_main)) + + + + diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index d7475d630..a92d89574 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -1,72 +1,24 @@ +/* vi: set sw=4 ts=4: */ /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. + * Copyright (C) 2000-2004 by Erik Andersen <andersen@codpoet.org> */ -/* - * Define this if the system uses RELOCA. - */ +/* Define this if the system uses RELOCA. */ #undef ELF_USES_RELOCA -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS) - -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -do { \ - GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ +/* Initialization sequence for the GOT. */ +#define INIT_GOT(GOT_BASE,MODULE) \ +do { \ + GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \ + GOT_BASE[1] = (unsigned long) MODULE; \ } while(0) -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)){ \ - case R_386_32: \ - *REL += SYMBOL; \ - break; \ - case R_386_PC32: \ - *REL += SYMBOL - (unsigned long) REL; \ - break; \ - case R_386_GLOB_DAT: \ - case R_386_JMP_SLOT: \ - *REL = SYMBOL; \ - break; \ - case R_386_RELATIVE: \ - *REL += (unsigned long) LOAD; \ - break; \ - default: \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. This routine has to exit the current function, then - * call the _dl_elf_main function. - */ -#define START() \ - __asm__ volatile ("leave\n\t" \ - "jmp *%%eax\n\t" \ - : "=a" (status) : "a" (_dl_elf_main)) - - - /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_386 #undef MAGIC2 + /* Used for error messages */ #define ELF_TARGET "386" diff --git a/ldso/ldso/m68k/dl-startup.h b/ldso/ldso/m68k/dl-startup.h index 42c96a6f5..8c37ebf0d 100644 --- a/ldso/ldso/m68k/dl-startup.h +++ b/ldso/ldso/m68k/dl-startup.h @@ -1,7 +1,65 @@ -/* Any assmbly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. See arm/boot1_arch.h for an example of what - * can be done. +/* + * Architecture specific code used by dl-startup.c */ -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) +/* For m68k we do not need any special setup so go right to _dl_boot() */ +#define DL_BOOT(X) __attribute__ ((unused)) void _dl_boot (X) + +/* Get a pointer to the argv array. On many platforms this can be just + * the address if the first argument, on other platforms we need to + * do something a little more subtle here. */ +#define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS))) + + +/* Handle relocation of the symbols in the dynamic loader. */ +static inline +void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr, + unsigned long symbol_addr, unsigned long load_addr, Elf32_Sym *symtab) +{ + switch (ELF32_R_TYPE(rpnt->r_info)) + { + case R_68K_8: + *(char *) reloc_addr = symbol_addr + rpnt->r_addend; + break; + case R_68K_16: + *(short *) reloc_addr = symbol_addr + rpnt->r_addend; + break; + case R_68K_32: + *reloc_addr = symbol_addr + rpnt->r_addend; + break; + case R_68K_PC8: + *(char *) reloc_addr = (symbol_addr + rpnt->r_addend + - (unsigned int) reloc_addr); + break; + case R_68K_PC16: + *(short *) reloc_addr = (symbol_addr + rpnt->r_addend + - (unsigned int) reloc_addr); + break; + case R_68K_PC32: + *reloc_addr = (symbol_addr + rpnt->r_addend + - (unsigned int) reloc_addr); + break; + case R_68K_GLOB_DAT: + case R_68K_JMP_SLOT: + *reloc_addr = symbol_addr; + break; + case R_68K_RELATIVE: + *reloc_addr = ((unsigned int) load_addr + + (rpnt->r_addend ? : : *reloc_addr)); + break; + default: + _dl_exit (1); + } +} + + +/* Transfer control to the user's application, once the dynamic loader is + * done. This routine has to exit the current function, then call the + * _dl_elf_main function. */ +#define START() \ + __asm__ volatile ("unlk %%a6\n\t" \ + "jmp %0@" \ + : : "a" (_dl_elf_main)); + + + diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h index d8936f530..1eff443e7 100644 --- a/ldso/ldso/m68k/dl-sysdep.h +++ b/ldso/ldso/m68k/dl-sysdep.h @@ -5,11 +5,6 @@ /* Define this if the system uses RELOCA. */ #define ELF_USES_RELOCA -/* Get a pointer to the argv array. On many platforms this can be - just the address if the first argument, on other platforms we need - to do something a little more subtle here. */ -#define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS))) - /* Initialization sequence for a GOT. */ #define INIT_GOT(GOT_BASE,MODULE) \ { \ @@ -17,59 +12,7 @@ GOT_BASE[1] = (int) (MODULE); \ } -/* Here is a macro to perform a relocation. This is only used when - bootstrapping the dynamic loader. RELP is the relocation that we - are performing, REL is the pointer to the address we are - relocating. SYMBOL is the symbol involved in the relocation, and - LOAD is the load address. */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch (ELF32_R_TYPE ((RELP)->r_info)) \ - { \ - case R_68K_8: \ - *(char *) (REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_16: \ - *(short *) (REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_68K_PC8: \ - *(char *) (REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_PC16: \ - *(short *) (REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_PC32: \ - *(REL) = ((SYMBOL) + (RELP)->r_addend \ - - (unsigned int) (REL)); \ - break; \ - case R_68K_GLOB_DAT: \ - case R_68K_JMP_SLOT: \ - *(REL) = (SYMBOL); \ - break; \ - case R_68K_RELATIVE: /* Compatibility kludge */ \ - *(REL) = ((unsigned int) (LOAD) + ((RELP)->r_addend ? : *(REL))); \ - break; \ - default: \ - _dl_exit (1); \ - } - - -/* Transfer control to the user's application, once the dynamic loader - is done. */ - -#define START() \ - __asm__ volatile ("unlk %%a6\n\t" \ - "jmp %0@" \ - : : "a" (_dl_elf_main)); - - - /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_68K #undef MAGIC2 /* Used for error messages */ diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h index 886f8b8b8..21c9074e1 100644 --- a/ldso/ldso/mips/dl-startup.h +++ b/ldso/ldso/mips/dl-startup.h @@ -35,3 +35,86 @@ asm("" \ ); #define DL_BOOT(X) static void __attribute__ ((unused)) _dl_boot2 (X) + +/* + * Get a pointer to the argv array. On many platforms this can be just + * the address if the first argument, on other platforms we need to + * do something a little more subtle here. + */ +#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) + + +/* + * Here is a macro to perform the GOT relocation. This is only + * used when bootstrapping the dynamic loader. + */ +#define PERFORM_BOOTSTRAP_GOT(got) \ +do { \ + Elf32_Sym *sym; \ + unsigned long i; \ + \ + /* Add load address displacement to all local GOT entries */ \ + i = 2; \ + while (i < tpnt->mips_local_gotno) \ + got[i++] += load_addr; \ + \ + /* Handle global GOT entries */ \ + got += tpnt->mips_local_gotno; \ + sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \ + load_addr) + tpnt->mips_gotsym; \ + i = tpnt->mips_symtabno - tpnt->mips_gotsym; \ + \ + while (i--) { \ + if (sym->st_shndx == SHN_UNDEF || \ + sym->st_shndx == SHN_COMMON) \ + *got = load_addr + sym->st_value; \ + else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \ + *got != sym->st_value) \ + *got += load_addr; \ + else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \ + if (sym->st_other == 0) \ + *got += load_addr; \ + } \ + else \ + *got = load_addr + sym->st_value; \ + \ + got++; \ + sym++; \ + } \ +} while (0) + + +/* + * Here is a macro to perform a relocation. This is only used when + * bootstrapping the dynamic loader. + */ +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ + switch(ELF32_R_TYPE((RELP)->r_info)) { \ + case R_MIPS_REL32: \ + if (symtab_index) { \ + if (symtab_index < tpnt->mips_gotsym) \ + *REL += SYMBOL; \ + } \ + else { \ + *REL += LOAD; \ + } \ + break; \ + case R_MIPS_NONE: \ + break; \ + default: \ + SEND_STDERR("Aiieeee!"); \ + _dl_exit(1); \ + } + + +/* + * Transfer control to the user's application, once the dynamic loader + * is done. This routine has to exit the current function, then + * call the _dl_elf_main function. For MIPS, we do it in assembly + * because the stack doesn't get properly restored otherwise. Got look + * at boot1_arch.h + */ +#define START() + + + diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 879cb8340..08e965567 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -1,120 +1,35 @@ -/* vi: set sw=4 ts=4: */ +/* vi: set sw=8 ts=8: */ /* * Various assmbly language/system dependent hacks that are required * so that we can minimize the amount of platform specific code. */ -/* - * Define this if the system uses RELOCA. - */ +/* Define this if the system uses RELOCA. */ #undef ELF_USES_RELOCA -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address if the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS) - - -/* - * Initialization sequence for the application/library GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -do { \ - unsigned long i; \ - \ - /* Check if this is the dynamic linker itself */ \ - if (MODULE->libtype == program_interpreter) \ - continue; \ - \ - /* Fill in first two GOT entries according to the ABI */ \ - GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ - \ +/* Initialization sequence for the application/library GOT. */ +#define INIT_GOT(GOT_BASE,MODULE) \ +do { \ + unsigned long i; \ + \ + /* Check if this is the dynamic linker itself */ \ + if (MODULE->libtype == program_interpreter) \ + continue; \ + \ + /* Fill in first two GOT entries according to the ABI */ \ + GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \ + GOT_BASE[1] = (unsigned long) MODULE; \ + \ /* Add load address displacement to all local GOT entries */ \ - i = 2; \ - while (i < MODULE->mips_local_gotno) \ - GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \ - \ + i = 2; \ + while (i < MODULE->mips_local_gotno) \ + GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \ + \ } while (0) -/* - * Here is a macro to perform the GOT relocation. This is only - * used when bootstrapping the dynamic loader. - */ -#define PERFORM_BOOTSTRAP_GOT(got) \ -do { \ - Elf32_Sym *sym; \ - unsigned long i; \ - \ - /* Add load address displacement to all local GOT entries */ \ - i = 2; \ - while (i < tpnt->mips_local_gotno) \ - got[i++] += load_addr; \ - \ - /* Handle global GOT entries */ \ - got += tpnt->mips_local_gotno; \ - sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \ - load_addr) + tpnt->mips_gotsym; \ - i = tpnt->mips_symtabno - tpnt->mips_gotsym; \ - \ - while (i--) { \ - if (sym->st_shndx == SHN_UNDEF || \ - sym->st_shndx == SHN_COMMON) \ - *got = load_addr + sym->st_value; \ - else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \ - *got != sym->st_value) \ - *got += load_addr; \ - else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \ - if (sym->st_other == 0) \ - *got += load_addr; \ - } \ - else \ - *got = load_addr + sym->st_value; \ - \ - got++; \ - sym++; \ - } \ -} while (0) - - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. - */ -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - switch(ELF32_R_TYPE((RELP)->r_info)) { \ - case R_MIPS_REL32: \ - if (symtab_index) { \ - if (symtab_index < tpnt->mips_gotsym) \ - *REL += SYMBOL; \ - } \ - else { \ - *REL += LOAD; \ - } \ - break; \ - case R_MIPS_NONE: \ - break; |