lib: c: re-organise into separate static modules, plus a single shared library

This commit is contained in:
2026-03-10 19:15:59 +00:00
parent 6d88cf4bf3
commit ea6ec785a9
18 changed files with 291 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
set(source_dirs core malloc)
set(source_dirs core malloc io)
set(public_include_dirs
${CMAKE_CURRENT_SOURCE_DIR}/include)
@@ -26,5 +26,5 @@ bsp_add_library(
NAME libc
LIB_DIR /usr/lib)
target_link_libraries(libc libmango)
target_link_libraries(libc libmango libxpc-static interface::fs)
target_compile_definitions(libc PRIVATE ENABLE_GLOBAL_HEAP=1)

View File

@@ -1,4 +1,4 @@
set(source_dirs stdio string)
set(source_dirs stdio string errno)
foreach (dir ${source_dirs})
file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c)
@@ -21,3 +21,5 @@ sysroot_add_library(
NAME libc-core
HEADER_DIR /usr/include
LIB_DIR /usr/lib)
target_link_libraries(libc-core libmango)

View File

@@ -0,0 +1,54 @@
#include <errno.h>
#include <mango/status.h>
#if defined(BUILD_STATIC)
int __set_errno(int err)
{
return -err;
}
#endif
#if defined(BUILD_SHARED)
int __set_errno(int err)
{
/* TODO */
return -1;
}
#endif
int __errno_from_kern_status(unsigned int err)
{
switch (err) {
case KERN_OK:
return SUCCESS;
case KERN_UNIMPLEMENTED:
return ENOSYS;
case KERN_NAME_EXISTS:
return EEXIST;
case KERN_INVALID_ARGUMENT:
return EINVAL;
case KERN_UNSUPPORTED:
return ENOTSUP;
case KERN_NO_MEMORY:
return ENOMEM;
case KERN_NO_ENTRY:
return ENOENT;
case KERN_WOULD_BLOCK:
return EWOULDBLOCK;
case KERN_NO_DEVICE:
return ENODEV;
case KERN_DEVICE_STUCK:
case KERN_IO_ERROR:
return EIO;
case KERN_FATAL_ERROR:
return ENXIO;
case KERN_BAD_STATE:
return EPERM;
case KERN_MEMORY_FAULT:
return EFAULT;
case KERN_ACCESS_DENIED:
return EACCES;
default:
return EINVAL;
}
}

View File

@@ -139,4 +139,7 @@
#define EQFULL 106 /* Interface output queue is full */
#define ELAST 106 /* Must be equal largest errno */
extern int __set_errno(int err);
extern int __errno_from_kern_status(unsigned int err);
#endif

View File

@@ -14,4 +14,6 @@ extern int strncmp(const char *s1, const char *s2, unsigned long n);
extern void *memset(void *str, int c, size_t n);
extern void *memcpy(void *dst, const void *src, size_t len);
extern char *strdup(char *s);
#endif

View File

@@ -1,9 +1,12 @@
#ifndef UNISTD_H_
#define UNISTD_H_
#include <stdint.h>
#include <stddef.h>
extern int open(const char *path, int flags);
extern int close(int fd);
extern int read(int fd, void *buf, size_t count);
extern int write(int fd, const void *buf, size_t count);
#endif

View File

