--- /dev/null
+/* Any assembly 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.
+ * Copyright (C) 2005 by Joakim Tjernlund
+ * Copyright (C) 2005 by Erik Andersen
+ */
+
+
+#include <sgidefs.h>
+__asm__(""
+ " .text\n"
+ " .globl _start\n"
+ " .ent _start\n"
+ " .type _start,@function\n"
+ " .hidden _start\n"
+ "_start:\n"
+ " .set noreorder\n"
+ " move $25, $31\n"
+ " bal 0f\n"
+ " nop\n"
+ "0:\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ " .cpload $31\n"
+#else /* N32 || N64 */
+ " .cpsetup $31, $2, 0b\n"
+#endif /* N32 || N64 */
+ " move $31, $25\n"
+ " .set reorder\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ " dla $4, _DYNAMIC\n"
+ " sd $4, -0x7ff0($28)\n"
+#else /* O32 || N32 */
+ " la $4, _DYNAMIC\n"
+ " sw $4, -0x7ff0($28)\n"
+#endif /* O32 || N32 */
+ " move $4, $29\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ " subu $29, 16\n"
+#endif
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ " dla $8, .coff\n"
+#else /* O32 || N32 */
+ " la $8, .coff\n"
+#endif /* O32 || N32 */
+ " bltzal $8, .coff\n"
+ ".coff:\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ " dsubu $8, $31, $8\n"
+ " dla $25, _dl_start\n"
+ " daddu $25, $8\n"
+#else /* O32 || N32 */
+ " subu $8, $31, $8\n"
+ " la $25, _dl_start\n"
+ " addu $25, $8\n"
+#endif /* O32 || N32 */
+ " jalr $25\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ " addiu $29, 16\n"
+#endif
+ " move $16, $28\n"
+ " move $17, $2\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ " ld $2, _dl_skip_args\n"
+ " beq $2, $0, 1f\n"
+ " ld $4, 0($29)\n"
+ " dsubu $4, $2\n"
+ " dsll $2, 2\n"
+ " daddu $29, $2\n"
+ " sd $4, 0($29)\n"
+ "1:\n"
+ " ld $5, 0($29)\n"
+ " dla $6, 8 ($29)\n"
+ " dsll $7, $5, 2\n"
+ " daddu $7, $7, $6\n"
+ " daddu $7, $7, 4\n"
+ " and $2, $29, -4 * 4\n"
+ " sd $29, -8($2)\n"
+ " dsubu $29, $2, 32\n"
+ " ld $29, 24($29)\n"
+ " dla $2, _dl_fini\n"
+#else /* O32 || N32 */
+ " lw $2, _dl_skip_args\n"
+ " beq $2, $0, 1f\n"
+ " lw $4, 0($29)\n"
+ " subu $4, $2\n"
+ " sll $2, 2\n"
+ " addu $29, $2\n"
+ " sw $4, 0($29)\n"
+ "1:\n"
+ " lw $5, 0($29)\n"
+ " la $6, 4 ($29)\n"
+ " sll $7, $5, 2\n"
+ " addu $7, $7, $6\n"
+ " addu $7, $7, 4\n"
+ " and $2, $29, -2 * 4\n"
+ " sw $29, -4($2)\n"
+ " subu $29, $2, 32\n"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ " .cprestore 16\n"
+#endif
+ " lw $29, 28($29)\n"
+ " la $2, _dl_fini\n"
+#endif /* O32 || N32 */
+ " move $25, $17\n"
+ " jr $25\n"
+ ".end _start\n"
+ ".size _start, . -_start\n"
+ "\n\n"
+ "\n\n"
+ ".previous\n"
+);
+
+/*
+ * Get a pointer to the argv array. On many platforms this can be just
+ * the address of 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)
+
+
+/* We can't call functions earlier in the dl startup process */
+#define NO_FUNCS_BEFORE_BOOTSTRAP
+
+
+/*
+ * Here is a macro to perform the GOT relocation. This is only
+ * used when bootstrapping the dynamic loader.
+ */
+#define PERFORM_BOOTSTRAP_GOT(tpnt) \
+do { \
+ ElfW(Sym) *sym; \
+ ElfW(Addr) i; \
+ register ElfW(Addr) gp __asm__ ("$28"); \
+ ElfW(Addr) *mipsgot = elf_mips_got_from_gpreg (gp); \
+ \
+ /* Add load address displacement to all local GOT entries */ \
+ i = 2; \
+ while (i < tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
+ mipsgot[i++] += tpnt->loadaddr; \
+ \
+ /* Handle global GOT entries */ \
+ mipsgot += tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; \
+ sym = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB] + \
+ tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; \
+ i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX];\
+ \
+ while (i--) { \
+ if (sym->st_shndx == SHN_UNDEF || \
+ sym->st_shndx == SHN_COMMON) \
+ *mipsgot = tpnt->loadaddr + sym->st_value; \
+ else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && \
+ *mipsgot != sym->st_value) \
+ *mipsgot += tpnt->loadaddr; \
+ else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) { \
+ if (sym->st_other == 0) \
+ *mipsgot += tpnt->loadaddr; \
+ } \
+ else \
+ *mipsgot = tpnt->loadaddr + sym->st_value; \
+ \
+ mipsgot++; \
+ sym++; \
+ } \
+} while (0)
+
+/*
+ * Here is a macro to perform a relocation. This is only used when
+ * bootstrapping the dynamic loader.
+ */
+#if _MIPS_SIM == _MIPS_SIM_ABI64 /* consult with glibc sysdeps/mips/dl-machine.h 1.69 */
+#define R_MIPS_BOOTSTRAP_RELOC ((R_MIPS_64 << 8) | R_MIPS_REL32)
+#else /* N32 || O32 */
+#define R_MIPS_BOOTSTRAP_RELOC R_MIPS_REL32
+#endif
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
+ switch(ELF_R_TYPE((RELP)->r_info)) { \
+ case R_MIPS_BOOTSTRAP_RELOC: \
+ if (SYMTAB) { \
+ if (symtab_index<tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX])\
+ *REL += SYMBOL; \
+ } \
+ else { \
+ *REL += LOAD; \
+ } \
+ break; \
+ case R_MIPS_NONE: \
+ break; \
+ default: \
+ SEND_STDERR("Aiieeee!"); \
+ _dl_exit(1); \
+ }