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; \ - 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() - - /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_MIPS #define MAGIC2 EM_MIPS_RS3_LE diff --git a/ldso/ldso/powerpc/dl-startup.h b/ldso/ldso/powerpc/dl-startup.h index 70e494331..a167ae866 100644 --- a/ldso/ldso/powerpc/dl-startup.h +++ b/ldso/ldso/powerpc/dl-startup.h @@ -18,3 +18,56 @@ 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)+1) + +/* + * 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) \ + {int type=ELF32_R_TYPE((RELP)->r_info); \ + Elf32_Addr finaladdr=(SYMBOL)+(RELP)->r_addend;\ + if (type==R_PPC_RELATIVE) { \ + *REL=(Elf32_Word)(LOAD)+(RELP)->r_addend;\ + } else if (type==R_PPC_JMP_SLOT) { \ + Elf32_Sword delta=finaladdr-(Elf32_Word)(REL);\ + *REL=OPCODE_B(delta); \ + } else if (type==R_PPC_ADDR32) { \ + *REL=finaladdr; \ + } else { \ + _dl_exit(100+ELF32_R_TYPE((RELP)->r_info)); \ + } \ + PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL); \ + } +/* + * 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. + */ + +/* hgb@ifi.uio.no: + * Adding a clobber list consisting of r0 for %1. addi on PowerPC + * takes a register as the second argument, but if the register is + * r0, the value 0 is used instead. If r0 is used here, the stack + * pointer (r1) will be zeroed, and the dynamically linked + * application will seg.fault immediatly when receiving control. + */ +#define START() \ + __asm__ volatile ( \ + "addi 1,%1,0\n\t" \ + "mtlr %0\n\t" \ + "blrl\n\t" \ + : : "r" (_dl_elf_main), "r" (args) \ + : "r0") + + + diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h index 1a78b1b8b..41d37e35c 100644 --- a/ldso/ldso/powerpc/dl-sysdep.h +++ b/ldso/ldso/powerpc/dl-sysdep.h @@ -9,13 +9,6 @@ #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)+1) - -/* * Initialization sequence for a GOT. */ #define INIT_GOT(GOT_BASE,MODULE) _dl_init_got(GOT_BASE,MODULE) @@ -63,50 +56,6 @@ #define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory") #define PPC_DIE asm volatile ("tweq 0,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) \ - {int type=ELF32_R_TYPE((RELP)->r_info); \ - Elf32_Addr finaladdr=(SYMBOL)+(RELP)->r_addend;\ - if (type==R_PPC_RELATIVE) { \ - *REL=(Elf32_Word)(LOAD)+(RELP)->r_addend;\ - } else if (type==R_PPC_JMP_SLOT) { \ - Elf32_Sword delta=finaladdr-(Elf32_Word)(REL);\ - *REL=OPCODE_B(delta); \ - } else if (type==R_PPC_ADDR32) { \ - *REL=finaladdr; \ - } else { \ - _dl_exit(100+ELF32_R_TYPE((RELP)->r_info)); \ - } \ - PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL); \ - } -/* - * 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. - */ - -/* hgb@ifi.uio.no: - * Adding a clobber list consisting of r0 for %1. addi on PowerPC - * takes a register as the second argument, but if the register is - * r0, the value 0 is used instead. If r0 is used here, the stack - * pointer (r1) will be zeroed, and the dynamically linked - * application will seg.fault immediatly when receiving control. - */ -#define START() \ - __asm__ volatile ( \ - "addi 1,%1,0\n\t" \ - "mtlr %0\n\t" \ - "blrl\n\t" \ - : : "r" (_dl_elf_main), "r" (args) \ - : "r0") - - /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_PPC diff --git a/ldso/ldso/sh/dl-startup.h b/ldso/ldso/sh/dl-startup.h index d1ca6d985..0a41e36d6 100644 --- a/ldso/ldso/sh/dl-startup.h +++ b/ldso/ldso/sh/dl-startup.h @@ -19,3 +19,57 @@ 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 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_SH_REL32: \ + *(REL) = (SYMBOL) + (RELP)->r_addend \ + - (unsigned long)(REL); \ + break; \ + case R_SH_DIR32: \ + case R_SH_GLOB_DAT: \ + case R_SH_JMP_SLOT: \ + *(REL) = (SYMBOL) + (RELP)->r_addend; \ + break; \ + case R_SH_RELATIVE: \ + *(REL) = (LOAD) + (RELP)->r_addend; \ + break; \ + case R_SH_NONE: \ + break; \ + default: \ + SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ + SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ + SEND_STDERR("REL, SYMBOL, LOAD: "); \ + SEND_ADDRESS_STDERR(REL, 0); \ + SEND_STDERR(", "); \ + SEND_ADDRESS_STDERR(SYMBOL, 0); \ + SEND_STDERR(", "); \ + SEND_ADDRESS_STDERR(LOAD, 1); \ + _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/sh/dl-sysdep.h b/ldso/ldso/sh/dl-sysdep.h index 83cc9b391..134e901c7 100644 --- a/ldso/ldso/sh/dl-sysdep.h +++ b/ldso/ldso/sh/dl-sysdep.h @@ -3,19 +3,10 @@ * 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. */ #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. */ #define INIT_GOT(GOT_BASE,MODULE) \ @@ -24,56 +15,10 @@ 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_SH_REL32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - break; \ - case R_SH_DIR32: \ - case R_SH_GLOB_DAT: \ - case R_SH_JMP_SLOT: \ - *(REL) = (SYMBOL) + (RELP)->r_addend; \ - break; \ - case R_SH_RELATIVE: \ - *(REL) = (LOAD) + (RELP)->r_addend; \ - break; \ - case R_SH_NONE: \ - break; \ - default: \ - SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ - SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ - SEND_STDERR("REL, SYMBOL, LOAD: "); \ - SEND_ADDRESS_STDERR(REL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(SYMBOL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(LOAD, 1); \ - _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; - - - /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_SH #undef MAGIC2 + /* Used for error messages */ #define ELF_TARGET "sh" @@ -84,7 +29,7 @@ static __inline__ unsigned int _dl_urem(unsigned int n, unsigned int base) { int res; - + __asm__ (""\ "mov #0, r0\n\t" \ "div0u\n\t" \ diff --git a/ldso/ldso/sh64/dl-startup.h b/ldso/ldso/sh64/dl-startup.h index 4c6f3c5e2..9c92e221f 100644 --- a/ldso/ldso/sh64/dl-startup.h +++ b/ldso/ldso/sh64/dl-startup.h @@ -23,3 +23,138 @@ 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 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. + */ + +/* + * We need to do this stupidity here as the preprocessor will choke when + * SYMTAB is NULL if we do this in PERFORM_BOOTSTRAP_RELOC(). + */ + +#include <elf.h> + +static inline int __extract_lsb_from_symtab(Elf32_Sym *symtab) +{ + static int lsb = 0; + + /* Check for SHmedia/SHcompact */ + if (symtab) + lsb = symtab->st_other & 4; + + return lsb; +} + +/* + * While on the subject of stupidity, there appear to be some conflicts with + * regards to several relocation types as far as binutils is concerned + * (Barcelona and Madrid both appear to use an out of date elf.h, whereas + * native Catalonia has all of the necessary definitions. As a workaround, + * we'll just define them here for sanity.. + */ +#ifndef R_SH_RELATIVE_LOW16 +# define R_SH_RELATIVE_LOW16 197 +# define R_SH_RELATIVE_MEDLOW16 198 +# define R_SH_IMM_LOW16 246 +# define R_SH_IMM_LOW16_PCREL 247 +# define R_SH_IMM_MEDLOW16 248 +# define R_SH_IMM_MEDLOW16_PCREL 249 +#endif + +#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ + const unsigned int r_type = ELF32_R_TYPE((RELP)->r_info); \ + int lsb = __extract_lsb_from_symtab(SYMTAB); \ + \ + switch (r_type) { \ + case R_SH_REL32: \ + *(REL) = (SYMBOL) + (RELP)->r_addend \ + - (unsigned long)(REL); \ + break; \ + case R_SH_DIR32: \ + case R_SH_GLOB_DAT: \ + case R_SH_JMP_SLOT: \ + *(REL) = ((SYMBOL) + (RELP)->r_addend) | lsb; \ + break; \ + case R_SH_RELATIVE: \ + *(REL) = (LOAD) + (RELP)->r_addend; \ + break; \ + case R_SH_RELATIVE_LOW16: \ + case R_SH_RELATIVE_MEDLOW16: \ + { \ + unsigned long word, value; \ + \ + word = (unsigned long)(REL) & ~0x3fffc00; \ + value = (LOAD) + (RELP)->r_addend; \ + \ + if (r_type == R_SH_RELATIVE_MEDLOW16) \ + value >>= 16; \ + \ + word |= (value & 0xffff) << 10; \ + *(REL) = word; \ + break; \ + } \ + case R_SH_IMM_LOW16: \ + case R_SH_IMM_MEDLOW16: \ + { \ + unsigned long word, value; \ + \ + word = (unsigned long)(REL) & ~0x3fffc00; \ + value = ((SYMBOL) + (RELP)->r_addend) | lsb; \ + \ + if (r_type == R_SH_IMM_MEDLOW16) \ + value >>= 16; \ + \ + word |= (value & 0xffff) << 10; \ + *(REL) = word; \ + break; \ + } \ + case R_SH_IMM_LOW16_PCREL: \ + case R_SH_IMM_MEDLOW16_PCREL: \ + { \ + unsigned long word, value; \ + \ + word = (unsigned long)(REL) & ~0x3fffc00; \ + value = (SYMBOL) + (RELP)->r_addend \ + - (unsigned long)(REL); \ + \ + if (r_type == R_SH_IMM_MEDLOW16_PCREL) \ + value >>= 16; \ + \ + word |= (value & 0xffff) << 10; \ + *(REL) = word; \ + break; \ + } \ + case R_SH_NONE: \ + break; \ + default: \ + SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ + SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ + SEND_STDERR("REL, SYMBOL, LOAD: "); \ + SEND_ADDRESS_STDERR(REL, 0); \ + SEND_STDERR(", "); \ + SEND_ADDRESS_STDERR(SYMBOL, 0); \ + SEND_STDERR(", "); \ + SEND_ADDRESS_STDERR(LOAD, 1); \ + _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/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h index f654b8333..266ec681c 100644 --- a/ldso/ldso/sh64/dl-sysdep.h +++ b/ldso/ldso/sh64/dl-sysdep.h @@ -4,19 +4,10 @@ * 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. */ #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. */ #define INIT_GOT(GOT_BASE,MODULE) \ @@ -25,133 +16,6 @@ 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. - */ - -/* - * We need to do this stupidity here as the preprocessor will choke when - * SYMTAB is NULL if we do this in PERFORM_BOOTSTRAP_RELOC(). - */ - -#include <elf.h> - -static inline int __extract_lsb_from_symtab(Elf32_Sym *symtab) -{ - static int lsb = 0; - - /* Check for SHmedia/SHcompact */ - if (symtab) - lsb = symtab->st_other & 4; - - return lsb; -} - -/* - * While on the subject of stupidity, there appear to be some conflicts with - * regards to several relocation types as far as binutils is concerned - * (Barcelona and Madrid both appear to use an out of date elf.h, whereas - * native Catalonia has all of the necessary definitions. As a workaround, - * we'll just define them here for sanity.. - */ -#ifndef R_SH_RELATIVE_LOW16 -# define R_SH_RELATIVE_LOW16 197 -# define R_SH_RELATIVE_MEDLOW16 198 -# define R_SH_IMM_LOW16 246 -# define R_SH_IMM_LOW16_PCREL 247 -# define R_SH_IMM_MEDLOW16 248 -# define R_SH_IMM_MEDLOW16_PCREL 249 -#endif - -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - const unsigned int r_type = ELF32_R_TYPE((RELP)->r_info); \ - int lsb = __extract_lsb_from_symtab(SYMTAB); \ - \ - switch (r_type) { \ - case R_SH_REL32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - break; \ - case R_SH_DIR32: \ - case R_SH_GLOB_DAT: \ - case R_SH_JMP_SLOT: \ - *(REL) = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - break; \ - case R_SH_RELATIVE: \ - *(REL) = (LOAD) + (RELP)->r_addend; \ - break; \ - case R_SH_RELATIVE_LOW16: \ - case R_SH_RELATIVE_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (LOAD) + (RELP)->r_addend; \ - \ - if (r_type == R_SH_RELATIVE_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16: \ - case R_SH_IMM_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - \ - if (r_type == R_SH_IMM_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16_PCREL: \ - case R_SH_IMM_MEDLOW16_PCREL: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - \ - if (r_type == R_SH_IMM_MEDLOW16_PCREL) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_NONE: \ - break; \ - default: \ - SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc type "); \ - SEND_NUMBER_STDERR(ELF32_R_TYPE((RELP)->r_info), 1); \ - SEND_STDERR("REL, SYMBOL, LOAD: "); \ - SEND_ADDRESS_STDERR(REL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(SYMBOL, 0); \ - SEND_STDERR(", "); \ - SEND_ADDRESS_STDERR(LOAD, 1); \ - _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; - /* Here we define the magic numbers that this dynamic loader should accept */ #define MAGIC1 EM_SH #undef MAGIC2 diff --git a/ldso/ldso/sparc/dl-startup.h b/ldso/ldso/sparc/dl-startup.h index 42c96a6f5..dd502f39c 100644 --- a/ldso/ldso/sparc/dl-startup.h +++ b/ldso/ldso/sparc/dl-startup.h @@ -4,4 +4,59 @@ * can be done. */ -#define DL_BOOT(X) void __attribute__ ((unused)) _dl_boot (X) +#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. We assume that argc is stored + * at the word just below the argvp that we return here. + */ +#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP)); + +/* + * 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_SPARC_32: \ + *REL = SYMBOL + (RELP)->r_addend; \ + break; \ + case R_SPARC_GLOB_DAT: \ + *REL = SYMBOL + (RELP)->r_addend; \ + break; \ + case R_SPARC_JMP_SLOT: \ + REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff); \ + REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \ + break; \ + case R_SPARC_NONE: \ + break; \ + case R_SPARC_WDISP30: \ + break; \ + case R_SPARC_RELATIVE: \ + *REL += (unsigned int) LOAD + (RELP)->r_addend; \ + break; \ + default: \ + _dl_exit(1); \ + } + + +/* + * Transfer control to the user's application, once the dynamic loader + * is done. The crt calls atexit with $g1 if not null, so we need to + * ensure that it contains NULL. + */ + +#define START() \ + __asm__ volatile ( \ + "add %%g0,%%g0,%%g1\n\t" \ + "jmpl %0, %%o7\n\t" \ + "restore %%g0,%%g0,%%g0\n\t" \ + : /*"=r" (status) */ : \ + "r" (_dl_elf_main): "g1", "o0", "o1") + + + + diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h index 72a85538e..c6ac89e11 100644 --- a/ldso/ldso/sparc/dl-sysdep.h +++ b/ldso/ldso/sparc/dl-sysdep.h @@ -5,20 +5,10 @@ */ #define LINUXBIN -/* - * Define this if the system uses RELOCA. - */ +/* 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. We assume that argc is stored - * at the word just below the argvp that we return here. - */ -#define GET_ARGV(ARGVP, ARGS) __asm__("\tadd %%fp,68,%0\n" : "=r" (ARGVP)); - -/* * Initialization sequence for a GOT. For the Sparc, this points to the * PLT, and we need to initialize a couple of the slots. The PLT should * look like: @@ -36,54 +26,10 @@ GOT_BASE[3] = (int) MODULE; \ } -/* - * 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_SPARC_32: \ - *REL = SYMBOL + (RELP)->r_addend; \ - break; \ - case R_SPARC_GLOB_DAT: \ - *REL = SYMBOL + (RELP)->r_addend; \ - break; \ - case R_SPARC_JMP_SLOT: \ - REL[1] = 0x03000000 | ((SYMBOL >> 10) & 0x3fffff); \ - REL[2] = 0x81c06000 | (SYMBOL & 0x3ff); \ - break; \ - case R_SPARC_NONE: \ - break; \ - case R_SPARC_WDISP30: \ - break; \ - case R_SPARC_RELATIVE: \ - *REL += (unsigned int) LOAD + (RELP)->r_addend; \ - break; \ - default: \ - _dl_exit(1); \ - } - - -/* - * Transfer control to the user's application, once the dynamic loader - * is done. The crt calls atexit with $g1 if not null, so we need to - * ensure that it contains NULL. - */ - -#define START() \ - __asm__ volatile ( \ - "add %%g0,%%g0,%%g1\n\t" \ - "jmpl %0, %%o7\n\t" \ - "restore %%g0,%%g0,%%g0\n\t" \ - : /*"=r" (status) */ : \ - "r" (_dl_elf_main): "g1", "o0", "o1") - - - /* Here we define the magic numbers that this dynamic loader should accept */ - #define MAGIC1 EM_SPARC #undef MAGIC2 + /* Used for error messages */ #define ELF_TARGET "Sparc" |