@@ -0,0 +1,33 @@
set(source_dirs unistd stdio)
file(GLOB sources *.c *.h)
foreach (dir ${source_dirs})
file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c)
file(GLOB dir_headers ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.h)
set(sources ${sources} ${dir_sources})
set(headers ${headers} ${dir_headers})
endforeach (dir)
file(GLOB_RECURSE sub_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
set(headers ${headers} ${sub_headers})
set(component_sources ${sources} PARENT_SCOPE)
set(component_headers ${headers} PARENT_SCOPE)
set(component_public_include_dirs ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
rosetta_add_library(STATIC
NAME libc-io
PUBLIC_INCLUDE_DIRS
${public_include_dirs}
${CMAKE_CURRENT_SOURCE_DIR}/include
SOURCES ${sources}
HEADERS ${headers})
sysroot_add_library(
NAME libc-io
HEADER_DIR /usr/include
LIB_DIR /usr/lib)
target_link_libraries(libc-io libc-core interface::fs libxpc-static libmango)

2
lib/libc/io/fs.c Normal file
View File

@@ -0,0 +1,2 @@
#define MSG_IMPLEMENTATION
#include <rosetta/fs.h>

View File

@@ -0,0 +1,43 @@
#ifndef SYS_MMAN_H_
#define SYS_MMAN_H_
#include <mango/types.h>
#include <stddef.h>
#define PROT_NONE 0x00u
#define PROT_EXEC 0x01u
#define PROT_READ 0x02u
#define PROT_WRITE 0x04u
#define MAP_SHARED 0x01u
#define MAP_SHARED_VALIDATE 0x03u
#define MAP_PRIVATE 0x04u
#define MAP_32BIT 0x08u
#define MAP_ANON MAP_ANONYMOUS
#define MAP_ANONYMOUS 0x10u
#define MAP_DENYWRITE 0x20u
#define MAP_EXECUTABLE 0x40u
#define MAP_FILE 0x80u
#define MAP_FIXED 0x100u
#define MAP_FIXED_NOREPLACE 0x300u
#define MAP_GROWSDOWN 0x400u
#define MAP_HUGETLB 0x800u
#define MAP_HUGE_2MB 0x1000u
#define MAP_HUGE_1GB 0x2000u
#define MAP_LOCKED 0x4000u
#define MAP_NONBLOCK 0x8000u
#define MAP_NORESERVE 0x10000u
#define MAP_POPULATE 0x20000u
#define MAP_STACK 0x40000u
#define MAP_SYNC 0x80000u
#define MAP_UNINITIALIZED 0x100000u
extern void *mmap(
void *addr,
size_t length,
int prot,
int flags,
int fd,
off_t offset);
#endif

View File

@@ -0,0 +1,18 @@
#ifndef SYS_REMOTE_H_
#define SYS_REMOTE_H_
#include <mango/types.h>
#include <stdbool.h>
enum sys_remote_id {
SYS_REMOTE_NONE,
SYS_REMOTE_NSD,
};
extern bool sys_remote_get(
enum sys_remote_id id,
tid_t *out_tid,
unsigned int *out_chid);
extern void sys_remote_set(enum sys_remote_id id, tid_t tid, unsigned int chid);
#endif

45
lib/libc/io/remote.c Normal file
View File

@@ -0,0 +1,45 @@
#include <sys/remote.h>
#define TID_INVALID ((tid_t) - 1)
#define CHID_INVALID ((unsigned int)-1)
struct remote {
tid_t tid;
unsigned int chid;
};
static struct remote remotes[] = {
[SYS_REMOTE_NONE] = {.tid = TID_INVALID, .chid = CHID_INVALID},
[SYS_REMOTE_NSD] = {.tid = TID_INVALID, .chid = CHID_INVALID},
};
static const size_t nr_remotes = sizeof remotes / sizeof remotes[0];
bool sys_remote_get(
enum sys_remote_id id,
tid_t *out_tid,
unsigned int *out_chid)
{
if (id < 0 || id >= nr_remotes) {
return false;
}
const struct remote *remote = &remotes[id];
if (remote->tid == TID_INVALID || remote->chid == CHID_INVALID) {
return false;
}
*out_tid = remote->tid;
*out_chid = remote->chid;
return true;
}
void sys_remote_set(enum sys_remote_id id, tid_t tid, unsigned int chid)
{
if (id < 0 || id >= nr_remotes) {
return;
}
struct remote *remote = &remotes[id];
remote->tid = tid;
remote->chid = chid;
}

View File

View File

@@ -0,0 +1,6 @@
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
return NULL;
}

40
lib/libc/io/unistd/open.c Normal file
View File

@@ -0,0 +1,40 @@
#include <errno.h>
#include <mango/handle.h>
#include <mango/msg.h>
#include <rosetta/fs.h>
#include <sys/remote.h>
int open(const char *path, int flags)
{
tid_t remote_tid;
unsigned int remote_chid;
if (!sys_remote_get(SYS_REMOTE_NSD, &remote_tid, &remote_chid)) {
return __set_errno(ENXIO);
}
kern_handle_t port;
kern_status_t status = port_create(&port);
if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status));
}
status = port_connect(port, remote_tid, remote_chid);
if (status != KERN_OK) {
kern_handle_close(port);
return __set_errno(__errno_from_kern_status(status));
}
int err = SUCCESS;
status = fs_open(port, path, flags, &err);
if (status != KERN_OK) {
kern_handle_close(port);
return __set_errno(__errno_from_kern_status(status));
}
if (err != SUCCESS) {
kern_handle_close(port);
return __set_errno(err);
}
return (int)port;
}

21
lib/libc/io/unistd/read.c Normal file
View File

@@ -0,0 +1,21 @@
#include <errno.h>
#include <mango/handle.h>
#include <mango/msg.h>
#include <rosetta/fs.h>
#include <sys/remote.h>
int read(int fd, void *buf, size_t count)
{
int err;
size_t nr_read;
kern_status_t status = fs_read(fd, count, &err, &nr_read, buf, count);
if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status));
}
if (err != SUCCESS) {
return __set_errno(err);
}
return nr_read;
}

View File

View File

@@ -1,4 +1,4 @@
set(source_dirs stdlib)
set(source_dirs stdlib string)
file(GLOB sources *.c *.h)

View File

@@ -0,0 +1,14 @@
#include <stdlib.h>
#include <string.h>
char *strdup(char *s)
{
size_t len = strlen(s);
char *out = malloc(len + 1);
if (!out) {
return NULL;
}
memcpy(out, s, len + 1);
return out;
}