summaryrefslogtreecommitdiff
path: root/exec/loader-armeabi.s
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-04-30 21:37:19 +0800
committerPo Lu <luangruo@yahoo.com>2023-04-30 21:37:19 +0800
commit368f6f3942a1f8b9483763a6ac24b3b3021e92bf (patch)
tree284ff92e18076ed7a8be3d2775ee450922b3166d /exec/loader-armeabi.s
parent4289ed6cffdb5ea758a78037fe385fd7c4e23677 (diff)
downloademacs-368f6f3942a1f8b9483763a6ac24b3b3021e92bf.tar.gz
Add helper binary `exec1'
* .gitignore: New files. * Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile exists. * autogen.sh (do_git): Autoreconf in exec as well. * configure.ac: Configure libexec on Android. * exec/Makefile.in: * exec/README: * exec/config-mips.m4.in: * exec/config.guess: * exec/config.h.in: * exec/config.sub: * exec/configure: * exec/configure.ac: * exec/deps.mk: * exec/exec.c (MIN, struct exec_open_command) (struct exec_map_command, struct exec_jump_command) (write_open_command, write_load_command, process_interpreter_1) (process_interpreter, process_program_header, insert_args) (exec_0): * exec/exec.h (_EXEC_H_, struct elf_header_32) (struct program_header_32, struct dt_entry_32) (struct elf_header_64, struct program_header_64) (struct dt_entry_64, struct exec_tracee): * exec/exec1.c (main): * exec/install-sh (scriptversion): * 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): * exec/mipsel-user.h (_MIPSEL_USER_H_): * exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p) (fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode): * exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0): * exec/test.c (print_usage, main): * exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory) (user_alloca, user_copy, remove_tracee, handle_clone) (syscall_trap_p, handle_exec, process_system_call, tracing_execve) (after_fork, find_tracee, exec_waitpid, exec_init): New files. * java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and loader. ($(CROSS_EXEC_BINS) &): New target.
Diffstat (limited to 'exec/loader-armeabi.s')
-rw-r--r--exec/loader-armeabi.s192
1 files changed, 192 insertions, 0 deletions
diff --git a/exec/loader-armeabi.s b/exec/loader-armeabi.s
new file mode 100644
index 00000000000..182ff11ec7a
--- /dev/null
+++ b/exec/loader-armeabi.s
@@ -0,0 +1,192 @@
+@ Copyright (C) 2023 Free Software Foundation, Inc.
+@
+@ This file is part of GNU Emacs.
+@
+@ GNU Emacs is free software: you can redistribute it and/or modify
+@ it under the terms of the GNU General Public License as published
+@ by the Free Software Foundation, either version 3 of the License,
+@ or (at your option) any later version.
+@
+@ GNU Emacs is distributed in the hope that it will be useful, but
+@ WITHOUT ANY WARRANTY; without even the implied warranty of
+@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+@ General Public License for more details.
+@
+@ You should have received a copy of the GNU General Public License
+@ along with GNU Emacs. If not, see <https:@www.gnu.org/licenses/>.
+
+ .section .text
+ .global _start
+_start:
+ @mov r7, #162 @ SYS_nanosleep
+ @adr r0, timespec @ req
+ @mov r1, #0 @ rem
+ @swi #0 @ syscall
+ mov r8, sp @ r8 = sp
+ ldr r9, [r8], #8 @ r9 = original sp, r8 += 8
+ mov r14, #-1 @ r14 = secondary fd
+.next_action:
+ ldr r11, [r8] @ r11 = action number
+ and r12, r11, #-17 @ actual action number
+ cmp r12, #0 @ open file?
+ beq .open_file @ open file.
+ cmp r12, #3 @ jump?
+ beq .rest_of_exec @ jump to code.
+ cmp r12, #4 @ anonymous mmap?
+ beq .do_mmap_anon @ anonymous mmap.
+.do_mmap:
+ add r6, r8, #4 @ r6 = r8 + 4
+ ldm r6!, {r0, r5} @ vm_address, file_offset
+ ldm r6!, {r1, r2} @ protection, length
+ mov r3, r1 @ swap
+ lsr r5, #12 @ divide file offset by page size
+ mov r1, r2 @ swap
+ mov r2, r3 @ swap
+ ldm r6!, {r3, r12} @ flags, clear
+ tst r11, #16 @ primary fd?
+ mov r4, r10 @ primary fd
+ beq .do_mmap_1
+ mov r4, r14 @ secondary fd
+.do_mmap_1:
+ mov r7, #192 @ SYS_mmap2
+ swi #0 @ syscall
+ ldr r2, [r8, #4] @ vm_address
+ cmp r2, r0 @ rc == vm_address?
+ bne .perror
+ add r0, r1, r2 @ r0 = length + vm_address
+ sub r3, r0, r12 @ r3 = r0 - clear
+ mov r1, #0 @ r1 = 0
+.align:
+ cmp r0, r3 @ r0 == r3?
+ beq .continue @ continue
+ tst r3, #3 @ r3 & 3?
+ bne .fill32 @ fill aligned
+ strb r1, [r3], #1 @ fill byte
+ b .align @ align again
+.fill32:
+ sub r2, r0, r3 @ r2 = r0 - r3
+ cmp r2, #31 @ r2 >= 32?
+ ble .fillb @ start filling bytes
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ str r1, [r3], #4 @ *r3++ = 0
+ b .fill32
+.fillb:
+ cmp r0, r3 @ r0 == r3
+ beq .continue @ done
+ strb r1, [r3], #1 @ ((char *) r3)++ = 0
+ b .fillb
+.continue:
+ add r8, r8, #28 @ next action
+ b .next_action
+.do_mmap_anon:
+ add r6, r8, #4 @ r6 = r8 + 4
+ ldm r6!, {r0, r5} @ vm_address, file_offset
+ ldm r6!, {r1, r2} @ protection, length
+ mov r3, r1 @ swap
+ lsr r5, #12 @ divide file offset by page size
+ mov r1, r2 @ swap
+ mov r2, r3 @ swap
+ ldm r6!, {r3, r12} @ flags, clear
+ mov r4, #-1 @ fd
+ b .do_mmap_1
+.open_file:
+ mov r7, #5 @ SYS_open
+ add r0, r8, #4 @ file name
+ mov r1, #0 @ O_RDONLY
+ mov r2, #0 @ mode
+ swi #0 @ syscall
+ cmp r0, #-1 @ r0 <= -1?
+ ble .perror
+ add r8, r8, #4 @ r8 = start of string
+.nextc:
+ ldrb r1, [r8], #1 @ b = *r0++
+ cmp r1, #0 @ b?
+ bne .nextc @ next character
+ add r8, r8, #3 @ round up r8
+ and r8, r8, #-4 @ mask for round, set r8
+ tst r11, #16 @ primary fd?
+ bne .secondary @ secondary fd
+ mov r10, r0 @ primary fd
+ b .next_action @ next action
+.secondary:
+ mov r14, r0 @ secondary fd
+ b .next_action @ next action
+.perror:
+ mov r7, #1 @ SYS_exit
+ mvn r0, r0 @ r0 = ~r0
+ add r0, r0, #1 @ r0 += 1
+ swi #0
+.rest_of_exec:
+ mov r7, r9 @ r7 = original SP
+ ldr r6, [r7] @ argc
+ add r6, r6, #2 @ argc + 2
+ lsl r6, r6, #2 @ argc *= 4
+ add r7, r7, r6 @ now past argv
+.skipenv:
+ ldr r6, [r7], #4 @ r6 = *r7++
+ cmp r6, #0 @ r6?
+ bne .skipenv @ r6?
+.one_auxv:
+ ldr r6, [r7], #8 @ r6 = *r7, r7 += 2
+ cmp r6, #0 @ !r6?
+ beq .cleanup @ r6?
+ cmp r6, #3 @ is AT_PHDR?
+ beq .replace_phdr @ replace
+ cmp r6, #4 @ is AT_PHENT?
+ beq .replace_phent @ replace
+ cmp r6, #5 @ is AT_PHNUM?
+ beq .replace_phnum @ replace
+ cmp r6, #9 @ is AT_ENTRY?
+ beq .replace_entry @ replace
+ cmp r6, #7 @ is AT_BASE?
+ beq .replace_base @ replace
+ b .one_auxv @ next auxv
+.replace_phdr:
+ ldr r6, [r8, #20] @ at_phdr
+ str r6, [r7, #-4] @ store value
+ b .one_auxv
+.replace_phent:
+ ldr r6, [r8, #12] @ at_phent
+ str r6, [r7, #-4] @ store value
+ b .one_auxv
+.replace_phnum:
+ ldr r6, [r8, #16] @ at_phnum
+ str r6, [r7, #-4] @ store value
+ b .one_auxv
+.replace_entry:
+ ldr r6, [r8, #8] @ at_entry
+ str r6, [r7, #-4] @ store value
+ b .one_auxv
+.replace_base:
+ ldr r6, [r8, #24] @ at_base
+ str r6, [r7, #-4] @ store value
+ b .one_auxv
+.cleanup:
+ cmp r14, #-1 @ secondary fd set?
+ bne .cleanup1 @ not set
+ mov r7, #6 @ SYS_close
+ mov r0, r14 @ secondary fd
+ swi #0 @ syscall
+.cleanup1:
+ mov r7, #6 @ SYS_close
+ mov r0, r10 @ primary fd
+ swi #0 @ syscall
+.enter:
+ mov sp, r9 @ restore original SP
+ mov r0, #0 @ clear rtld_fini
+ ldr r1, [r8, #4] @ branch to code
+ bx r1
+
+timespec:
+ .long 10
+ .long 10
+
+@ Local Variables:
+@ asm-comment-char: 64
+@ End: