Home | History | Annotate | Download | only in mips64
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <private/bionic_asm.h>
     30 
     31 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
     32 #define ELF_DYNSZ       8
     33 #define ELF_DYN_TAG     0
     34 #define ELF_DYN_VAL     4
     35 #define GOTENT_SZ       4
     36 #else
     37 #define ELF_DYNSZ       16
     38 #define ELF_DYN_TAG     0
     39 #define ELF_DYN_VAL     8
     40 #define GOTENT_SZ       8
     41 #endif
     42 
     43     .text
     44     .align	4
     45     .type	__start,@function
     46 
     47     .ent	__start
     48     .globl	__start
     49     .globl	_start
     50 __start:
     51 _start:
     52     .set	noreorder
     53     bal		1f
     54      nop
     55 1:
     56 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
     57     .cpload	ra
     58 #else
     59     .cpsetup	ra, $0, 1b
     60 #endif
     61     .set	reorder
     62 
     63     /* Discover the load address */
     64     LA		t0, 1b
     65     PTR_SUBU	t0, ra, t0
     66 
     67 #define DT_PLTGOT 3
     68 #define DT_MIPS_LOCAL_GOTNO 0x7000000a
     69 
     70     /* Search dynamic table for DT_MIPS_LOCAL_GOTNO and DT_PLTGOT values */
     71     LA		t1, _DYNAMIC
     72     PTR_ADDU	t1, t0
     73     LI		t3, DT_PLTGOT
     74     LI		ta0, DT_MIPS_LOCAL_GOTNO
     75 0:
     76     REG_L	t2, ELF_DYN_TAG(t1)
     77     beqz	t2, .Lrelocate_local_got
     78 
     79     bne		t2, t3, 1f	/* DT_PLTGOT? */
     80     REG_L	s0, ELF_DYN_VAL(t1)
     81     PTR_ADDU	s0, t0
     82     b		2f
     83 
     84 1:
     85     bne		t2, ta0, 2f    /* DT_MIPS_LOCAL_GOTNO? */
     86     REG_L	s1, ELF_DYN_VAL(t1)
     87 
     88 2:  PTR_ADDU    t1, ELF_DYNSZ
     89     b		0b
     90 
     91 .Lrelocate_local_got:
     92     /*
     93      * Relocate the local GOT entries
     94      * got[0] is address of lazy resolver function
     95      * got[1] may be used for a GNU extension
     96      */
     97 
     98     PTR_ADDU	s0, GOTENT_SZ
     99     SUBU	s1, 1
    100     PTR_L	t1, (s0)
    101     bgez	t1, 9f
    102     PTR_ADDU	s0, GOTENT_SZ
    103     SUBU	s1, 1
    104     b		9f
    105 
    106 1:  PTR_L	t1, (s0)
    107     PTR_ADDU	t1, t0
    108     PTR_S	t1, (s0)
    109     PTR_ADDU	s0, GOTENT_SZ
    110 9:  SUBU	s1, 1
    111     bgez	s1, 1b
    112 
    113     /* call linker_init */
    114     move	a0, sp
    115 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
    116     PTR_SUBU	sp, 4*REGSZ       /* space for arg saves in linker_init */
    117 #endif
    118     jal		__linker_init
    119 #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
    120     PTR_ADDU	sp, 4*REGSZ        /* restore sp */
    121 #endif
    122     move	t9, v0
    123     j		t9
    124     .end    __start
    125