summaryrefslogtreecommitdiff
path: root/ldso/ldso/mips/dl-startup.h
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2006-11-04 20:14:10 +0000
committerEric Andersen <andersen@codepoet.org>2006-11-04 20:14:10 +0000
commitbcd949c7f80ccf66c8ef869367a9b33dbb51a261 (patch)
tree981e52a9924916366df69688e042f3ad427a22c4 /ldso/ldso/mips/dl-startup.h
parent980871f06dc4b2359b589fd9d720ed3fc8c3a925 (diff)
mips64 patch from Atsushi Nemoto:
64bit MIPS ELF format tweaks. (from glibc) Elf32/ElfW convertions. asm code adjustments.
Diffstat (limited to 'ldso/ldso/mips/dl-startup.h')
-rw-r--r--ldso/ldso/mips/dl-startup.h70
1 files changed, 61 insertions, 9 deletions
diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h
index bf461d3b8..4e3fcafb8 100644
--- a/ldso/ldso/mips/dl-startup.h
+++ b/ldso/ldso/mips/dl-startup.h
@@ -6,6 +6,7 @@
*/
+#include <sgidefs.h>
asm(""
" .text\n"
" .globl _start\n"
@@ -17,23 +18,66 @@ asm(""
" 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"
@@ -50,9 +94,12 @@ asm(""
" 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"
@@ -80,10 +127,10 @@ asm(""
*/
#define PERFORM_BOOTSTRAP_GOT(tpnt) \
do { \
- Elf32_Sym *sym; \
- Elf32_Addr i; \
+ ElfW(Sym) *sym; \
+ ElfW(Addr) i; \
register ElfW(Addr) gp __asm__ ("$28"); \
- Elf32_Addr *mipsgot = elf_mips_got_from_gpreg (gp); \
+ ElfW(Addr) *mipsgot = elf_mips_got_from_gpreg (gp); \
\
/* Add load address displacement to all local GOT entries */ \
i = 2; \
@@ -92,18 +139,18 @@ do { \
\
/* Handle global GOT entries */ \
mipsgot += tpnt->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]; \
- sym = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB] + \
- tpnt->dynamic_info[DT_MIPS_GOTSYM_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 (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
+ else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && \
*mipsgot != sym->st_value) \
*mipsgot += tpnt->loadaddr; \
- else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
+ else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) { \
if (sym->st_other == 0) \
*mipsgot += tpnt->loadaddr; \
} \
@@ -119,9 +166,14 @@ do { \
* 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(ELF32_R_TYPE((RELP)->r_info)) { \
- case R_MIPS_REL32: \
+ 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; \