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
15 " .type _start,@function\n"
23 #if _MIPS_SIM == _MIPS_SIM_ABI32
25 #else /* N32 || N64 */
26 " .cpsetup $31, $2, 0b\n"
27 #endif /* N32 || N64 */
30 #if _MIPS_SIM == _MIPS_SIM_ABI64
32 " sd $4, -0x7ff0($28)\n"
33 #else /* O32 || N32 */
35 " sw $4, -0x7ff0($28)\n"
36 #endif /* O32 || N32 */
38 #if _MIPS_SIM == _MIPS_SIM_ABI32
41 #if _MIPS_SIM == _MIPS_SIM_ABI64
43 #else /* O32 || N32 */
45 #endif /* O32 || N32 */
46 # if !defined __mips_isa_rev || __mips_isa_rev < 6
53 #if _MIPS_SIM == _MIPS_SIM_ABI64
54 " dsubu $8, $31, $8\n"
55 " dla $25, _dl_start\n"
57 #else /* O32 || N32 */
59 " la $25, _dl_start\n"
61 #endif /* O32 || N32 */
63 #if _MIPS_SIM == _MIPS_SIM_ABI32
68 #if _MIPS_SIM == _MIPS_SIM_ABI64
69 " ld $2, _dl_skip_args\n"
82 " and $2, $29, -4 * 4\n"
84 " dsubu $29, $2, 32\n"
87 #else /* O32 || N32 */
88 " lw $2, _dl_skip_args\n"
101 " and $2, $29, -2 * 4\n"
103 " subu $29, $2, 32\n"
104 #if _MIPS_SIM == _MIPS_SIM_ABI32
109 #endif /* O32 || N32 */
113 ".size _start, . -_start\n"
121 * Get a pointer to the argv array. On many platforms this can be just
122 * the address of the first argument, on other platforms we need to
123 * do something a little more subtle here.
125 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS)+1)
128 /* We can't call functions earlier in the dl startup process */
129 #define NO_FUNCS_BEFORE_BOOTSTRAP
133 * Here is a macro to perform the GOT relocation. This is only
134 * used when bootstrapping the dynamic loader.
136 #define PERFORM_BOOTSTRAP_GOT(tpnt) \
140 register ElfW(Addr) gp __asm__ ("$28"); \
141 ElfW(Addr) *mipsgot = elf_mips_got_from_gpreg (gp); \
143 /* Add load address displacement to all local GOT entries */ \
145 while (i < tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
146 mipsgot[i++] += tpnt->loadaddr; \
148 /* Handle global GOT entries */ \
149 mipsgot += tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; \
150 sym = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB] + \
151 tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX]; \
152 i = tpnt->dynamic_info[DT_MIPS_SYMTABNO_IDX] - tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX];\
155 if (sym->st_shndx == SHN_UNDEF || \
156 sym->st_shndx == SHN_COMMON) \
157 *mipsgot = tpnt->loadaddr + sym->st_value; \
158 else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && \
159 *mipsgot != sym->st_value) \
160 *mipsgot += tpnt->loadaddr; \
161 else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) { \
162 if (sym->st_other == 0) \
163 *mipsgot += tpnt->loadaddr; \
166 *mipsgot = tpnt->loadaddr + sym->st_value; \
174 * Here is a macro to perform a relocation. This is only used when
175 * bootstrapping the dynamic loader.
177 #if _MIPS_SIM == _MIPS_SIM_ABI64 /* consult with glibc sysdeps/mips/dl-machine.h 1.69 */
178 #define R_MIPS_BOOTSTRAP_RELOC ((R_MIPS_64 << 8) | R_MIPS_REL32)
179 #else /* N32 || O32 */
180 #define R_MIPS_BOOTSTRAP_RELOC R_MIPS_REL32
182 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
183 switch(ELF_R_TYPE((RELP)->r_info)) { \
184 case R_MIPS_BOOTSTRAP_RELOC: \
186 if (symtab_index<tpnt->dynamic_info[DT_MIPS_GOTSYM_IDX])\