[TOOLCHAIN] Making musl portable

This commit is contained in:
Thomas Lovén 2017-02-09 19:47:07 +01:00
parent a7d2b24a79
commit 8d1e693884
10 changed files with 207 additions and 6 deletions

View File

@ -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:

View File

@ -11,6 +11,8 @@ CFLAGS ?= -Wall -Wextra -ggdb -O0
all: init
init: $(SYSROOT)/usr/lib/libc.a
$(installdir)/init: init
mkdir -p $(dir $@)
cp $< $@

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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
View File

@ -0,0 +1,3 @@
#pragma once
#define SYS_DEBUG 0x3FF

53
libc/syscalls.c Normal file
View 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
View 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, ...);

View File

@ -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
View 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 $@