root/exec/loader-x86_64.s

/* [<][>][^][v][top][bottom][index][help] */
     1 define(`CC', `
     2 dnl')
     3 
     4 CC Copyright (C) 2023 Free Software Foundation, Inc.
     5 CC
     6 CC This file is part of GNU Emacs.
     7 CC
     8 CC GNU Emacs is free software: you can redistribute it and/or modify
     9 CC it under the terms of the GNU General Public License as published
    10 CC by the Free Software Foundation, either version 3 of the License,
    11 CC or (at your option) any later version.
    12 CC
    13 CC GNU Emacs is distributed in the hope that it will be useful, but
    14 CC WITHOUT ANY WARRANTY; without even the implied warranty of
    15 CC MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    16 CC General Public License for more details.
    17 CC
    18 CC You should have received a copy of the GNU General Public License
    19 CC along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
    20 
    21         .section .text
    22         .global _start
    23 _start:
    24 dnl     movq    $35, %rax               CC SYS_nanosleep
    25 dnl     leaq    timespec(%rip), %rdi
    26 dnl     xorq    %rsi, %rsi
    27 dnl     syscall
    28         popq    %r13                    CC original SP
    29         popq    %r15                    CC size of load area.
    30         movq    $-1, %r12               CC r12 is the interpreter fd
    31 .next_action:
    32         movq    (%rsp), %r14            CC action number
    33         movq    %r14, %r15              CC original action number
    34         andq    $-17, %r14
    35         cmpq    $0, %r14                CC open file?
    36         je      .open_file
    37         cmpq    $3, %r14                CC jump?
    38         je      .rest_of_exec
    39         cmpq    $4, %r14                CC anonymous mmap?
    40         je      .do_mmap_anon
    41 .do_mmap:
    42         movq    $9, %rax                CC SYS_mmap
    43         movq    8(%rsp), %rdi           CC address
    44         movq    16(%rsp), %r9           CC offset
    45         movq    24(%rsp), %rdx          CC protection
    46         movq    32(%rsp), %rsi          CC length
    47         movq    40(%rsp), %r10          CC flags
    48                                         CC set r8 to the primary fd unless r15 & 16
    49         testq   $16, %r15
    50         movq    %r12, %r8
    51         cmovzq  %rbx, %r8
    52 .do_mmap_1:
    53         syscall
    54         cmpq    $-1, %rax               CC mmap failed
    55         je      .perror
    56         movq    48(%rsp), %r9           CC clear
    57         testq   %r9, %r9
    58         jz      .continue
    59         movq    8(%rsp), %r10           CC start of mapping
    60         addq    32(%rsp), %r10          CC end of mapping
    61         subq    %r9, %r10               CC start of clear area
    62 .again:
    63         testq   %r9, %r9
    64         jz      .continue
    65         subq    $1, %r9
    66         movb    $0, (%r10, %r9, 1)
    67         jmp     .again
    68 .continue:
    69         leaq    56(%rsp), %rsp
    70         jmp     .next_action
    71 .do_mmap_anon:
    72         movq    $9, %rax                CC SYS_mmap
    73         movq    8(%rsp), %rdi           CC address
    74         movq    16(%rsp), %r9           CC offset
    75         movq    24(%rsp), %rdx          CC protection
    76         movq    32(%rsp), %rsi          CC length
    77         movq    40(%rsp), %r10          CC flags
    78         movq    $-1, %r8                CC -1
    79         jmp     .do_mmap_1
    80 .open_file:
    81         movq    $2, %rax                CC SYS_open
    82         leaq    8(%rsp), %rdi           CC rdi = %rsp + 8
    83         xorq    %rsi, %rsi              CC flags = O_RDONLY
    84         xorq    %rdx, %rdx              CC mode = 0
    85         syscall
    86         cmpq    $-1, %rax               CC open failed
    87         jle     .perror
    88         movq    %rdi, %rsp              CC rsp = start of string
    89         subq    $1, %rsp
    90         movq    %rsp, %r14              CC r14 = start of string
    91 .nextc:
    92         addq    $1, %rsp
    93         movb    (%rsp), %dil            CC rdi = *rsp
    94         cmpb    $47, %dil               CC *rsp == '/'?
    95         jne     .nextc1
    96         movq    %rsp, %r14              CC r14 = rsp
    97         addq    $1, %r14                CC r14 = char past separator
    98 .nextc1:
    99         cmpb    $0, %dil                CC *rsp == 0?
   100         jne     .nextc
   101         addq    $8, %rsp                CC adjust past rsp prior to rounding
   102         andq    $-8, %rsp               CC round rsp up to the next quad
   103         testq   $16, %r15               CC r15 & 16?
   104         jz      .primary
   105         movq    %rax, %r12              CC otherwise, move fd to r12
   106         jmp     .next_action
   107 .primary:
   108         movq    %rax, %rbx              CC if not, move fd to rbx
   109         movq    $157, %rax              CC SYS_prctl
   110         movq    $15, %rdi               CC PR_SET_NAME
   111         movq    %r14, %rsi              CC arg1
   112         xorq    %rdx, %rdx              CC arg2
   113         xorq    %r10, %r10              CC arg3
   114         xorq    %r8, %r8                CC arg4
   115         xorq    %r9, %r9                CC arg5
   116         syscall
   117         jmp     .next_action
   118 .perror:
   119         movq    %rax, %r12              CC error code
   120         negq    %r12
   121         movq    $1, %rax                CC SYS_write
   122         movq    $1, %rdi                CC stdout
   123         leaq    error(%rip), %rsi       CC buffer
   124         movq    $23, %rdx               CC count
   125         syscall
   126         movq    $60, %rax               CC SYS_exit
   127         movq    %r12, %rdi              CC code
   128         syscall
   129 .rest_of_exec:                          CC rsp now points to six quads:
   130         movq    %rsp, %r8               CC now, they are r8
   131         movq    %r13, %rsp              CC restore SP
   132         popq    %r10                    CC argc
   133         leaq    8(%rsp,%r10,8), %rsp    CC now at start of environ
   134 .skip_environ:
   135         popq    %r10                    CC envp[N]
   136         testq   %r10, %r10              CC envp[n]?
   137         jnz     .skip_environ           CC otherwise, rsp is now at the start of auxv
   138 .one_auxv:
   139         popq    %rcx                    CC auxv type
   140         addq    $8, %rsp                CC skip value
   141         testq   %rcx, %rcx              CC is 0?
   142         jz      .cleanup
   143         cmpq    $3, %rcx                CC is AT_PHDR?
   144         je      .replace_phdr
   145         cmpq    $4, %rcx                CC is AT_PHENT?
   146         je      .replace_phent
   147         cmpq    $5, %rcx                CC is AT_PHNUM?
   148         je      .replace_phnum
   149         cmpq    $9, %rcx                CC is AT_ENTRY?
   150         je      .replace_entry
   151         cmpq    $7, %rcx                CC is AT_BASE?
   152         je      .replace_base
   153         jmp     .one_auxv
   154 .replace_phdr:
   155         movq    40(%r8), %r9
   156         movq    %r9, -8(%rsp)           CC set at_phdr
   157         jmp     .one_auxv
   158 .replace_phent:
   159         movq    24(%r8), %r9
   160         movq    %r9, -8(%rsp)           CC set at_phent
   161         jmp     .one_auxv
   162 .replace_phnum:
   163         movq    32(%r8), %r9
   164         movq    %r9, -8(%rsp)           CC set at_phnum
   165         jmp     .one_auxv
   166 .replace_entry:
   167         movq    16(%r8), %r9
   168         movq    %r9, -8(%rsp)           CC set at_entry
   169         jmp     .one_auxv
   170 .replace_base:
   171         movq    48(%r8), %r9
   172         movq    %r9, -8(%rsp)           CC set at_base
   173         jmp     .one_auxv
   174 .cleanup:
   175         movq    $3, %rax                CC SYS_close
   176         cmpq    $-1, %r12               CC see if interpreter fd is set
   177         je      .cleanup_1
   178         movq    %r12, %rdi
   179         syscall
   180         movq    $3, %rax                CC SYS_close
   181 .cleanup_1:
   182         movq    %rbx, %rdi
   183         syscall
   184 .enter:
   185         pushq   $0
   186         popfq                           CC clear FP state
   187         movq    %r13, %rsp              CC restore SP
   188         xorq    %rdx, %rdx              CC clear rtld_fini
   189         jmpq    *8(%r8)                 CC entry
   190 
   191 error:
   192         .ascii  "_start: internal error."
   193 timespec:
   194         .quad   10
   195         .quad   10

/* [<][>][^][v][top][bottom][index][help] */