diff options
author | Maciej W. Rozycki <macro@codesourcery.com> | 2013-02-27 23:45:07 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@codesourcery.com> | 2013-02-27 23:45:07 +0000 |
commit | 43301bd3c281036ba97eef384c9340cc7b6130d3 (patch) | |
tree | 263f0cc7e01c33c72e626480a52b2bfc1dce78f0 /ports/sysdeps/mips/dl-machine.h | |
parent | 85bd816a603a437aedeb688a60a3e0dba4439c50 (diff) | |
download | glibc-43301bd3c281036ba97eef384c9340cc7b6130d3.tar.gz glibc-43301bd3c281036ba97eef384c9340cc7b6130d3.tar.xz glibc-43301bd3c281036ba97eef384c9340cc7b6130d3.zip |
Add support for building as MIPS16 code.
Diffstat (limited to 'ports/sysdeps/mips/dl-machine.h')
-rw-r--r-- | ports/sysdeps/mips/dl-machine.h | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/ports/sysdeps/mips/dl-machine.h b/ports/sysdeps/mips/dl-machine.h index 91f7a7bb5e..a7c784fec5 100644 --- a/ports/sysdeps/mips/dl-machine.h +++ b/ports/sysdeps/mips/dl-machine.h @@ -119,6 +119,7 @@ static inline ElfW(Addr) elf_machine_load_address (void) { ElfW(Addr) addr; +#ifndef __mips16 asm (" .set noreorder\n" " " STRINGXP (PTR_LA) " %0, 0f\n" " bltzal $0, 0f\n" @@ -128,6 +129,19 @@ elf_machine_load_address (void) : "=r" (addr) : /* No inputs */ : "$31"); +#else + ElfW(Addr) tmp; + asm (" .set noreorder\n" + " move %1,$gp\n" + " lw %1,%%got(0f)(%1)\n" + "0: .fill 0\n" /* Clear the ISA bit on 0:. */ + " la %0,0b\n" + " addiu %1,%%lo(0b)\n" + " subu %0,%1\n" + " .set reorder\n" + : "=d" (addr), "=d" (tmp) + : /* No inputs */); +#endif return addr; } @@ -210,7 +224,8 @@ do { \ 2) That under Unix the entry is named __start and not just plain _start. */ -#define RTLD_START asm (\ +#ifndef __mips16 +# define RTLD_START asm (\ ".text\n\ " _RTLD_PROLOGUE(ENTRY_POINT) "\ " STRINGXV(SETUP_GPX($25)) "\n\ @@ -283,6 +298,91 @@ do { \ ".previous"\ ); +#else /* __mips16 */ +/* MIPS16 version. We currently only support O32 under MIPS16; the proper + assembly preprocessor abstractions will need to be added if other ABIs + are to be supported. */ + +# define RTLD_START asm (\ + ".text\n\ + .set mips16\n\ + " _RTLD_PROLOGUE (ENTRY_POINT) "\ + # Construct GP value in $3.\n\ + li $3, %hi(_gp_disp)\n\ + addiu $4, $pc, %lo(_gp_disp)\n\ + sll $3, 16\n\ + addu $3, $4\n\ + move $28, $3\n\ + lw $4, %got(_DYNAMIC)($3)\n\ + sw $4, -0x7ff0($3)\n\ + move $4, $sp\n\ + addiu $sp, -16\n\ + # _dl_start() is sufficiently near to use pc-relative\n\ + # load address.\n\ + la $3, _dl_start\n\ + move $25, $3\n\ + jalr $3\n\ + addiu $sp, 16\n\ + " _RTLD_EPILOGUE (ENTRY_POINT) "\ + \n\ + \n\ + " _RTLD_PROLOGUE (_dl_start_user) "\ + li $16, %hi(_gp_disp)\n\ + addiu $4, $pc, %lo(_gp_disp)\n\ + sll $16, 16\n\ + addu $16, $4\n\ + move $17, $2\n\ + move $28, $16\n\ + lw $4, %got(_dl_skip_args)($16)\n\ + lw $4, 0($4)\n\ + beqz $4, 1f\n\ + # Load the original argument count.\n\ + lw $5, 0($sp)\n\ + # Subtract _dl_skip_args from it.\n\ + subu $5, $4\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sll $4, " STRINGXP (PTRLOG) "\n\ + move $6, $sp\n\ + addu $6, $4\n\ + move $sp, $6\n\ + # Save back the modified argument count.\n\ + sw $5, 0($sp)\n\ +1: # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env) \n\ + lw $4, %got(_rtld_local)($16)\n\ + lw $4, 0($4)\n\ + lw $5, 0($sp)\n\ + addiu $6, $sp, " STRINGXP (PTRSIZE) "\n\ + sll $7, $5, " STRINGXP (PTRLOG) "\n\ + addu $7, $6\n\ + addu $7, " STRINGXP (PTRSIZE) "\n\ + # Make sure the stack pointer is aligned for _dl_init_internal.\n\ + li $2, 2 * " STRINGXP (SZREG) "\n\ + neg $2, $2\n\ + move $3, $sp\n\ + and $2, $3\n\ + sw $3, -" STRINGXP (SZREG) "($2)\n\ + addiu $2, -32\n\ + move $sp, $2\n\ + sw $16, 16($sp)\n\ + # Call the function to run the initializers.\n\ + lw $2, %call16(_dl_init_internal)($16)\n\ + move $25, $2\n\ + jalr $2\n\ + # Restore the stack pointer for _start.\n\ + lw $2, 32-" STRINGXP (SZREG) "($sp)\n\ + move $sp, $2\n\ + move $28, $16\n\ + # Pass our finalizer function to the user in $2 as per ELF ABI.\n\ + lw $2, %call16(_dl_fini)($16)\n\ + # Jump to the user entry point.\n\ + move $25, $17\n\ + jr $17\n\t"\ + _RTLD_EPILOGUE (_dl_start_user)\ + ".previous"\ +); + +#endif /* __mips16 */ + /* Names of the architecture-specific auditing callback functions. */ # if _MIPS_SIM == _ABIO32 # define ARCH_LA_PLTENTER mips_o32_gnu_pltenter |