mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
Start work on a standard C library. I'm calling it... LibC.
This commit is contained in:
parent
85bcf2ed0f
commit
4cbf079a17
Notes:
sideshowbarker
2024-07-19 18:45:16 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/4cbf079a172
8 changed files with 311 additions and 0 deletions
32
LibC/Makefile
Normal file
32
LibC/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
|||
OBJS = \
|
||||
stdio.o \
|
||||
unistd.o
|
||||
|
||||
LIBRARY = LibC.a
|
||||
ARCH_FLAGS =
|
||||
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
|
||||
LIBC_FLAGS = -ffreestanding -fno-stack-protector -fno-ident
|
||||
WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings
|
||||
FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -fmerge-all-constants -fno-unroll-loops -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fno-pie -fno-pic
|
||||
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
|
||||
INCLUDE_FLAGS = -I.. -I.
|
||||
|
||||
DEFINES = -DSERENITY_LIBC -DSANITIZE_PTRS
|
||||
|
||||
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(LIBC_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
|
||||
CXX = g++
|
||||
LD = ld
|
||||
AR = ar
|
||||
LDFLAGS = -T linker.ld --strip-debug -melf_i386 --gc-sections --build-id=none -z norelro -z now
|
||||
|
||||
all: $(LIBRARY)
|
||||
|
||||
$(LIBRARY): $(OBJS)
|
||||
@echo "LIB $@"; $(AR) rcs $@ $(OBJS)
|
||||
|
||||
.cpp.o:
|
||||
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
@echo "CLEAN"; rm -f $(LIBRARY) $(OBJS)
|
||||
|
12
LibC/stdarg.h
Normal file
12
LibC/stdarg.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef char* va_list;
|
||||
|
||||
#define va_start(ap, v) ap = (va_list)&v + sizeof(v)
|
||||
#define va_arg(ap, t) ((t*)(ap += sizeof(t)))[-1]
|
||||
#define va_end(ap) ap = nullptr
|
||||
|
||||
}
|
||||
|
173
LibC/stdio.cpp
Normal file
173
LibC/stdio.cpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
#include "stdio.h"
|
||||
#include "stdarg.h"
|
||||
#include "types.h"
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
template<typename PutChFunc>
|
||||
int printHex(PutChFunc putch, char*& bufptr, dword number, byte fields)
|
||||
{
|
||||
static const char h[] = {
|
||||
'0','1','2','3','4','5','6','7',
|
||||
'8','9','a','b','c','d','e','f'
|
||||
};
|
||||
|
||||
int ret = 0;
|
||||
byte shr_count = fields * 4;
|
||||
while (shr_count) {
|
||||
shr_count -= 4;
|
||||
putch(bufptr, h[(number >> shr_count) & 0x0F]);
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename PutChFunc>
|
||||
int printNumber(PutChFunc putch, char*& bufptr, dword number)
|
||||
{
|
||||
dword divisor = 1000000000;
|
||||
char ch;
|
||||
char padding = 1;
|
||||
int ret = 0;
|
||||
|
||||
for (;;) {
|
||||
ch = '0' + (number / divisor);
|
||||
number %= divisor;
|
||||
|
||||
if (ch != '0')
|
||||
padding = 0;
|
||||
|
||||
if (!padding || divisor == 1) {
|
||||
putch(bufptr, ch);
|
||||
++ret;
|
||||
}
|
||||
|
||||
if (divisor == 1)
|
||||
break;
|
||||
divisor /= 10;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename PutChFunc>
|
||||
static int printSignedNumber(PutChFunc putch, char*& bufptr, int number)
|
||||
{
|
||||
if (number < 0) {
|
||||
putch(bufptr, '-');
|
||||
return printNumber(putch, bufptr, 0 - number) + 1;
|
||||
}
|
||||
return printNumber(putch, bufptr, number);
|
||||
}
|
||||
|
||||
static void sys_putch(char*, char ch)
|
||||
{
|
||||
Syscall::invoke(Syscall::PutCharacter, ch);
|
||||
}
|
||||
|
||||
template<typename PutChFunc>
|
||||
int printfInternal(PutChFunc putch, char* buffer, const char*& fmt, char*& ap)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
int ret = 0;
|
||||
char* bufptr = buffer;
|
||||
|
||||
for (p = fmt; *p; ++p) {
|
||||
if (*p == '%' && *(p + 1)) {
|
||||
++p;
|
||||
switch( *p )
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
const char* sp = va_arg(ap, const char*);
|
||||
//ASSERT(sp != nullptr);
|
||||
if (!sp) {
|
||||
putch(bufptr, '(');
|
||||
putch(bufptr, 'n');
|
||||
putch(bufptr, 'u');
|
||||
putch(bufptr, 'l');
|
||||
putch(bufptr, 'l');
|
||||
putch(bufptr, ')');
|
||||
ret += 6;
|
||||
} else {
|
||||
for (; *sp; ++sp) {
|
||||
putch(bufptr, *sp);
|
||||
++ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
ret += printSignedNumber(putch, bufptr, va_arg(ap, int));
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
ret += printNumber(putch, bufptr, va_arg(ap, dword));
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
ret += printHex(putch, bufptr, va_arg(ap, dword), 8);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
ret += printHex(putch, bufptr, va_arg(ap, int), 4);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
ret += printHex(putch, bufptr, va_arg(ap, int), 2);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
putch(bufptr, (char)va_arg(ap, int));
|
||||
++ret;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
putch(bufptr, '0');
|
||||
putch(bufptr, 'x');
|
||||
ret += 2;
|
||||
ret += printHex(putch, bufptr, va_arg(ap, dword), 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
putch(bufptr, *p);
|
||||
++ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int putchar(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
int printf(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = printfInternal(sys_putch, nullptr, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void buffer_putch(char*& bufptr, char ch)
|
||||
{
|
||||
*bufptr++ = ch;
|
||||
}
|
||||
|
||||
int sprintf(char* buffer, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = printfInternal(buffer_putch, buffer, fmt, ap);
|
||||
buffer[ret] = '\0';
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
10
LibC/stdio.h
Normal file
10
LibC/stdio.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
|
||||
int printf(const char* fmt, ...);
|
||||
int sprintf(char* buffer, const char* fmt, ...);
|
||||
int putchar(int ch);
|
||||
|
||||
}
|
||||
|
36
LibC/syscall.h
Normal file
36
LibC/syscall.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
inline dword syscall_a0(dword function)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword syscall_a1(dword function, dword arg1)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword syscall_a2(dword function, dword arg1, dword arg2)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline dword syscall_a3(dword function, dword arg1, dword arg2, dword arg3)
|
||||
{
|
||||
dword result;
|
||||
asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2),"b"(arg3));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
14
LibC/types.h
Normal file
14
LibC/types.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned char byte;
|
||||
|
||||
typedef dword uid_t;
|
||||
typedef dword gid_t;
|
||||
typedef dword pid_t;
|
||||
|
||||
}
|
||||
|
22
LibC/unistd.cpp
Normal file
22
LibC/unistd.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "unistd.h"
|
||||
#include <Kernel/Syscall.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
uid_t getuid()
|
||||
{
|
||||
return Syscall::invoke(Syscall::PosixGetuid);
|
||||
}
|
||||
|
||||
uid_t getgid()
|
||||
{
|
||||
return Syscall::invoke(Syscall::PosixGetgid);
|
||||
}
|
||||
|
||||
uid_t getpid()
|
||||
{
|
||||
return Syscall::invoke(Syscall::PosixGetpid);
|
||||
}
|
||||
|
||||
}
|
||||
|
12
LibC/unistd.h
Normal file
12
LibC/unistd.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
uid_t getuid();
|
||||
gid_t getgid();
|
||||
pid_t getpid();
|
||||
|
||||
}
|
||||
|
Loading…
Reference in a new issue