Path: blob/main/libexec/rtld-elf/amd64/rtld_start.S
34923 views
/*-1* Copyright 1996-1998 John D. Polstra.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR14* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES15* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,17* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT18* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,19* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY20* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT21* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF22* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.23*/2425.text26.align 427.globl .rtld_start28.type .rtld_start,@function29.rtld_start:30.cfi_startproc31.cfi_undefined %rip32xorq %rbp,%rbp # Clear frame pointer for good form33subq $24,%rsp # A place to store exit procedure addr34.cfi_def_cfa_offset 3235movq %rdi,%r1236movq %rsp,%rsi # save address of exit proc37movq %rsp,%rdx # construct address of obj_main38addq $8,%rdx39call _rtld # Call rtld(sp); returns entry point40popq %rsi # Get exit procedure address41.cfi_def_cfa_offset 2442movq %r12,%rdi # *ap43/*44* At this point, %rax contains the entry point of the main program, and45* %rdx contains a pointer to a termination function that should be46* registered with atexit(). (crt1.o registers it.)47*/48.globl .rtld_goto_main49.rtld_goto_main: # This symbol exists just to make debugging easier.50jmp *%rax # Enter main program51.cfi_endproc525354/*55* Binder entry point. Control is transferred to here by code in the PLT.56* On entry, there are two arguments on the stack. In ascending address57* order, they are (1) "obj", a pointer to the calling object's Obj_Entry,58* and (2) "reloff", the byte offset of the appropriate relocation entry59* in the PLT relocation table.60*61* We are careful to preserve all registers, even the caller-save62* registers. That is because this code may be invoked by low-level63* assembly-language code that is not ABI-compliant.64*65* Stack map:66* reloff 0x6067* obj 0x5868* spare 0x5069* rflags 0x4870* rax 0x4071* rdx 0x3872* rcx 0x3073* rsi 0x2874* rdi 0x2075* r8 0x1876* r9 0x1077* r10 0x878* r11 0x079*/80.align 481.globl _rtld_bind_start82.type _rtld_bind_start,@function83_rtld_bind_start:84.cfi_startproc85.cfi_adjust_cfa_offset 1686subq $8,%rsp87.cfi_adjust_cfa_offset 888pushfq # Save rflags89.cfi_adjust_cfa_offset 890pushq %rax # Save %rax91.cfi_adjust_cfa_offset 892.cfi_offset %rax,-3293pushq %rdx # Save %rdx94.cfi_adjust_cfa_offset 895.cfi_offset %rdx,-4096pushq %rcx # Save %rcx97.cfi_adjust_cfa_offset 898.cfi_offset %rcx,-4899pushq %rsi # Save %rsi100.cfi_adjust_cfa_offset 8101.cfi_offset %rsi,-56102pushq %rdi # Save %rdi103.cfi_adjust_cfa_offset 8104.cfi_offset %rdi,-64105pushq %r8 # Save %r8106.cfi_adjust_cfa_offset 8107.cfi_offset %r8,-72108pushq %r9 # Save %r9109.cfi_adjust_cfa_offset 8110.cfi_offset %r9,-80111pushq %r10 # Save %r10112.cfi_adjust_cfa_offset 8113.cfi_offset %r10,-88114pushq %r11 # Save %r11115.cfi_adjust_cfa_offset 8116.cfi_offset %r11,-96117118movq 0x58(%rsp),%rdi # Fetch obj argument119movq 0x60(%rsp),%rsi # Fetch reloff argument120leaq (%rsi,%rsi,2),%rsi # multiply by 3121leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela)122123call _rtld_bind # Transfer control to the binder124/* Now %rax contains the entry point of the function being called. */125126movq %rax,0x60(%rsp) # Store target over reloff argument127popq %r11 # Restore %r11128.cfi_adjust_cfa_offset -8129.cfi_restore %r11130popq %r10 # Restore %r10131.cfi_adjust_cfa_offset -8132.cfi_restore %r10133popq %r9 # Restore %r9134.cfi_adjust_cfa_offset -8135.cfi_restore %r9136popq %r8 # Restore %r8137.cfi_adjust_cfa_offset -8138.cfi_restore %r8139popq %rdi # Restore %rdi140.cfi_adjust_cfa_offset -8141.cfi_restore %rdi142popq %rsi # Restore %rsi143.cfi_adjust_cfa_offset -8144.cfi_restore %rsi145popq %rcx # Restore %rcx146.cfi_adjust_cfa_offset -8147.cfi_restore %rcx148popq %rdx # Restore %rdx149.cfi_adjust_cfa_offset -8150.cfi_restore %rdx151popq %rax # Restore %rax152.cfi_adjust_cfa_offset -8153.cfi_restore %rax154popfq # Restore rflags155.cfi_adjust_cfa_offset -8156leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags157ret # "Return" to target address158.cfi_endproc159.size _rtld_bind_start, . - _rtld_bind_start160161.align 4162.globl rtld_dynamic_addr163.type rtld_dynamic_addr,@function164rtld_dynamic_addr:165.cfi_startproc166.weak _DYNAMIC167.hidden _DYNAMIC168lea _DYNAMIC(%rip),%rax169ret170.cfi_endproc171.size rtld_dynamic_addr, . - rtld_dynamic_addr172173.section .note.GNU-stack,"",%progbits174175176