Browse Source

Seperate out the startup stuff from the non-startup stuff.
Begin converting some big ugly macros to inline functions
instead

Eric Andersen 20 years ago
parent
commit
e5649e6176

+ 87 - 13
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;
+
+

+ 32 - 96
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

+ 49 - 2
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))
+
+

+ 1 - 52
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 */

+ 49 - 5
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))
+
+
+
+

+ 9 - 57
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"
 

+ 63 - 5
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));
+
+
+

+ 0 - 57
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 */

+ 83 - 0
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()
+
+
+

+ 19 - 104
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

+ 53 - 0
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")
+
+
+

+ 0 - 51
ldso/ldso/powerpc/dl-sysdep.h

@@ -8,13 +8,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.
  */
@@ -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

+ 54 - 0
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;
+
+
+
+

+ 3 - 58
ldso/ldso/sh/dl-sysdep.h

@@ -3,18 +3,9 @@
  * 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.
  */
@@ -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" \

+ 135 - 0
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;
+
+

+ 1 - 137
ldso/ldso/sh64/dl-sysdep.h

@@ -4,18 +4,9 @@
  * 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.
  */
@@ -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

+ 56 - 1
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")
+
+
+
+

+ 2 - 56
ldso/ldso/sparc/dl-sysdep.h

@@ -5,19 +5,9 @@
  */
 #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
@@ -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"