define(`CC', ` dnl') CC Copyright (C) 2023-2024 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 . .section .text .global _start _start: dnl movl $162, %eax CC SYS_nanosleep dnl leal timespec, %ebx dnl xorl %ecx, %ecx dnl int $0x80 leal 8(%esp), %ebp CC ebp = start of load area subl $8, %esp CC (%esp) = primary fd, 4(%esp) = secondary fd movl $-1, 4(%esp) .next_action: movl (%ebp), %edx CC edx = action number andl $-17, %edx cmpl $0, %edx CC open file? je .open_file cmpl $3, %edx CC jump? je .rest_of_exec cmpl $4, %edx CC anonymous mmap? je .do_mmap_anon .do_mmap: subl $24, %esp movl $90, %eax CC SYS_old_mmap movl %esp, %ebx movl 4(%ebp), %ecx CC address movl %ecx, (%esp) movl 16(%ebp), %ecx CC length movl %ecx, 4(%esp) movl 12(%ebp), %ecx CC protection movl %ecx, 8(%esp) movl 20(%ebp), %ecx CC flags movl %ecx, 12(%esp) testl $16, (%ebp) CC primary? movl 28(%esp), %ecx cmovzl 24(%esp), %ecx movl %ecx, 16(%esp) CC fd movl 8(%ebp), %ecx CC offset movl %ecx, 20(%esp) .do_mmap_1: int $0x80 addl $24, %esp CC restore esp cmpl $-1, %eax CC mmap failed? je .perror movl 24(%ebp), %ecx CC clear testl %ecx, %ecx jz .continue movl 4(%ebp), %esi CC start of mapping addl 16(%ebp), %esi CC end of mapping subl %ecx, %esi CC start of clear area .again: testl %ecx, %ecx jz .continue subl $1, %ecx movb $0, (%esi, %ecx, 1) jmp .again .continue: leal 28(%ebp), %ebp jmp .next_action .do_mmap_anon: subl $24, %esp movl $90, %eax CC SYS_old_mmap movl %esp, %ebx movl 4(%ebp), %ecx CC address movl %ecx, (%esp) movl 16(%ebp), %ecx CC length movl %ecx, 4(%esp) movl 12(%ebp), %ecx CC protection movl %ecx, 8(%esp) movl 20(%ebp), %ecx CC flags movl %ecx, 12(%esp) movl $-1, 16(%esp) CC fd movl 8(%ebp), %ecx CC offset movl %ecx, 20(%esp) jmp .do_mmap_1 .open_file: movl $5, %eax CC SYS_open leal 4(%ebp), %ebx CC ebx = %esp + 8 pushl %ebx xorl %ecx, %ecx CC flags = O_RDONLY xorl %edx, %edx CC mode = 0 int $0x80 cmpl $-1, %eax CC open failed? jle .perror movl %ebp, %esi CC (esi) = original action number popl %ebp CC ebp = start of string movl %ebp, %ecx CC char past separator decl %ebp .nextc: incl %ebp movb (%ebp), %dl CC dl = *ebp cmpb $47, %dl CC dl == '\?'? jne .nextc1 leal 1(%ebp), %ecx CC ecx = char past separator .nextc1: cmpb $0, %dl CC dl == 0? jne .nextc addl $4, %ebp CC adjust past ebp prior to rounding andl $-4, %ebp CC round ebp up to the next long testl $16, (%esi) CC original action number & 16? jz .primary movl %eax, 4(%esp) CC secondary fd = eax jmp .next_action .primary: pushl %ebp xorl %esi, %esi CC arg3 movl %eax, 4(%esp) CC primary fd = eax xorl %edx, %edx CC arg2 movl $15, %ebx CC PR_SET_NAME, arg1 = ecx xorl %edi, %edi CC arg4 movl $172, %eax CC SYS_prctl xorl %ebp, %ebp CC arg5 int $0x80 CC syscall popl %ebp jmp .next_action .perror: movl %eax, %ebx negl %ebx movl $1, %eax int $0x80 .rest_of_exec: movl 8(%esp), %ecx CC ecx = original stack pointer movl (%ecx), %esi CC esi = argc leal 8(%ecx, %esi, 4), %ecx CC ecx = start of environ .skip_environ: movl (%ecx), %esi CC envp[N] addl $4, %ecx testl %esi, %esi CC envp[n] ? jnz .skip_environ CC otherwise, esi is now at the start of auxv .one_auxv: movl (%ecx), %esi CC auxv type leal 8(%ecx), %ecx CC skip to next auxv testl %esi, %esi CC is 0? jz .cleanup cmpl $3, %esi CC is AT_PHDR je .replace_phdr cmpl $4, %esi CC is AT_PHENT? je .replace_phent cmpl $5, %esi CC is AT_PHNUM? je .replace_phnum cmpl $9, %esi CC is AT_ENTRY? je .replace_entry cmpl $7, %esi CC is AT_BASE je .replace_base jmp .one_auxv .replace_phdr: movl 20(%ebp), %esi movl %esi, -4(%ecx) jmp .one_auxv .replace_phent: movl 12(%ebp), %esi movl %esi, -4(%ecx) jmp .one_auxv .replace_phnum: movl 16(%ebp), %esi movl %esi, -4(%ecx) jmp .one_auxv .replace_entry: movl 8(%ebp), %esi movl %esi, -4(%ecx) jmp .one_auxv .replace_base: movl 24(%ebp), %esi movl %esi, -4(%ecx) jmp .one_auxv .cleanup: movl $6, %eax CC SYS_close cmpl $-1, 4(%esp) CC see if interpreter fd is set je .cleanup_1 movl 4(%esp), %ebx int $0x80 movl $6, %eax CC SYS_close .cleanup_1: movl (%esp), %ebx int $0x80 .enter: pushl $0 popfl CC restore floating point state movl 8(%esp), %esp CC restore initial stack pointer xorl %edx, %edx CC clear rtld_fini jmpl *4(%ebp) CC entry timespec: .long 10 .long 10