root/libexec/ld.so/powerpc/ldasm.S
/*      $OpenBSD: ldasm.S,v 1.34 2019/07/01 15:57:34 kettenis Exp $ */

/*
 * Copyright (c) 1999 Dale Rahn
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#define AUX_entry 9

#include <machine/asm.h>
#include <sys/syscall.h>

        .section .boot.text,"ax",@progbits
        .align  2
        .globl  _dl_start
        .type   _dl_start,@function
_dl_start:
        mr      19, 1
        stwu    1, (-16 -((AUX_entry+3)*4))(1)  # Some space.

        mflr    27              /* save off old link register */
        stw     27, 4(19)       /* save in normal location */

        # squirrel away the arguments for main
        mr      20, 3   #argc
        mr      21, 4   #argv
        mr      22, 5   #envp
        mr      23, 6   # ???

        bcl     20, 31, 1f
1:      mflr    30
        addis   30, 30, _GLOBAL_OFFSET_TABLE_-1b@ha
        addi    30, 30, _GLOBAL_OFFSET_TABLE_-1b@l

        bcl     20, 31, 1f
1:      mflr    18
        addis   18, 18, _DYNAMIC-1b@ha
        addi    18, 18, _DYNAMIC-1b@l
        lwz     4, 0(30)        # load address of _DYNAMIC according to got.
        sub     4, 18, 4        # determine load offset

        mr      17, 4           # save for _dl_boot

        subi    3, 21, 4        # Get stack pointer (arg0 for _dl_boot).
        addi    4, 1, 8         # dl_data
        mr      5, 18           # dynamicp

        bl      _dl_boot_bind@local

        mr      3, 21           # argv
        mr      4, 22           # envp
        mr      5, 17           # loff
        addi    6, 1, 8         # dl_data

        bl      _dl_boot@local

        mtctr   3               # put return value into ctr to execute

        # get back the squirreled away the arguments for main
        mr      3, 20
        mr      4, 21
        mr      5, 22
        mr      6, 23

        lwz     7, _dl_dtors@got(30)

        mtlr    27
        lwz     1, 0(1)         # Restore stack pointer.
        bctr                    # Go execute the 'real' program.
END(_dl_start)

ENTRY(_dl_bind_start)
        stwu    1,-72(1)

        stw     0,8(1)          # save r0 - cerror ;-)
        mflr    0
        stw     0,68(1)         # save  lr

        stw     3,12(1)         # save  r3-r10, C calling convention
        stw     4,20(1)         # r13 - r31 are preserved by called code
        stw     5,24(1)
        stw     6,28(1)
        stw     7,32(1)
        stw     8,36(1)
        stw     9,40(1)
        stw     10,44(1)

        mr      3,12            # obj
        mr      4,11            # reloff
        bl      _dl_bind@plt    #       _rtld_bind(obj, reloff)
        mtctr   3

        lwz     3,12(1)
        lwz     4,20(1)
        lwz     5,24(1)
        lwz     6,28(1)
        lwz     7,32(1)
        lwz     8,36(1)
        lwz     9,40(1)
        lwz     10,44(1)

        lwz     0,68(1)         # restore lr
        mtlr    0
        lwz     0,8(1)

        addi    1,1,72
        bctr
END(_dl_bind_start)