root/libexec/ld.so/amd64/ldasm.S
/*      $OpenBSD: ldasm.S,v 1.31 2023/05/18 16:33:39 guenther Exp $     */

/*
 * Copyright (c) 2002,2004 Dale Rahn
 * All rights reserved.
 *
 * 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 DL_DATA_SIZE    (16*8)   /* 16 * sizeof(ELF_Addr) */
#define DL_LOFF_OFFSET  (7*8)   /* index 7 */
#include <machine/asm.h>

        .section .boot.text,"ax",@progbits
        .align  16,0xcc
        .globl  _dl_start
        .type   _dl_start,@function
_dl_start:
        movq    %rsp, %r12              # save stack pointer for _rtld

        subq    $8, %rsp                # align stack
        andq    $~15, %rsp
        addq    $8, %rsp

        pushq   %rbx                    # save ps_strings
        subq    $DL_DATA_SIZE, %rsp     # allocate dl_data

        leaq    _DYNAMIC(%rip),%rdx     # &_DYNAMIC
        movq    %rsp, %rsi              # dl_data for dl_boot_bind
        movq    %r12, %rdi              # load saved SP for dl_boot_bind
        call    _dl_boot_bind@PLT       # _dl_boot_bind(sp,dl_data,dynamicp)

        movq    %rsp, %rcx              # dl_data
        movq    DL_LOFF_OFFSET(%rsp), %rdx              # loff from dl_data

        movq    (%r12), %rdi
        leaq    16(%r12,%rdi,8), %rsi   # envp
        movq    %r12, %rdi
        addq    $8,%rdi                 # argv
        call    _dl_boot@PLT            # _dl_boot(argv,envp,loff,dl_data)

        addq    $DL_DATA_SIZE,%rsp      # return dl_data

        leaq    _dl_dtors(%rip), %rdx   # %rdx = cleanup
        movq    %r12, %rsp
        jmp     *%rax
END(_dl_start)

_ENTRY(_dl_bind_start)
        .cfi_startproc
        .cfi_adjust_cfa_offset  16
        endbr64
        pushfq                          # save registers
        .cfi_adjust_cfa_offset  8
        /*.cfi_offset   %rflags, -16 */
        pushq   %rax
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %rax, -24
        pushq   %rcx
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %rcx, -32
        pushq   %rdx
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %rdx, -40
        pushq   %rsi
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %rsi, -48
        pushq   %rdi
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %rdi, -56
        pushq   %r8
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %r8, -64
        pushq   %r9
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %r9, -72
        pushq   %r10
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %r10, -80
        pushq   %r11
        .cfi_adjust_cfa_offset  8
        .cfi_offset     %r11, -88

        movq    80(%rsp), %rdi          # Copy of reloff
        movq    88(%rsp), %rsi          # Copy of obj
        call    _dl_bind@PLT            # Call the binder
        movq    %rax,88(%rsp)           # Store function to be called in obj

        popq    %r11                    # restore registers
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %r11
        popq    %r10
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %r10
        popq    %r9
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %r9
        popq    %r8
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %r8
        popq    %rdi
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %rdi
        popq    %rsi
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %rsi
        popq    %rdx
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %rdx
        popq    %rcx
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %rcx
        popq    %rax
        .cfi_adjust_cfa_offset  -8
        .cfi_restore    %rax
        popfq
        .cfi_adjust_cfa_offset  -8
        /*.cfi_restore  %rflags */

        leaq    8(%rsp),%rsp            # Discard reloff, do not change eflags
        .cfi_adjust_cfa_offset  -8
        ret
        .cfi_endproc
END(_dl_bind_start)