mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-25 07:28:20 +00:00
f4512cca0b
* exec/Makefile.in (.SUFFIXES): Include ., then `srcdir'. * exec/loader-aarch64.s (_start): * exec/loader-armeabi.s (_start): * exec/loader-mips64el.s (__start): * exec/loader-mipsel.s (__start): * exec/loader-x86.s (_start): * exec/loader-x86_64.s (_start): Get basename of opened exec file and make it the command name. Fix envp skipping on x86 and various leaks.
196 lines
4.9 KiB
ArmAsm
196 lines
4.9 KiB
ArmAsm
define(`CC', `
|
|
dnl')
|
|
|
|
CC Copyright (C) 2023 Free Software Foundation, Inc.
|
|
CC
|
|
CC This file is part of GNU Emacs.
|
|
CC
|
|
CC GNU Emacs is free software: you can redistribute it and/or modify
|
|
CC it under the terms of the GNU General Public License as published
|
|
CC by the Free Software Foundation, either version 3 of the License,
|
|
CC or (at your option) any later version.
|
|
CC
|
|
CC GNU Emacs is distributed in the hope that it will be useful, but
|
|
CC WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
CC MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
CC General Public License for more details.
|
|
CC
|
|
CC You should have received a copy of the GNU General Public License
|
|
CC along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
.section .text
|
|
.global _start
|
|
_start:
|
|
dnl movq $35, %rax CC SYS_nanosleep
|
|
dnl leaq timespec(%rip), %rdi
|
|
dnl xorq %rsi, %rsi
|
|
dnl syscall
|
|
popq %r13 CC original SP
|
|
popq %r15 CC size of load area.
|
|
movq $-1, %r12 CC r12 is the interpreter fd
|
|
.next_action:
|
|
movq (%rsp), %r14 CC action number
|
|
movq %r14, %r15 CC original action number
|
|
andq $-17, %r14
|
|
cmpq $0, %r14 CC open file?
|
|
je .open_file
|
|
cmpq $3, %r14 CC jump?
|
|
je .rest_of_exec
|
|
cmpq $4, %r14 CC anonymous mmap?
|
|
je .do_mmap_anon
|
|
.do_mmap:
|
|
movq $9, %rax CC SYS_mmap
|
|
movq 8(%rsp), %rdi CC address
|
|
movq 16(%rsp), %r9 CC offset
|
|
movq 24(%rsp), %rdx CC protection
|
|
movq 32(%rsp), %rsi CC length
|
|
movq 40(%rsp), %r10 CC flags
|
|
CC set r8 to the primary fd unless r15 & 16
|
|
testq $16, %r15
|
|
movq %r12, %r8
|
|
cmovzq %rbx, %r8
|
|
.do_mmap_1:
|
|
syscall
|
|
cmpq $-1, %rax CC mmap failed
|
|
je .perror
|
|
movq 48(%rsp), %r9 CC clear
|
|
testq %r9, %r9
|
|
jz .continue
|
|
movq 8(%rsp), %r10 CC start of mapping
|
|
addq 32(%rsp), %r10 CC end of mapping
|
|
subq %r9, %r10 CC start of clear area
|
|
.again:
|
|
testq %r9, %r9
|
|
jz .continue
|
|
subq $1, %r9
|
|
movb $0, (%r10, %r9, 1)
|
|
jmp .again
|
|
.continue:
|
|
leaq 56(%rsp), %rsp
|
|
jmp .next_action
|
|
.do_mmap_anon:
|
|
movq $9, %rax CC SYS_mmap
|
|
movq 8(%rsp), %rdi CC address
|
|
movq 16(%rsp), %r9 CC offset
|
|
movq 24(%rsp), %rdx CC protection
|
|
movq 32(%rsp), %rsi CC length
|
|
movq 40(%rsp), %r10 CC flags
|
|
movq $-1, %r8 CC -1
|
|
jmp .do_mmap_1
|
|
.open_file:
|
|
movq $2, %rax CC SYS_open
|
|
leaq 8(%rsp), %rdi CC rdi = %rsp + 8
|
|
xorq %rsi, %rsi CC flags = O_RDONLY
|
|
xorq %rdx, %rdx CC mode = 0
|
|
syscall
|
|
cmpq $-1, %rax CC open failed
|
|
jle .perror
|
|
movq %rdi, %rsp CC rsp = start of string
|
|
subq $1, %rsp
|
|
movq %rsp, %r14 CC r14 = start of string
|
|
.nextc:
|
|
addq $1, %rsp
|
|
movb (%rsp), %dil CC rdi = *rsp
|
|
cmpb $47, %dil CC *rsp == '/'?
|
|
jne .nextc1
|
|
movq %rsp, %r14 CC r14 = rsp
|
|
addq $1, %r14 CC r14 = char past separator
|
|
.nextc1:
|
|
cmpb $0, %dil CC *rsp == 0?
|
|
jne .nextc
|
|
addq $8, %rsp CC adjust past rsp prior to rounding
|
|
andq $-8, %rsp CC round rsp up to the next quad
|
|
testq $16, %r15 CC r15 & 16?
|
|
jz .primary
|
|
movq %rax, %r12 CC otherwise, move fd to r12
|
|
jmp .next_action
|
|
.primary:
|
|
movq %rax, %rbx CC if not, move fd to rbx
|
|
movq $157, %rax CC SYS_prctl
|
|
movq $15, %rdi CC PR_SET_NAME
|
|
movq %r14, %rsi CC arg1
|
|
xorq %rdx, %rdx CC arg2
|
|
xorq %r10, %r10 CC arg3
|
|
xorq %r8, %r8 CC arg4
|
|
xorq %r9, %r9 CC arg5
|
|
syscall
|
|
jmp .next_action
|
|
.perror:
|
|
movq %rax, %r12 CC error code
|
|
negq %r12
|
|
movq $1, %rax CC SYS_write
|
|
movq $1, %rdi CC stdout
|
|
leaq error(%rip), %rsi CC buffer
|
|
movq $23, %rdx CC count
|
|
syscall
|
|
movq $60, %rax CC SYS_exit
|
|
movq %r12, %rdi CC code
|
|
syscall
|
|
.rest_of_exec: CC rsp now points to six quads:
|
|
movq %rsp, %r8 CC now, they are r8
|
|
movq %r13, %rsp CC restore SP
|
|
popq %r10 CC argc
|
|
leaq 8(%rsp,%r10,8), %rsp CC now at start of environ
|
|
.skip_environ:
|
|
popq %r10 CC envp[N]
|
|
testq %r10, %r10 CC envp[n]?
|
|
jnz .skip_environ CC otherwise, rsp is now at the start of auxv
|
|
.one_auxv:
|
|
popq %rcx CC auxv type
|
|
addq $8, %rsp CC skip value
|
|
testq %rcx, %rcx CC is 0?
|
|
jz .cleanup
|
|
cmpq $3, %rcx CC is AT_PHDR?
|
|
je .replace_phdr
|
|
cmpq $4, %rcx CC is AT_PHENT?
|
|
je .replace_phent
|
|
cmpq $5, %rcx CC is AT_PHNUM?
|
|
je .replace_phnum
|
|
cmpq $9, %rcx CC is AT_ENTRY?
|
|
je .replace_entry
|
|
cmpq $7, %rcx CC is AT_BASE?
|
|
je .replace_base
|
|
jmp .one_auxv
|
|
.replace_phdr:
|
|
movq 40(%r8), %r9
|
|
movq %r9, -8(%rsp) CC set at_phdr
|
|
jmp .one_auxv
|
|
.replace_phent:
|
|
movq 24(%r8), %r9
|
|
movq %r9, -8(%rsp) CC set at_phent
|
|
jmp .one_auxv
|
|
.replace_phnum:
|
|
movq 32(%r8), %r9
|
|
movq %r9, -8(%rsp) CC set at_phnum
|
|
jmp .one_auxv
|
|
.replace_entry:
|
|
movq 16(%r8), %r9
|
|
movq %r9, -8(%rsp) CC set at_entry
|
|
jmp .one_auxv
|
|
.replace_base:
|
|
movq 48(%r8), %r9
|
|
movq %r9, -8(%rsp) CC set at_base
|
|
jmp .one_auxv
|
|
.cleanup:
|
|
movq $3, %rax CC SYS_close
|
|
cmpq $-1, %r12 CC see if interpreter fd is set
|
|
je .cleanup_1
|
|
movq %r12, %rdi
|
|
syscall
|
|
movq $3, %rax CC SYS_close
|
|
.cleanup_1:
|
|
movq %rbx, %rdi
|
|
syscall
|
|
.enter:
|
|
pushq $0
|
|
popfq CC clear FP state
|
|
movq %r13, %rsp CC restore SP
|
|
xorq %rdx, %rdx CC clear rtld_fini
|
|
jmpq *8(%r8) CC entry
|
|
|
|
error:
|
|
.ascii "_start: internal error."
|
|
timespec:
|
|
.quad 10
|
|
.quad 10
|