feat(rtl): migrate blaise_start .s to inline asm
This commit is contained in:
parent
7781242696
commit
d840f40e89
|
|
@ -41,12 +41,12 @@ BLAISE = $(COMPILER_BIN)/blaise
|
|||
BLAISE_FLAGS = --no-incremental --assembler internal
|
||||
|
||||
# Assembly sources — platform-specific, no C compiler needed.
|
||||
# (blaise_atomic, blaise_setjmp migrated to inline-asm Pascal units.)
|
||||
ASM_OBJS = $(OBJ_DIR)/blaise_start_x86_64.o \
|
||||
$(OBJ_DIR)/blaise_utf8_x86_64.o
|
||||
# (blaise_atomic, blaise_setjmp, blaise_start migrated to inline-asm units.)
|
||||
ASM_OBJS = $(OBJ_DIR)/blaise_utf8_x86_64.o
|
||||
|
||||
# Pascal RTL units compiled via the Blaise compiler.
|
||||
PAS_OBJS = $(OBJ_DIR)/blaise_atomic.o \
|
||||
PAS_OBJS = $(OBJ_DIR)/blaise_start.o \
|
||||
$(OBJ_DIR)/blaise_atomic.o \
|
||||
$(OBJ_DIR)/blaise_setjmp.o \
|
||||
$(OBJ_DIR)/blaise_mem.o \
|
||||
$(OBJ_DIR)/blaise_str.o \
|
||||
|
|
@ -74,6 +74,10 @@ $(OBJ_DIR)/%.o: $(ASM_DIR)/%.s
|
|||
$(CC) -c -o $@ $<
|
||||
|
||||
# --- Pascal unit rules (unit-as-top-level) ---
|
||||
$(OBJ_DIR)/blaise_start.o: $(PAS_SRC_DIR)/blaise_start.pas
|
||||
@mkdir -p $(OBJ_DIR)
|
||||
$(BLAISE) $(BLAISE_FLAGS) --source $< --unit-path $(PAS_SRC_DIR) --output $@
|
||||
|
||||
$(OBJ_DIR)/blaise_atomic.o: $(PAS_SRC_DIR)/blaise_atomic.pas
|
||||
@mkdir -p $(OBJ_DIR)
|
||||
$(BLAISE) $(BLAISE_FLAGS) --source $< --unit-path $(PAS_SRC_DIR) --output $@
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
#
|
||||
# Blaise — An Object Pascal Compiler
|
||||
# Copyright (c) 2026 Graeme Geldenhuys
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH Swift-exception
|
||||
# Licensed under the Apache License v2.0 with Runtime Library Exception.
|
||||
# See LICENSE file in the project root for full license terms.
|
||||
#
|
||||
# Program entry point (x86_64, System V ABI, glibc-compatible).
|
||||
#
|
||||
# This replaces the system Scrt1.o so the internal linker needs no
|
||||
# gcc-provided startup object and no versioned gcc directory (issue #142).
|
||||
# The runtime ships its own _start; the linker (TLinker.Link '_start') uses
|
||||
# this symbol as the ELF entry point.
|
||||
#
|
||||
# On entry the kernel hands us the initial process stack:
|
||||
# (%rsp) argc
|
||||
# 8(%rsp) argv[0]
|
||||
# ... argv[argc] = NULL, then envp, then the auxiliary vector
|
||||
# and %rdx holds the dynamic linker's finaliser (rtld_fini) for PIE images.
|
||||
#
|
||||
# We marshal these into the arguments __libc_start_main expects:
|
||||
# __libc_start_main(main, argc, argv, init, fini, rtld_fini, stack_end)
|
||||
# %rdi = main (the program's C-style entry)
|
||||
# %rsi = argc
|
||||
# %rdx = argv
|
||||
# %rcx = init = NULL (unit init runs from main, not .init_array)
|
||||
# %r8 = fini = NULL
|
||||
# %r9 = rtld_fini
|
||||
# stack_end pushed on the stack
|
||||
# glibc runs the init array (if any), calls main(argc, argv, envp), then
|
||||
# exit(main's return value). This mirrors modern glibc's own Scrt1.o.
|
||||
|
||||
.text
|
||||
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
endbr64
|
||||
xor %ebp, %ebp # outermost frame marker (ABI)
|
||||
mov %rdx, %r9 # rtld_fini -> arg 7
|
||||
pop %rsi # argc -> arg 2
|
||||
mov %rsp, %rdx # argv -> arg 3 (now at stack top)
|
||||
and $0xfffffffffffffff0, %rsp # re-align stack to 16 bytes
|
||||
push %rax # padding (8 bytes) ...
|
||||
push %rsp # ... and stack_end, keeping alignment
|
||||
xor %r8d, %r8d # fini = NULL -> arg 5
|
||||
xor %ecx, %ecx # init = NULL -> arg 4
|
||||
lea main(%rip), %rdi # main -> arg 1
|
||||
call __libc_start_main@PLT # does not return
|
||||
hlt # trap if it ever does
|
||||
.size _start, .-_start
|
||||
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
52
runtime/src/main/pascal/blaise_start.pas
Normal file
52
runtime/src/main/pascal/blaise_start.pas
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
Blaise - An Object Pascal Compiler
|
||||
Copyright (c) 2026 Graeme Geldenhuys
|
||||
SPDX-License-Identifier: Apache-2.0 WITH Swift-exception
|
||||
Licensed under the Apache License v2.0 with Runtime Library Exception.
|
||||
See LICENSE file in the project root for full license terms.
|
||||
}
|
||||
|
||||
unit blaise_start;
|
||||
|
||||
// Program entry point (x86_64, System V ABI, glibc-compatible).
|
||||
//
|
||||
// Inline-assembler port of runtime/src/main/asm/blaise_start_x86_64.s — _start
|
||||
// is now an `asm … end` routine so the RTL needs no hand-written .s
|
||||
// (docs/inline-asm-design.adoc, §"Migration of the .s files").
|
||||
//
|
||||
// This replaces the system Scrt1.o so the internal linker needs no
|
||||
// gcc-provided startup object (issue #142). The linker uses '_start' as the
|
||||
// ELF entry point; an unmangled unit-level routine named _start emits exactly
|
||||
// that symbol.
|
||||
//
|
||||
// On entry the kernel hands us the initial process stack:
|
||||
// (%rsp) argc 8(%rsp) argv[0] ... then NULL, envp, auxv
|
||||
// and %rdx holds rtld_fini for PIE images. We marshal these into the args
|
||||
// __libc_start_main(main, argc, argv, init=NULL, fini=NULL, rtld_fini,
|
||||
// stack_end) expects; glibc runs the init array, calls main(argc, argv, envp),
|
||||
// then exit(main's return). nostackframe: the body owns the whole frame.
|
||||
|
||||
interface
|
||||
|
||||
procedure _start;
|
||||
|
||||
implementation
|
||||
|
||||
procedure _start; assembler; nostackframe;
|
||||
asm
|
||||
endbr64
|
||||
xor %ebp, %ebp
|
||||
mov %rdx, %r9
|
||||
pop %rsi
|
||||
mov %rsp, %rdx
|
||||
and $0xfffffffffffffff0, %rsp
|
||||
push %rax
|
||||
push %rsp
|
||||
xor %r8d, %r8d
|
||||
xor %ecx, %ecx
|
||||
lea main(%rip), %rdi
|
||||
call __libc_start_main@PLT
|
||||
hlt
|
||||
end;
|
||||
|
||||
end.
|
||||
Loading…
Reference in a new issue