123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /* 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 */
- # if !defined __mips_isa_rev || __mips_isa_rev < 6
- " bltzal $8, .coff\n"
- ".coff:\n"
- # else
- ".coff:\n"
- " lapc $31, .coff\n"
- # endif
- #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); \
- }
|