From bcd949c7f80ccf66c8ef869367a9b33dbb51a261 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sat, 4 Nov 2006 20:14:10 +0000 Subject: mips64 patch from Atsushi Nemoto: 64bit MIPS ELF format tweaks. (from glibc) Elf32/ElfW convertions. asm code adjustments. --- ldso/ldso/mips/dl-startup.h | 70 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 9 deletions(-) (limited to 'ldso/ldso/mips/dl-startup.h') 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 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_indexdynamic_info[DT_MIPS_GOTSYM_IDX])\ *REL += SYMBOL; \ -- cgit v1.2.3