[TOOLCHAIN] Making musl portable
This commit is contained in:
parent
a7d2b24a79
commit
8d1e693884
7
Makefile
7
Makefile
@ -8,8 +8,12 @@ endif
|
||||
SHELL := bash
|
||||
|
||||
CC=$(TARGET)-gcc
|
||||
AR=$(TARGET)-ar
|
||||
LD=$(TARGET)-ld
|
||||
FLAGS_TO_PASS:= \
|
||||
CC=$(CC)
|
||||
CC=$(CC) \
|
||||
AR=$(AR) \
|
||||
LD=$(LD)
|
||||
|
||||
all: kernel libc init
|
||||
|
||||
@ -24,6 +28,7 @@ libc:
|
||||
ifeq ($(shell make -sqC libc || echo 1), 1)
|
||||
@(. util/helpers.sh; print_info "Building c library")
|
||||
$(MAKE) -C libc install $(FLAGS_TO_PASS)
|
||||
$(MAKE) $(MAKECMDGOALS)
|
||||
endif
|
||||
|
||||
init:
|
||||
|
@ -11,6 +11,8 @@ CFLAGS ?= -Wall -Wextra -ggdb -O0
|
||||
|
||||
all: init
|
||||
|
||||
init: $(SYSROOT)/usr/lib/libc.a
|
||||
|
||||
$(installdir)/init: init
|
||||
mkdir -p $(dir $@)
|
||||
cp $< $@
|
||||
|
@ -4,7 +4,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
asm("syscall" :: "a" (0x3FF), "D" ("Hello, world!\n"));
|
||||
fork();
|
||||
for(;;);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <msr.h>
|
||||
#include <gdt.h>
|
||||
#include <registers.h>
|
||||
#include "../../libc/syscall_num.h"
|
||||
|
||||
extern void syscall_entry();
|
||||
|
||||
@ -52,7 +53,7 @@ void syscall_init()
|
||||
syscall_installed = 1;
|
||||
memset(syscall_handlers, 0, 1024*sizeof(syscall_handler_t));
|
||||
|
||||
SYSCALL_REGISTER(debug, 0x3FF);
|
||||
SYSCALL_REGISTER(debug, SYS_DEBUG);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,26 +3,41 @@ ifeq ($(MITTOS64),)
|
||||
endif
|
||||
|
||||
LIBDIR := $(SYSROOT)/usr/lib
|
||||
LIBC := $(LIBDIR)/libc.a
|
||||
|
||||
CRT := crt0
|
||||
CRT_OBJ := $(addprefix obj/, $(patsubst %,%.o,$(CRT)))
|
||||
SRC := $(filter-out $(CRT).%, $(wildcard *.[cS]))
|
||||
OBJ := $(addprefix obj/, $(patsubst %,%.o, $(basename $(SRC))))
|
||||
|
||||
libfile := mittos64.o
|
||||
LIB_OBJ := $(LIBC)($(libfile))
|
||||
|
||||
CFLAGS := -Wall -Wextra -ggdb -O0
|
||||
ASFLAGS := -ggdb
|
||||
|
||||
all: $(CRT_OBJ)
|
||||
all: $(CRT_OBJ) $(OBJ)
|
||||
|
||||
OBJ_DIRS := $(sort $(dir $(CRT_OBJ)))
|
||||
OBJ_DIRS := $(sort $(dir $(CRT_OBJ) $(OBJ)))
|
||||
$(CRT_OBJ): | $(OBJ_DIRS)
|
||||
$(OBJ_DIRS):
|
||||
mkdir -p $@
|
||||
|
||||
obj/%.o:%.c
|
||||
$(COMPILE.c) $^ -o $@
|
||||
obj/%.o:%.S
|
||||
$(COMPILE.S) $^ -o $@
|
||||
obj/$(libfile):$(OBJ)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
$(LIBC)(%):obj/%
|
||||
$(AR) -d $@ $<
|
||||
$(AR) -rs $@ $<
|
||||
|
||||
$(LIBDIR)/%: obj/%
|
||||
cp $< $@
|
||||
|
||||
install: $(patsubst %,$(LIBDIR)/%.o,$(CRT))
|
||||
install: $(patsubst %,$(LIBDIR)/%.o,$(CRT)) $(LIB_OBJ)
|
||||
|
||||
clean:
|
||||
rm -rf obj/
|
||||
|
3
libc/syscall_num.h
Normal file
3
libc/syscall_num.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define SYS_DEBUG 0x3FF
|
53
libc/syscalls.c
Normal file
53
libc/syscalls.c
Normal file
@ -0,0 +1,53 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "syscalls.h"
|
||||
|
||||
long kernel_syscall(int num, ...)
|
||||
{
|
||||
va_list varg;
|
||||
va_start(varg, num);
|
||||
long a1 = va_arg(varg, long);
|
||||
long a2 = va_arg(varg, long);
|
||||
long a3 = va_arg(varg, long);
|
||||
register long r10 __asm__("r10") = va_arg(varg, long);
|
||||
register long r8 __asm__("r8") = va_arg(varg, long);
|
||||
register long r9 __asm__("r9") = va_arg(varg, long);
|
||||
va_end(varg);
|
||||
|
||||
long ret;
|
||||
__asm__ __volatile__("syscall" : "=a" (ret) : "a" (num), "D" (a1), "S" (a2), "d" (a3), "r" (r10), "r" (r8), "r" (r9) : "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
char debug_buffer[256];
|
||||
void kernel_debug(char *fmt, ...)
|
||||
{
|
||||
va_list varg;
|
||||
va_start(varg, fmt);
|
||||
vsprintf(debug_buffer, fmt, varg);
|
||||
va_end(varg);
|
||||
kernel_syscall(SYS_DEBUG, (long)debug_buffer);
|
||||
}
|
||||
|
||||
long __syscall_common(long num, ...)
|
||||
{
|
||||
va_list varg;
|
||||
va_start(varg, num);
|
||||
long a1 = va_arg(varg, long);
|
||||
long a2 = va_arg(varg, long);
|
||||
long a3 = va_arg(varg, long);
|
||||
long a4 = va_arg(varg, long);
|
||||
long a5 = va_arg(varg, long);
|
||||
long a6 = va_arg(varg, long);
|
||||
va_end(varg);
|
||||
|
||||
kernel_debug("==> SYSCALL %ld (%lx, %lx, %lx, %lx, %lx, %lx)\n", num, a1, a2, a3, a4, a5, a6);
|
||||
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pthread *__pthread_self()
|
||||
{
|
||||
return 0;
|
||||
}
|
36
libc/syscalls.h
Normal file
36
libc/syscalls.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "syscall_num.h"
|
||||
|
||||
#define SYSCALL_DEF(name) \
|
||||
long __syscall_##name(long num, long _a1, long _a2, long _a3, long _a4, long _a5, long _a6)
|
||||
|
||||
#define _SYSCALL_INIT6(t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,t6,n6) \
|
||||
(void)num; \
|
||||
t1 n1 = (t1)_a1; \
|
||||
(void)n1; \
|
||||
t2 n2 = (t2)_a2; \
|
||||
(void)n2; \
|
||||
t3 n3 = (t3)_a3; \
|
||||
(void)n3; \
|
||||
t4 n4 = (t4)_a4; \
|
||||
(void)n4; \
|
||||
t5 n5 = (t5)_a5; \
|
||||
(void)n5; \
|
||||
t6 n6 = (t6)_a6; \
|
||||
(void)n6;
|
||||
#define _SYSCALL_INIT5(t1,n1,t2,n2,t3,n3,t4,n4,t5,n5) _SYSCALL_INIT6(t1,n1,t2,n2,t3,n3,t4,n4,t5,n5,long,__a6)
|
||||
#define _SYSCALL_INIT4(t1,n1,t2,n2,t3,n3,t4,n4) _SYSCALL_INIT6(t1,n1,t2,n2,t3,n3,t4,n4,long,__a5,long,__a6)
|
||||
#define _SYSCALL_INIT3(t1,n1,t2,n2,t3,n3) _SYSCALL_INIT6(t1,n1,t2,n2,t3,n3,long,__a4,long,__a5,long,__a6)
|
||||
#define _SYSCALL_INIT2(t1,n1,t2,n2) _SYSCALL_INIT6(t1,n1,t2,n2,long,__a3,long,__a4,long,__a5,long,__a6)
|
||||
#define _SYSCALL_INIT1(t1,n1) _SYSCALL_INIT6(t1,n1,long,__a2,long,__a3,long,__a4,long,__a5,long,__a6)
|
||||
#define _SYSCALL_INIT0() _SYSCALL_INIT6(long,__a1,long,__a2,long,__a3,long,__a4,long,__a5,long,__a6)
|
||||
|
||||
#define __SYSCALL_NARGS(a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,n,...) n
|
||||
#define _SYSCALL_NARGS(...) __SYSCALL_NARGS(__VA_ARGS__,6,6,5,5,4,4,3,3,2,2,1,1,0,0)
|
||||
#define __SYSCALL_CONCAT(a,b) a##b
|
||||
#define _SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT(a,b)
|
||||
#define _SYSCALL_INIT(a,...) _SYSCALL_CONCAT(a, _SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define SYSCALL_INIT(...) _SYSCALL_INIT(_SYSCALL_INIT,__VA_ARGS__)
|
||||
|
||||
long kernel_syscall(int num, ...);
|
||||
void kernel_debug(char *fmt, ...);
|
@ -18,10 +18,12 @@ musl_config="--target=${TARGET} \
|
||||
--disable-shared \
|
||||
--enable-debug \
|
||||
CFLAGS=-O0"
|
||||
musl_patchcmd="${BUILDROOT}/util/patch_musl.sh ${STASH}/musl/"
|
||||
|
||||
musl_headers_checkfile=${SYSROOT}/usr/include/complex.h
|
||||
musl_headers_filename=${musl_filename}
|
||||
musl_headers_url=${musl_url}
|
||||
musl_headers_patchcmd=${musl_patchcmd}
|
||||
function musl_headers_install() {
|
||||
local package=musl
|
||||
|
||||
|
84
util/patch_musl.sh
Executable file
84
util/patch_musl.sh
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
function main()
|
||||
{
|
||||
readonly musl_dir=$1
|
||||
|
||||
syscall_arch=${musl_dir}/arch/x86_64/syscall_arch.h
|
||||
|
||||
syscall_in=${musl_dir}/arch/x86_64/bits/syscall.h.in
|
||||
|
||||
syscall_dir=${musl_dir}/src/internal/x86_64/
|
||||
|
||||
rm ${musl_dir}/src/thread/x86_64/__set_thread_area.s
|
||||
rm ${syscall_dir}/syscall.s
|
||||
|
||||
cat >> ${syscall_arch} << EOF
|
||||
#define SYSCALL_NO_INLINE
|
||||
EOF
|
||||
|
||||
cat > ${syscall_dir}/syscall_1.c << EOF
|
||||
#include <stdarg.h>
|
||||
|
||||
#pragma weak __syscall_common
|
||||
long __syscall_common(long num, ...)
|
||||
{
|
||||
for(;;);
|
||||
}
|
||||
long __syscall_default(long num, ...)
|
||||
{ for(;;); }
|
||||
|
||||
typedef long (*syscall_fn)(long, ...);
|
||||
|
||||
EOF
|
||||
|
||||
sed -n -E 's/.*__NR_([^[:space:]]+).*/long __attribute__\(\(weak\)\) __syscall_\1\(long, ...\);/p' < ${syscall_in} >> ${syscall_dir}/syscall_1.c
|
||||
|
||||
cat >> ${syscall_dir}/syscall_1.c << EOF
|
||||
|
||||
syscall_fn __syscall_fns[] = {
|
||||
EOF
|
||||
|
||||
sed -n -E 's/.*__NR_([^[:space:]]+)[[:space:]]+([0-9]+).*/\[\2\] = __syscall_\1,/p' < ${syscall_in} >> ${syscall_dir}/syscall_1.c
|
||||
|
||||
cat >> ${syscall_dir}/syscall_1.c << EOF
|
||||
|
||||
};
|
||||
|
||||
EOF
|
||||
cat >${syscall_dir}/syscall_2.c << EOF
|
||||
#include <stdarg.h>
|
||||
typedef long (*syscall_fn)(long, ...);
|
||||
extern long __syscall_common(long, ...);
|
||||
extern syscall_fn __syscall_fns[];
|
||||
|
||||
long __syscall(long num, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, num);
|
||||
long a1 = va_arg(args, long);
|
||||
long a2 = va_arg(args, long);
|
||||
long a3 = va_arg(args, long);
|
||||
long a4 = va_arg(args, long);
|
||||
long a5 = va_arg(args, long);
|
||||
long a6 = va_arg(args, long);
|
||||
va_end(args);
|
||||
|
||||
if(__syscall_fns[num])
|
||||
return __syscall_fns[num](num, a1, a2, a3, a4, a5, a6);
|
||||
else
|
||||
return __syscall_common(num, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
EOF
|
||||
|
||||
cat >${musl_dir}/arch/x86_64/pthread_arch.h <<EOF
|
||||
struct pthread *__pthread_self();
|
||||
#define TP_ADJ(p) (p)
|
||||
#define MC_PC gregs[REG_RIP]
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
main $@
|
Loading…
x
Reference in New Issue
Block a user