1 @ Copyright (C) 2023 Free Software Foundation, Inc. 2 @ 3 @ This file is part of GNU Emacs. 4 @ 5 @ GNU Emacs is free software: you can redistribute it and/or modify 6 @ it under the terms of the GNU General Public License as published 7 @ by the Free Software Foundation, either version 3 of the License, 8 @ or (at your option) any later version. 9 @ 10 @ GNU Emacs is distributed in the hope that it will be useful, but 11 @ WITHOUT ANY WARRANTY; without even the implied warranty of 12 @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 @ General Public License for more details. 14 @ 15 @ You should have received a copy of the GNU General Public License 16 @ along with GNU Emacs. If not, see <https:@www.gnu.org/licenses/>. 17 18 .section .text 19 .global _start 20 _start: 21 @mov r7, #162 @ SYS_nanosleep 22 @adr r0, timespec @ req 23 @mov r1, #0 @ rem 24 @swi #0 @ syscall 25 mov r8, sp @ r8 = sp 26 ldr r9, [r8], #8 @ r9 = original sp, r8 += 8 27 mov r14, #-1 @ r14 = secondary fd 28 .next_action: 29 ldr r11, [r8] @ r11 = action number 30 and r12, r11, #-17 @ actual action number 31 cmp r12, #0 @ open file? 32 beq .open_file @ open file. 33 cmp r12, #3 @ jump? 34 beq .rest_of_exec @ jump to code. 35 cmp r12, #4 @ anonymous mmap? 36 beq .do_mmap_anon @ anonymous mmap. 37 .do_mmap: 38 add r6, r8, #4 @ r6 = r8 + 4 39 ldm r6!, {r0, r5} @ vm_address, file_offset 40 ldm r6!, {r1, r2} @ protection, length 41 mov r3, r1 @ swap 42 lsr r5, #12 @ divide file offset by page size 43 mov r1, r2 @ swap 44 mov r2, r3 @ swap 45 ldm r6!, {r3, r12} @ flags, clear 46 tst r11, #16 @ primary fd? 47 mov r4, r10 @ primary fd 48 beq .do_mmap_1 49 mov r4, r14 @ secondary fd 50 .do_mmap_1: 51 mov r7, #192 @ SYS_mmap2 52 swi #0 @ syscall 53 ldr r2, [r8, #4] @ vm_address 54 cmp r2, r0 @ rc == vm_address? 55 bne .perror 56 add r0, r1, r2 @ r0 = length + vm_address 57 sub r3, r0, r12 @ r3 = r0 - clear 58 mov r1, #0 @ r1 = 0 59 .align: 60 cmp r0, r3 @ r0 == r3? 61 beq .continue @ continue 62 tst r3, #3 @ r3 & 3? 63 bne .fill32 @ fill aligned 64 strb r1, [r3], #1 @ fill byte 65 b .align @ align again 66 .fill32: 67 sub r2, r0, r3 @ r2 = r0 - r3 68 cmp r2, #31 @ r2 >= 32? 69 ble .fillb @ start filling bytes 70 str r1, [r3], #4 @ *r3++ = 0 71 str r1, [r3], #4 @ *r3++ = 0 72 str r1, [r3], #4 @ *r3++ = 0 73 str r1, [r3], #4 @ *r3++ = 0 74 str r1, [r3], #4 @ *r3++ = 0 75 str r1, [r3], #4 @ *r3++ = 0 76 str r1, [r3], #4 @ *r3++ = 0 77 str r1, [r3], #4 @ *r3++ = 0 78 b .fill32 79 .fillb: 80 cmp r0, r3 @ r0 == r3 81 beq .continue @ done 82 strb r1, [r3], #1 @ ((char *) r3)++ = 0 83 b .fillb 84 .continue: 85 add r8, r8, #28 @ next action 86 b .next_action 87 .do_mmap_anon: 88 add r6, r8, #4 @ r6 = r8 + 4 89 ldm r6!, {r0, r5} @ vm_address, file_offset 90 ldm r6!, {r1, r2} @ protection, length 91 mov r3, r1 @ swap 92 lsr r5, #12 @ divide file offset by page size 93 mov r1, r2 @ swap 94 mov r2, r3 @ swap 95 ldm r6!, {r3, r12} @ flags, clear 96 mov r4, #-1 @ fd 97 b .do_mmap_1 98 .open_file: 99 mov r7, #5 @ SYS_open 100 add r0, r8, #4 @ file name 101 mov r1, #0 @ O_RDONLY 102 mov r2, #0 @ mode 103 swi #0 @ syscall 104 cmp r0, #-1 @ r0 <= -1? 105 ble .perror 106 add r8, r8, #4 @ r8 = start of string 107 mov r1, r8 @ r1 = r8 108 .nextc: 109 ldrb r2, [r8], #1 @ b = *r0++ 110 cmp r2, #47 @ dir separator? 111 bne .nextc1 @ not dir separator 112 mov r1, r8 @ r1 = char past separator 113 .nextc1: 114 cmp r2, #0 @ b? 115 bne .nextc @ next character 116 add r8, r8, #3 @ round up r8 117 and r8, r8, #-4 @ mask for round, set r8 118 tst r11, #16 @ primary fd? 119 bne .secondary @ secondary fd 120 mov r10, r0 @ primary fd 121 mov r7, #172 @ SYS_prctl 122 mov r0, #15 @ PR_SET_NAME, r1 = name 123 mov r2, #0 @ arg2 124 mov r3, #0 @ arg3 125 mov r4, #0 @ arg4 126 mov r5, #0 @ arg5 127 swi #0 @ syscall 128 b .next_action @ next action 129 .secondary: 130 mov r14, r0 @ secondary fd 131 b .next_action @ next action 132 .perror: 133 mov r7, #1 @ SYS_exit 134 mvn r0, r0 @ r0 = ~r0 135 add r0, r0, #1 @ r0 += 1 136 swi #0 137 .rest_of_exec: 138 mov r7, r9 @ r7 = original SP 139 ldr r6, [r7] @ argc 140 add r6, r6, #2 @ argc + 2 141 lsl r6, r6, #2 @ argc *= 4 142 add r7, r7, r6 @ now past argv 143 .skipenv: 144 ldr r6, [r7], #4 @ r6 = *r7++ 145 cmp r6, #0 @ r6? 146 bne .skipenv @ r6? 147 .one_auxv: 148 ldr r6, [r7], #8 @ r6 = *r7, r7 += 2 149 cmp r6, #0 @ !r6? 150 beq .cleanup @ r6? 151 cmp r6, #3 @ is AT_PHDR? 152 beq .replace_phdr @ replace 153 cmp r6, #4 @ is AT_PHENT? 154 beq .replace_phent @ replace 155 cmp r6, #5 @ is AT_PHNUM? 156 beq .replace_phnum @ replace 157 cmp r6, #9 @ is AT_ENTRY? 158 beq .replace_entry @ replace 159 cmp r6, #7 @ is AT_BASE? 160 beq .replace_base @ replace 161 b .one_auxv @ next auxv 162 .replace_phdr: 163 ldr r6, [r8, #20] @ at_phdr 164 str r6, [r7, #-4] @ store value 165 b .one_auxv 166 .replace_phent: 167 ldr r6, [r8, #12] @ at_phent 168 str r6, [r7, #-4] @ store value 169 b .one_auxv 170 .replace_phnum: 171 ldr r6, [r8, #16] @ at_phnum 172 str r6, [r7, #-4] @ store value 173 b .one_auxv 174 .replace_entry: 175 ldr r6, [r8, #8] @ at_entry 176 str r6, [r7, #-4] @ store value 177 b .one_auxv 178 .replace_base: 179 ldr r6, [r8, #24] @ at_base 180 str r6, [r7, #-4] @ store value 181 b .one_auxv 182 .cleanup: 183 cmp r14, #-1 @ secondary fd set? 184 bne .cleanup1 @ not set 185 mov r7, #6 @ SYS_close 186 mov r0, r14 @ secondary fd 187 swi #0 @ syscall 188 .cleanup1: 189 mov r7, #6 @ SYS_close 190 mov r0, r10 @ primary fd 191 swi #0 @ syscall 192 .enter: 193 mov sp, r9 @ restore original SP 194 mov r0, #0 @ clear rtld_fini 195 ldr r1, [r8, #4] @ branch to code 196 bx r1 197 198 timespec: 199 .long 10 200 .long 10 201 202 @ Local Variables: 203 @ asm-comment-char: 64 204 @ End: