mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 13:16:31 +00:00
完善libc,构建了OS-specific工具链,编译了基于gcc-11.3.0的DragonOS userland compiler,移植了mpfr,gmp,mpc库 (#134)
* 修改include路径 * 添加了创建libsysapi.a和/bin/sysroot/usr/include/+lib/的代码 * 修补.gitignore * 删除多余项 * 优化脚本可读性 * 新增crt0 crti crtn * 编译binutils所需的东西 * fflush()和fprintf()的简单实现 * 应用程序启动前,调用初始化libc的函数 * 自动创建sysroot * 添加了stderr的初始化 * 修改了stderr的初始化 * 内核添加对stdio的简略处理 * 格式化代码 * 修正打开stdio文件描述符的问题 * bugfix: 修复fprintf忘记释放buf的问题 * 修复shell错误地把入口设置为main而不是_start的问题 * 新增__cxa_atexit (gcc要求libc提供这个) * 增加putchar puts * 更新写入磁盘镜像的脚本,默认无参数时,使用legacy方式安装 * 更新编译脚本 * stdio增加eof的定义 * 新增extern cplusplus * mpfr gmp mpc 构建脚本 * 更新libsysapi.a为libc.a * 加上ferror fopen fclose * 更新移植的软件的构建脚本 * 更改build_gcc_toolchain.sh中的-save参数名为-save-cache Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
@ -8,9 +8,12 @@ CFLAGS += -I .
|
||||
libc_sub_dirs=math sys
|
||||
|
||||
ifeq ($(ARCH), __x86_64__)
|
||||
libc_sub_dirs += sysdeps/x86_64
|
||||
libc_sub_dirs += arch/x86_64
|
||||
endif
|
||||
|
||||
$(libc_sub_dirs): ECHO
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS) -I $(shell pwd)"
|
||||
|
||||
libc_objs:= $(shell find ./*.c)
|
||||
|
||||
ECHO:
|
||||
@ -29,13 +32,7 @@ clean:
|
||||
cd .. ;\
|
||||
done
|
||||
|
||||
libc: $(libc_objs) libc_rust
|
||||
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
|
||||
echo "make all in $$subdir";\
|
||||
cd $$subdir;\
|
||||
$(MAKE) all CFLAGS="$(CFLAGS) -I $(shell pwd)";\
|
||||
cd ..;\
|
||||
done
|
||||
libc: $(libc_objs) $(libc_sub_dirs) libc_rust
|
||||
|
||||
libc_rust:
|
||||
rustup default nightly
|
||||
|
23
user/libs/libc/src/arch/x86_64/Makefile
Normal file
23
user/libs/libc/src/arch/x86_64/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
libc_arch_objs:= $(shell find ./*.c)
|
||||
|
||||
ECHO:
|
||||
@echo "$@"
|
||||
|
||||
|
||||
$(libc_arch_objs): ECHO
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
all: $(libc_arch_objs) crti.o crtn.o
|
||||
mv crt0.c.o crt0.o
|
||||
|
||||
crti.o: crti.S
|
||||
$(CC) -E crti.S > _crti.s # 预处理
|
||||
$(AS) $(ASFLAGS) -o crti.o _crti.s
|
||||
|
||||
crtn.o: crtn.S
|
||||
$(CC) -E crtn.S > _crtn.s # 预处理
|
||||
$(AS) $(ASFLAGS) -o crtn.o _crtn.s
|
||||
|
||||
clean:
|
||||
|
||||
echo "Done."
|
@ -3,11 +3,14 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
extern int main(int, char **);
|
||||
extern void _init();
|
||||
extern void _libc_init();
|
||||
|
||||
void _start(int argc, char **argv)
|
||||
{
|
||||
// printf("before main\n");
|
||||
// Run the global constructors.
|
||||
_init();
|
||||
_libc_init();
|
||||
int retval = main(argc, argv);
|
||||
// printf("before exit, code=%d\n", retval);
|
||||
exit(retval);
|
||||
}
|
13
user/libs/libc/src/arch/x86_64/crti.S
Normal file
13
user/libs/libc/src/arch/x86_64/crti.S
Normal file
@ -0,0 +1,13 @@
|
||||
.section .init
|
||||
.global _init
|
||||
_init:
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
|
||||
|
||||
.section .fini
|
||||
.global _fini
|
||||
_fini:
|
||||
push %rbp
|
||||
movq %rsp, %rbp
|
||||
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */
|
9
user/libs/libc/src/arch/x86_64/crtn.S
Normal file
9
user/libs/libc/src/arch/x86_64/crtn.S
Normal file
@ -0,0 +1,9 @@
|
||||
.section .init
|
||||
/* gcc will nicely put the contents of crtend.o's .init section here. */
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.section .fini
|
||||
/* gcc will nicely put the contents of crtend.o's .fini section here. */
|
||||
popq %rbp
|
||||
ret
|
8
user/libs/libc/src/cxa.c
Normal file
8
user/libs/libc/src/cxa.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* Register a function to be called by exit or when a shared library
|
||||
is unloaded. This function is only called from code generated by
|
||||
the C++ compiler. */
|
||||
int __cxa_atexit(void (*func)(void *), void *arg, void *d)
|
||||
{
|
||||
// todo: 使用rust实现这个函数。参考:http://redox.longjin666.cn/xref/relibc/src/cxa.rs?r=c7d499d4&mo=323&fi=15#15
|
||||
return 0;
|
||||
}
|
@ -6,19 +6,22 @@
|
||||
|
||||
#include <__libc__.h>
|
||||
|
||||
|
||||
int isalnum(int c);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
// int isalnum(int c);
|
||||
int isalpha(int c);
|
||||
int isdigit(int c);
|
||||
int islower(int c);
|
||||
int isprint(int c);
|
||||
int isgraph(int c);
|
||||
int iscntrl(int c);
|
||||
int isgraph(int c);
|
||||
int ispunct(int c);
|
||||
// int isgraph(int c);
|
||||
// int iscntrl(int c);
|
||||
// int isgraph(int c);
|
||||
// int ispunct(int c);
|
||||
int isspace(int c);
|
||||
int isupper(int c);
|
||||
int isxdigit(int c);
|
||||
// int isxdigit(int c);
|
||||
|
||||
int isascii(int c);
|
||||
|
||||
@ -36,3 +39,6 @@ int toupper(int c);
|
||||
|
||||
extern char _ctype_[256];
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief inode的属性(copy from vfs.h)
|
||||
@ -63,4 +66,8 @@ int closedir(struct DIR *dirp);
|
||||
* @param dir
|
||||
* @return struct dirent*
|
||||
*/
|
||||
struct dirent* readdir(struct DIR* dir);
|
||||
struct dirent* readdir(struct DIR* dir);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -10,6 +10,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define E2BIG 1 /* 参数列表过长,或者在输出buffer中缺少空间 或者参数比系统内建的最大值要大 Argument list too long. */
|
||||
#define EACCES 2 /* 访问被拒绝 Permission denied */
|
||||
#define EADDRINUSE 3 /* 地址正在被使用 Address in use.*/
|
||||
@ -100,4 +104,8 @@
|
||||
#define EWOULDBLOCK 80 /* 操作将被禁止 Operation would block (may be the same value as [EAGAIN]). */
|
||||
#define EXDEV 81 /* 跨设备连接 Cross-device link. */
|
||||
|
||||
extern int errno;
|
||||
extern int errno;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -10,6 +10,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define O_RDONLY 00000000 // Open Read-only
|
||||
#define O_WRONLY 00000001 // Open Write-only
|
||||
#define O_RDWR 00000002 // Open read/write
|
||||
@ -62,4 +66,8 @@
|
||||
* @param ...
|
||||
* @return int 文件描述符
|
||||
*/
|
||||
int open(const char * path, int options, ...);
|
||||
int open(const char * path, int options, ...);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ===== 描述long double 的数据比特结构
|
||||
#if __LDBL_MANT_DIG__ == 53 && __LDBL_MAX_EXP__ == 1024
|
||||
#elif __LDBL_MANT_DIG__ == 64 && __LDBL_MAX_EXP__ == 16384 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
@ -73,3 +77,7 @@ union ldshape
|
||||
(void)__x; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -1,12 +1,20 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
double fabs(double x);
|
||||
float fabsf(float x);
|
||||
// float fabsf(float x);
|
||||
long double fabsl(long double x);
|
||||
|
||||
double round(double x);
|
||||
float roundf(float x);
|
||||
long double roundl(long double x);
|
||||
|
||||
int64_t pow(int64_t x, int y);
|
||||
int64_t pow(int64_t x, int y);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PAD_ZERO 1 // 0填充
|
||||
#define LEFT 2 // 靠左对齐
|
||||
@ -10,4 +13,8 @@
|
||||
#define SMALL 64 // 十进制以上数字显示小写字母
|
||||
#define SIGN 128 // 显示符号位
|
||||
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9') // 用来判断是否是数字的宏
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9') // 用来判断是否是数字的宏
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SIGHUP 1
|
||||
#define SIGINT 2
|
||||
#define SIGQUIT 3
|
||||
@ -91,4 +95,8 @@ struct sigaction
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
|
||||
int signal(int signum, __sighandler_t handler);
|
||||
int raise(int sig);
|
||||
int kill(pid_t, int sig);
|
||||
int kill(pid_t, int sig);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -8,6 +8,12 @@
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t; // Signed integer type of the result of subtracting two pointers.
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -3,6 +3,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 字体颜色的宏定义
|
||||
#define COLOR_WHITE 0x00ffffff //白
|
||||
#define COLOR_BLACK 0x00000000 //黑
|
||||
@ -20,6 +24,18 @@
|
||||
|
||||
#define SEEK_MAX 3
|
||||
|
||||
/* The value returned by fgetc and similar functions to indicate the
|
||||
end of the file. */
|
||||
#define EOF (-1)
|
||||
|
||||
typedef struct {
|
||||
int fd; // 文件描述符
|
||||
} FILE;
|
||||
|
||||
extern FILE* stdin;
|
||||
extern FILE* stdout;
|
||||
extern FILE* stderr;
|
||||
|
||||
/**
|
||||
* @brief 往屏幕上输出字符串
|
||||
*
|
||||
@ -32,4 +48,16 @@ int64_t put_string(char *str, uint64_t front_color, uint64_t bg_color);
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
int sprintf(char *buf, const char *fmt, ...);
|
||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
|
||||
int fflush(FILE *stream);
|
||||
int fprintf(FILE *restrict stream, const char *restrict format, ...);
|
||||
int ferror(FILE *stream);
|
||||
FILE *fopen(const char *restrict pathname, const char *restrict mode);
|
||||
int fclose(FILE *stream);
|
||||
int puts(const char *s);
|
||||
int putchar(int c);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 获取一块堆内存
|
||||
*
|
||||
@ -45,4 +49,8 @@ void exit(int status);
|
||||
* @brief 通过发送SIGABRT,从而退出当前进程
|
||||
*
|
||||
*/
|
||||
void abort();
|
||||
void abort();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *memset(void *dst, unsigned char C, uint64_t size);
|
||||
/**
|
||||
* @brief 获取字符串的大小
|
||||
@ -76,4 +80,8 @@ static void *memcpy(void *dst, const void *src, long Num)
|
||||
: "0"(Num / 8), "q"(Num), "1"(dst), "2"(src)
|
||||
: "memory");
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 操作系统定义时间以ns为单位
|
||||
#define CLOCKS_PER_SEC 1000000
|
||||
|
||||
@ -42,4 +46,8 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
*
|
||||
* @return clock_t
|
||||
*/
|
||||
clock_t clock();
|
||||
clock_t clock();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -2,6 +2,10 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 关闭文件接口
|
||||
*
|
||||
@ -116,4 +120,8 @@ int rm(const char * path);
|
||||
*/
|
||||
void swab(void *restrict src, void *restrict dest, ssize_t nbytes);
|
||||
|
||||
pid_t getpid(void);
|
||||
pid_t getpid(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
18
user/libs/libc/src/libc_init.c
Normal file
18
user/libs/libc/src/libc_init.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
FILE *stdin;
|
||||
FILE *stdout;
|
||||
FILE *stderr;
|
||||
|
||||
void _libc_init()
|
||||
{
|
||||
// 初始化标准流对应的文件描述符
|
||||
stdin = malloc(sizeof(FILE));
|
||||
stdout = malloc(sizeof(FILE));
|
||||
stderr = malloc(sizeof(FILE));
|
||||
|
||||
stdin->fd = 0;
|
||||
stdout->fd = 1;
|
||||
stderr->fd = 2;
|
||||
}
|
69
user/libs/libc/src/stdio.c
Normal file
69
user/libs/libc/src/stdio.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fprintf(FILE *restrict stream, const char *restrict format, ...)
|
||||
{
|
||||
const int bufsize = 65536 * 2;
|
||||
char *buf = malloc(bufsize);
|
||||
memset(buf, 0, bufsize);
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(buf, format, args);
|
||||
va_end(args);
|
||||
|
||||
int len = strlen(buf);
|
||||
if (len > bufsize - 1)
|
||||
{
|
||||
len = bufsize - 1;
|
||||
buf[bufsize - 1] = 0;
|
||||
}
|
||||
write(stream->fd, buf, len);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
int puts(const char *s)
|
||||
{
|
||||
return put_string(s, COLOR_WHITE, COLOR_BLACK);
|
||||
}
|
||||
|
||||
int putchar(int c)
|
||||
{
|
||||
return printf("%c", (char)c);
|
||||
}
|
||||
|
||||
int fflush(FILE *stream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ferror(FILE *stream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fclose(FILE *stream)
|
||||
{
|
||||
if (stream->fd >= 3)
|
||||
{
|
||||
int retcval = close(stream);
|
||||
free(stream);
|
||||
return;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
FILE *stream = malloc(sizeof(FILE));
|
||||
memset(stream, 0, sizeof(FILE));
|
||||
|
||||
int fd = open(pathname, mode);
|
||||
if (fd >= 0)
|
||||
stream->fd = fd;
|
||||
return stream;
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
#include <libsystem/syscall.h>
|
||||
#include <signal.h>
|
||||
|
||||
extern void _fini();
|
||||
|
||||
int abs(int i)
|
||||
{
|
||||
return i < 0 ? -i : i;
|
||||
@ -54,6 +56,7 @@ int atoi(const char *str)
|
||||
*/
|
||||
void exit(int status)
|
||||
{
|
||||
_fini();
|
||||
syscall_invoke(SYS_EXIT, status, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
all: start.o
|
||||
|
||||
ifeq ($(ARCH), __x86_64__)
|
||||
start.o:
|
||||
$(CC) $(CFLAGS) -c elf/start.c -o elf/start.o
|
||||
endif
|
||||
|
||||
clean:
|
||||
|
||||
echo "Done."
|
Reference in New Issue
Block a user