1 /* Any assembly language/system dependent hacks needed to setup boot1.c so it
2 * will work as expected and cope with whatever platform specific wierdness is
3 * needed for this architecture.
4 * Copyright (C) 2005 by Joakim Tjernlund
5 * Copyright (C) 2005 by Erik Andersen
14 " .type _start,@function\n"
22 #if _MIPS_SIM == _MIPS_SIM_ABI32
24 #else /* N32 || N64 */
25 " .cpsetup $31, $2, 0b\n"
26 #endif /* N32 || N64 */
29 #if _MIPS_SIM == _MIPS_SIM_ABI64
31 " sd $4, -0x7ff0($28)\n"
32 #else /* O32 || N32 */
34 " sw $4, -0x7ff0($28)\n"
35 #endif /* O32 || N32 */
37 #if _MIPS_SIM == _MIPS_SIM_ABI32
40 #if _MIPS_SIM == _MIPS_SIM_ABI64
42 #else /* O32 || N32 */
44 #endif /* O32 || N32 */
47 #if _MIPS_SIM == _MIPS_SIM_ABI64
48 " dsubu $8, $31, $8\n"
49 " dla $25, _dl_start\n"
51 #else /* O32 || N32 */
53 " la $25, _dl_start\n"
55 #endif /* O32 || N32 */
57 #if _MIPS_SIM == _MIPS_SIM_ABI32
62 #if _MIPS_SIM == _MIPS_SIM_ABI64
63 " ld $2, _dl_skip_args\n"
76 " and $2, $29, -4 * 4\n"
78 " dsubu $29, $2, 32\n"
81 #else /* O32 || N32 */
82 " lw $2, _dl_skip_args\n"
95 " and $2, $29, -2 * 4\n"
98 #if _MIPS_SIM == _MIPS_SIM_ABI32
103 #endif /* O32 || N32 */
107 ".size _start, . -_start\n"
114 * Get a pointer to the argv array. On many platforms this can be just
115 * the address of the first argument, on other platforms we need to
116 * do something a little more subtle here.
118 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS)+1)
121 /* We can't call functions earlier in the dl startup process */
122 #define NO_FUNCS_BEFORE_BOOTSTRAP
126 * Here is a macro to perform the GOT relocation. This is only
127 * used when bootstrapping the dynamic loader.
129 #define PERFORM_BOOTSTRAP_GOT(tpnt) \
133 register ElfW(Addr) gp __asm__ ("$28"); \
134 ElfW(Addr) *mipsgot = elf_mips_got_from_gpreg (gp); \
136 /* Add load address displacement to all local GOT entries */ \
138 while (i < tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
139 mipsgot[i++] += tpnt->loadaddr; \
141 /* Handle global GOT entries */ \
142 mipsgot += tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; \
143 sym = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB] + \
144 tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; \
145 i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX];\
148 if (sym->st_shndx == SHN_UNDEF || \
149 sym->st_shndx == SHN_COMMON) \
150 *mipsgot = tpnt->loadaddr + sym->st_value; \
151 else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && \
152 *mipsgot != sym->st_value) \
153 *mipsgot += tpnt->loadaddr; \
154 else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) { \
155 if (sym->st_other == 0) \
156 *mipsgot += tpnt->loadaddr; \
159 *mipsgot = tpnt->loadaddr + sym->st_value; \
167 * Here is a macro to perform a relocation. This is only used when
168 * bootstrapping the dynamic loader.
170 #if _MIPS_SIM == _MIPS_SIM_ABI64 /* consult with glibc sysdeps/mips/dl-machine.h 1.69 */
171 #define R_MIPS_BOOTSTRAP_RELOC ((R_MIPS_64 << 8) | R_MIPS_REL32)
172 #else /* N32 || O32 */
173 #define R_MIPS_BOOTSTRAP_RELOC R_MIPS_REL32
175 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
176 switch(ELF_R_TYPE((RELP)->r_info)) { \
177 case R_MIPS_BOOTSTRAP_RELOC: \
179 if (symtab_index<tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX])\
189 SEND_STDERR("Aiieeee!"); \