Compare commits

..

30 Commits

Author SHA1 Message Date
b975256cb9 meta: update kernel 2026-03-24 20:26:19 +00:00
8d22ec661c bootstrap: remove old request handler code 2026-03-24 20:26:12 +00:00
a91dc5965e services: herdd: getdents test 2026-03-24 20:25:49 +00:00
329829c0e9 lib: fs: implement file cleanup using disconnect and detach events 2026-03-24 20:25:13 +00:00
dade9fa81f lib: xpc: add support for event messages 2026-03-24 20:24:36 +00:00
e9ccefd980 toolchain: xpcg: fix buffer length output not being set 2026-03-24 12:45:13 +00:00
20723d4dff bootstrap: tar: implement readdir() 2026-03-24 12:44:33 +00:00
d2df4259e6 interface: fs: add fs.getdents function 2026-03-24 12:43:33 +00:00
e30368553f lib: c: io: implement getdents() 2026-03-24 12:42:39 +00:00
660cb3bd71 lib: c: io: update fs_read usage 2026-03-24 12:42:08 +00:00
d3a25f0af7 lib: c: remove errno log messages 2026-03-24 12:41:41 +00:00
30614e679b lib: xpc: implement support for iterating through directories 2026-03-24 12:41:12 +00:00
1eb6853cb0 lib: xpc: implement scatter/gather i/o for buffers and messages 2026-03-24 12:40:16 +00:00
af3dd454b0 bootstrap: start herdd instead of systemd 2026-03-23 18:16:15 +00:00
2a587942ac meta: add herdd runlevel configuration files 2026-03-23 18:15:55 +00:00
bf5052fd3d meta: replace systemd and ldd with herdd and nsd 2026-03-23 18:15:38 +00:00
d4d3ab13f4 prog: remove test program 2026-03-23 18:14:57 +00:00
98dbaa05ac cmake: add support for building services with config files 2026-03-23 18:13:22 +00:00
1e3e38b0e2 meta: update kernel 2026-03-22 19:11:55 +00:00
c1e10e8b70 lib: c: implement runtime initialisation 2026-03-22 19:11:43 +00:00
7b89a038a2 lib: c: add fallback errno storage for single-threaded programs 2026-03-22 19:11:25 +00:00
a792bbe5db lib: c: pthread: implement per-thread errno storage 2026-03-22 19:09:18 +00:00
dd46a378b3 lib: c: pthread: implement pthread_self 2026-03-22 19:08:42 +00:00
33888e364b lib: rosetta: change integer bootstrap args to fixed-width types 2026-03-22 19:07:39 +00:00
a535c588f1 lib: launch: add terminating null ptr to environ array 2026-03-22 19:07:07 +00:00
9f4c4cbc9d lib: fs: fix incorrect status code in fs_msg_open 2026-03-22 19:06:40 +00:00
3e0fdb616c ld: resolve: search all images for symbols, rather than just direct links 2026-03-22 19:05:47 +00:00
44cd6c551a ld: resolve: remove redundant stack pointer save/restore 2026-03-22 19:05:25 +00:00
60e1ca951c ld: resolve: fix incorrect symbol and GOT index calculation 2026-03-22 19:04:58 +00:00
119a86b8e6 cmake: update for compatibility with CMake 4.0 2026-03-22 13:11:10 +00:00
70 changed files with 1194 additions and 398 deletions

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 4.0)
project(Rosetta C CXX ASM) project(Rosetta C CXX ASM)
include(CheckPIESupported) include(CheckPIESupported)
@@ -28,6 +28,7 @@ add_subdirectory(interface)
add_subdirectory(sys) add_subdirectory(sys)
add_subdirectory(lib) add_subdirectory(lib)
add_subdirectory(services) add_subdirectory(services)
add_subdirectory(runlevel)
add_subdirectory(programs) add_subdirectory(programs)
sysroot_add_program(NAME ${kernel_name} BIN_DIR /boot) sysroot_add_program(NAME ${kernel_name} BIN_DIR /boot)

View File

@@ -5,13 +5,13 @@ set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
find_program(C_COMPILER x86_64-elf-gcc REQUIRED) find_program(C_COMPILER x86_64-elf-gcc REQUIRED)
find_program(CXX_COMPILER x86_64-elf-g++ REQUIRED) find_program(CXX_COMPILER x86_64-elf-g++ REQUIRED)
find_program(ASM_COMPILER x86_64-elf-as REQUIRED) #find_program(ASM_COMPILER x86_64-elf-as REQUIRED)
add_compile_definitions(__mango__=1) add_compile_definitions(__mango__=1)
set(CMAKE_C_COMPILER ${C_COMPILER}) set(CMAKE_C_COMPILER ${C_COMPILER})
set(CMAKE_CXX_COMPILER ${CXX_COMPILER}) set(CMAKE_CXX_COMPILER ${CXX_COMPILER})
set(CMAKE_ASM_COMPILER ${ASM_COMPILER}) #set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
SET(CMAKE_C_FLAGS "-ffreestanding -nostdlib -z max-page-size=0x1000 -m64 -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -D_64BIT -DBYTE_ORDER=1234" CACHE STRING "" FORCE) SET(CMAKE_C_FLAGS "-ffreestanding -nostdlib -z max-page-size=0x1000 -m64 -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -D_64BIT -DBYTE_ORDER=1234" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-shared" CACHE STRING "" FORCE) set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-shared" CACHE STRING "" FORCE)
@@ -19,6 +19,7 @@ set(CMAKE_EXE_LINKER_FLAGS "-Wl,--unresolved-symbols=report-all,--dynamic-linker
set(CMAKE_C_LINK_OPTIONS_PIE "-pie") set(CMAKE_C_LINK_OPTIONS_PIE "-pie")
set(CMAKE_C_LINK_PIE_SUPPORTED TRUE) set(CMAKE_C_LINK_PIE_SUPPORTED TRUE)
set(CMAKE_C_LINK_NO_PIE_SUPPORTED TRUE) set(CMAKE_C_LINK_NO_PIE_SUPPORTED TRUE)
SET(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
set(CMAKE_C_OUTPUT_EXTENSION .o) set(CMAKE_C_OUTPUT_EXTENSION .o)
set(CMAKE_CXX_OUTPUT_EXTENSION .o) set(CMAKE_CXX_OUTPUT_EXTENSION .o)

View File

@@ -9,6 +9,36 @@ function(bsp_reset)
COMMAND_ERROR_IS_FATAL ANY) COMMAND_ERROR_IS_FATAL ANY)
endfunction(bsp_reset) endfunction(bsp_reset)
function(bsp_add_file)
set(options)
set(one_value_args ID SRC_PATH DEST_DIR)
set(multi_value_args)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(target_name ${arg_ID})
set(bsp_target_name _bsp-${target_name})
get_property(bsp_targets GLOBAL PROPERTY bsp_target_list)
list(LENGTH bsp_targets nr_bsp_targets)
if (${nr_bsp_targets} GREATER 0)
math(EXPR serialiser_index "${nr_bsp_targets}-1")
list(GET bsp_targets ${serialiser_index} serialiser)
endif ()
add_custom_target(${bsp_target_name}
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
add-binary ${bsp_manifest} ${target_name}
${arg_DEST_DIR} ${arg_SRC_PATH}
COMMENT "Preparing bsp component: ${target_name}"
DEPENDS ${arg_SRC_PATH} ${serialiser})
set_property(GLOBAL PROPERTY bsp_target_list ${bsp_targets} ${bsp_target_name})
endfunction(bsp_add_file)
function(bsp_add_library) function(bsp_add_library)
set(options) set(options)
set(one_value_args NAME HEADER_DIR LIB_DIR) set(one_value_args NAME HEADER_DIR LIB_DIR)
@@ -70,6 +100,40 @@ function(bsp_add_program)
set_property(GLOBAL PROPERTY bsp_target_list ${bsp_targets} ${bsp_target_name}) set_property(GLOBAL PROPERTY bsp_target_list ${bsp_targets} ${bsp_target_name})
endfunction(bsp_add_program) endfunction(bsp_add_program)
function(bsp_add_service)
set(options)
set(one_value_args NAME BIN_DIR SVC_DIR)
set(multi_value_args)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(target_name ${arg_NAME})
set(bsp_target_name _bsp-${target_name})
get_property(bsp_targets GLOBAL PROPERTY bsp_target_list)
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
list(LENGTH bsp_targets nr_bsp_targets)
if (${nr_bsp_targets} GREATER 0)
math(EXPR serialiser_index "${nr_bsp_targets}-1")
list(GET bsp_targets ${serialiser_index} serialiser)
endif ()
add_custom_target(${bsp_target_name}
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
add-binary ${bsp_manifest} ${target_name}
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
add-binary ${bsp_manifest} ${target_name}-cfg
${arg_SVC_DIR} ${cfg_file}
COMMENT "Preparing bsp component: ${target_name}"
DEPENDS ${target_name} ${serialiser})
set_property(GLOBAL PROPERTY bsp_target_list ${bsp_targets} ${bsp_target_name})
endfunction(bsp_add_service)
function(bsp_finalise) function(bsp_finalise)
set(options) set(options)
set(one_value_args BOOTSTRAP_PROGRAM DEST_DIR BSP_NAME) set(one_value_args BOOTSTRAP_PROGRAM DEST_DIR BSP_NAME)

View File

@@ -155,6 +155,40 @@ function(sysroot_add_program)
set_property(GLOBAL PROPERTY sysroot_target_list ${sysroot_targets} ${sysroot_target_name}) set_property(GLOBAL PROPERTY sysroot_target_list ${sysroot_targets} ${sysroot_target_name})
endfunction(sysroot_add_program) endfunction(sysroot_add_program)
function(sysroot_add_service)
set(options)
set(one_value_args NAME BIN_DIR SVC_DIR)
set(multi_value_args)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(target_name ${arg_NAME})
set(sysroot_target_name _sysroot-${target_name})
get_property(sysroot_targets GLOBAL PROPERTY sysroot_target_list)
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
list(LENGTH sysroot_targets nr_sysroot_targets)
if (${nr_sysroot_targets} GREATER 0)
math(EXPR serialiser_index "${nr_sysroot_targets}-1")
list(GET sysroot_targets ${serialiser_index} serialiser)
endif ()
add_custom_target(${sysroot_target_name}
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
add-binary ${sysroot_manifest} ${target_name}
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
add-binary ${sysroot_manifest} ${target_name}-cfg
${arg_SVC_DIR} ${cfg_file}
COMMENT "Preparing sysroot component: ${target_name}"
DEPENDS ${target_name} ${serialiser})
set_property(GLOBAL PROPERTY sysroot_target_list ${sysroot_targets} ${sysroot_target_name})
endfunction(sysroot_add_service)
function(sysroot_add_file) function(sysroot_add_file)
set(options) set(options)
set(one_value_args ID SRC_PATH DEST_DIR) set(one_value_args ID SRC_PATH DEST_DIR)

View File

@@ -32,6 +32,29 @@ function(rosetta_add_executable)
DESTINATION ${arg_SYSROOT_PATH}) DESTINATION ${arg_SYSROOT_PATH})
endfunction(rosetta_add_executable) endfunction(rosetta_add_executable)
function(rosetta_add_service)
set(options)
set(one_value_args NAME CFG_FILE)
set(multi_value_args SOURCES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}"
"${one_value_args}"
"${multi_value_args}")
set(exec_name ${arg_NAME})
get_property(programs GLOBAL PROPERTY rosetta_program_list)
set_property(GLOBAL PROPERTY rosetta_program_list ${programs} ${exec_name})
message(STATUS "Building service ${exec_name}")
add_executable(${exec_name} ${arg_SOURCES})
set_target_properties(${exec_name} PROPERTIES
POSITION_INDEPENDENT_CODE ON
service_cfg_path ${arg_CFG_FILE})
install(TARGETS ${exec_name}
DESTINATION ${arg_SYSROOT_PATH})
endfunction(rosetta_add_service)
function(rosetta_add_library) function(rosetta_add_library)
set(options STATIC SHARED) set(options STATIC SHARED)
set(one_value_args NAME) set(one_value_args NAME)

View File

@@ -3,9 +3,11 @@ interface fs 6400;
func open[0](path: string, flags: int) -> (err: int); func open[0](path: string, flags: int) -> (err: int);
func close[1]() -> (err: int); func close[1]() -> (err: int);
func read[2](count: size) -> (err: int, nr_read: size, data: buffer); func read[2](count: size) -> (err: int, data: buffer);
func write[3](data: buffer) -> (err: int, nr_written: size); func write[3](data: buffer) -> (err: int, nr_written: size);
func seek[4](offset: offset, origin: int) -> (err: int, new_pos: offset); func seek[4](offset: offset, origin: int) -> (err: int, new_pos: offset);
func map[5](prot: int, flags: int) -> (err: int, vmo: handle); func map[5](prot: int, flags: int) -> (err: int, vmo: handle);
func getdents[6]() -> (err: int, dents: buffer);

2
kernel

Submodule kernel updated: a2c89df195...a0a6a061a4

View File

@@ -26,7 +26,7 @@ bsp_add_library(
NAME libc NAME libc
LIB_DIR /usr/lib) LIB_DIR /usr/lib)
target_link_libraries(libc libmango libxpc-static interface::fs) target_link_libraries(libc PRIVATE libmango librosetta libxpc-static interface::fs)
target_compile_definitions(libc PRIVATE ENABLE_GLOBAL_HEAP=1) target_compile_definitions(libc PRIVATE ENABLE_GLOBAL_HEAP=1)
add_subdirectory(pthread) add_subdirectory(pthread)

View File

@@ -8,13 +8,17 @@ foreach (dir ${source_dirs})
set(headers ${headers} ${dir_headers}) set(headers ${headers} ${dir_headers})
endforeach (dir) endforeach (dir)
set(component_sources ${sources} PARENT_SCOPE) file(GLOB sys_sources
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.S)
set(component_sources ${sources} ${sys_sources} PARENT_SCOPE)
set(component_headers ${headers} PARENT_SCOPE) set(component_headers ${headers} PARENT_SCOPE)
rosetta_add_library(STATIC rosetta_add_library(STATIC
NAME libc-core NAME libc-core
PUBLIC_INCLUDE_DIRS ${public_include_dirs} PUBLIC_INCLUDE_DIRS ${public_include_dirs}
SOURCES ${sources} SOURCES ${sources} ${sys_sources}
HEADERS ${headers}) HEADERS ${headers})
sysroot_add_library( sysroot_add_library(
@@ -22,4 +26,4 @@ sysroot_add_library(
HEADER_DIR /usr/include HEADER_DIR /usr/include
LIB_DIR /usr/lib) LIB_DIR /usr/lib)
target_link_libraries(libc-core libmango) target_link_libraries(libc-core PRIVATE libmango librosetta)

View File

@@ -1,6 +1,13 @@
#include <errno.h> #include <errno.h>
#include <mango/status.h> #include <mango/status.h>
static int __errno = 32;
int __attribute__((weak)) * __errno_location(void)
{
return &__errno;
}
#if defined(BUILD_STATIC) #if defined(BUILD_STATIC)
int __set_errno(int err) int __set_errno(int err)
{ {
@@ -12,6 +19,7 @@ int __set_errno(int err)
int __set_errno(int err) int __set_errno(int err)
{ {
/* TODO */ /* TODO */
*__errno_location() = err;
return -1; return -1;
} }
#endif #endif

View File

@@ -0,0 +1,18 @@
#include <mango/log.h>
#include <rosetta/bootstrap.h>
#include <stdio.h>
extern int main(int, const char **, const char **);
void *__attribute__((weak)) pthread_self(void)
{
/* Nothing */
return NULL;
}
int __libc_init(const struct rosetta_bootstrap *bsinfo)
{
(volatile void)pthread_self();
kern_logf("bsinfo = %p", bsinfo);
return 0;
}

13
lib/libc/include/dirent.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef DIRENT_H_
#define DIRENT_H_
#define DT_UNKNOWN 0
#define DT_BLK 1
#define DT_CHR 2
#define DT_DIR 3
#define DT_FIFO 4
#define DT_LNK 5
#define DT_REG 6
#define DT_SOCK 7
#endif

View File

@@ -1,6 +1,8 @@
#ifndef ERRNO_H_ #ifndef ERRNO_H_
#define ERRNO_H_ #define ERRNO_H_
#define errno (*__errno_location())
#define SUCCESS 0 /* Success */ #define SUCCESS 0 /* Success */
#define EPERM 1 /* Operation not permitted */ #define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */ #define ENOENT 2 /* No such file or directory */
@@ -142,4 +144,6 @@
extern int __set_errno(int err); extern int __set_errno(int err);
extern int __errno_from_kern_status(unsigned int err); extern int __errno_from_kern_status(unsigned int err);
extern int __attribute__((weak)) * __errno_location(void);
#endif #endif

View File

@@ -7,4 +7,11 @@
#define SEEK_CUR 1 #define SEEK_CUR 1
#define SEEK_END 2 #define SEEK_END 2
struct dentry {
unsigned long d_ino;
unsigned short d_reclen;
char d_type;
char d_name[];
};
#endif #endif

View File

@@ -12,4 +12,6 @@ extern int write(int fd, const void *buf, size_t count);
extern off_t lseek(int fd, off_t offset, int whence); extern off_t lseek(int fd, off_t offset, int whence);
extern long getdents(int fd, struct dentry *dirp, unsigned int count);
#endif #endif

View File

@@ -0,0 +1,22 @@
#include <errno.h>
#include <mango/handle.h>
#include <mango/msg.h>
#include <rosetta/fs.h>
#include <sys/remote.h>
#include <sys/types.h>
int getdents(int fd, struct dentry *dirp, unsigned int count)
{
int err;
size_t nr_read = 0;
kern_status_t status = fs_getdents(fd, &err, dirp, count, &nr_read);
if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status));
}
if (err != SUCCESS) {
return __set_errno(err);
}
return nr_read;
}

View File

@@ -8,7 +8,7 @@ int read(int fd, void *buf, size_t count)
{ {
int err; int err;
size_t nr_read; size_t nr_read;
kern_status_t status = fs_read(fd, count, &err, &nr_read, buf, count); kern_status_t status = fs_read(fd, count, &err, buf, count, &nr_read);
if (status != KERN_OK) { if (status != KERN_OK) {
return __set_errno(__errno_from_kern_status(status)); return __set_errno(__errno_from_kern_status(status));
} }

View File

@@ -1,33 +1,32 @@
set(source_dirs thread) set(pthread_source_dirs thread)
foreach (dir ${source_dirs}) foreach (dir ${pthread_source_dirs})
file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c) file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.c)
file(GLOB dir_headers ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.h) file(GLOB dir_headers ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*.h)
set(sources ${sources} ${dir_sources}) set(pthread_sources ${pthread_sources} ${dir_sources})
set(headers ${headers} ${dir_headers}) set(pthread_headers ${pthread_headers} ${dir_headers})
endforeach (dir) endforeach (dir)
file(GLOB sys_sources file(GLOB pthread_sys_sources
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.S) ${CMAKE_CURRENT_SOURCE_DIR}/sys/${CMAKE_SYSTEM_PROCESSOR}/*.S)
set_property(SOURCE ${sys_sources} PROPERTY LANGUAGE C)
set(sources ${sources} ${sys_sources}) set(pthread_sources ${pthread_sources} ${pthread_sys_sources})
set(headers ${headers} ${CMAKE_CURRENT_SOURCE_DIR}/include/pthread.h) set(pthread_headers ${pthread_headers} ${CMAKE_CURRENT_SOURCE_DIR}/include/pthread.h)
set(public_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include) set(pthread_public_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)
rosetta_add_library(STATIC rosetta_add_library(STATIC
NAME libc-pthread NAME libc-pthread
PUBLIC_INCLUDE_DIRS ${public_include_dir} PUBLIC_INCLUDE_DIRS ${pthread_public_include_dir}
SOURCES ${sources} SOURCES ${pthread_sources}
HEADERS ${headers}) HEADERS ${pthread_headers})
rosetta_add_library(SHARED rosetta_add_library(SHARED
NAME libpthread NAME libpthread
PUBLIC_INCLUDE_DIRS ${public_include_dir} PUBLIC_INCLUDE_DIRS ${pthread_public_include_dir}
SOURCES ${sources} SOURCES ${pthread_sources}
HEADERS ${headers}) HEADERS ${pthread_headers})
sysroot_add_library( sysroot_add_library(
NAME libc-pthread NAME libc-pthread
@@ -38,5 +37,10 @@ sysroot_add_library(
HEADER_DIR /usr/include HEADER_DIR /usr/include
LIB_DIR /usr/lib) LIB_DIR /usr/lib)
target_link_libraries(libc-pthread libc-io libmango) bsp_add_library(
target_link_libraries(libpthread libmango libc) NAME libpthread
LIB_DIR /usr/lib)
target_link_libraries(libc-pthread PRIVATE libc-io libmango)
target_link_libraries(libpthread PRIVATE libmango)
target_link_libraries(libpthread PUBLIC libc)

View File

@@ -1,9 +1,9 @@
.code64 .code64
.global pthread_self .global __pthread_self
.type pthread_self, @function .type __pthread_self, @function
pthread_self: __pthread_self:
push %rbp push %rbp
mov %rsp, %rbp mov %rsp, %rbp

View File

@@ -0,0 +1,9 @@
#include "pthread.h"
#include <pthread.h>
int *__errno_location(void)
{
struct __pthread *self = pthread_self();
return &self->thr_errno;
}

View File

@@ -9,6 +9,7 @@ enum pthread_flags {
struct __pthread { struct __pthread {
struct __pthread *thr_self; struct __pthread *thr_self;
int thr_errno;
enum pthread_flags thr_flags; enum pthread_flags thr_flags;
kern_handle_t thr_handle; kern_handle_t thr_handle;
void *thr_map_base; void *thr_map_base;
@@ -16,6 +17,7 @@ struct __pthread {
void *thr_result; void *thr_result;
}; };
extern struct __pthread *__pthread_self(void);
extern void __pthread_unmap_exit( extern void __pthread_unmap_exit(
kern_handle_t address_space, kern_handle_t address_space,
void *unmap_base, void *unmap_base,

View File

@@ -0,0 +1,36 @@
#include "pthread.h"
#include <mango/task.h>
#include <mango/types.h>
#include <string.h>
#include <sys/mman.h>
static struct __pthread main_thread = {0};
struct __pthread *pthread_self(void)
{
static int init = 0;
if (!init) {
kern_handle_t self_handle = KERN_HANDLE_INVALID;
kern_status_t status = thread_self(&self_handle);
if (status != KERN_OK) {
/* TODO set an errno value in a way that doesn't result
* in a recursive call to pthread_self */
return NULL;
}
struct __pthread *self = &main_thread;
self->thr_self = self;
self->thr_handle = self_handle;
self->thr_map_base = self;
self->thr_map_size = sizeof *self;
thread_config_set(
self_handle,
THREAD_CFG_GSBASE,
&self,
sizeof(void *));
init = 1;
return self;
}
return __pthread_self();
}

View File

@@ -1,6 +1,5 @@
file(GLOB runtime_sources file(GLOB runtime_sources
${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_SYSTEM_PROCESSOR}/*.s) ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_SYSTEM_PROCESSOR}/*.s)
set_property(SOURCE ${runtime_sources} PROPERTY LANGUAGE C)
rosetta_add_object_library( rosetta_add_object_library(
NAME libc-runtime STATIC NAME libc-runtime STATIC

View File

@@ -3,18 +3,20 @@
.global _start .global _start
.type _start, @function .type _start, @function
.extern main .extern __libc_init
.type main, @function .type __libc_init, @function
.extern task_exit .extern task_exit
.type task_exit, @function .type task_exit, @function
_start: _start:
# Args (as provided by the ABI) # %rdi: (struct rosetta_bootstrap *)bs_info
# %rdi: int argc mov %rdi, %rbx
# %rsi: const char **argv call __libc_init
# %rdx: kern_handle_t task
# %rcx: kern_handle_t address_space mov 0(%rbx), %rdi # argc
mov 8(%rbx), %rsi # argv
mov 24(%rbx), %rdx # envp
call main call main
mov %rax, %rdi mov %rax, %rdi

View File

@@ -92,6 +92,7 @@ struct fs_context *fs_context_create(struct fs_allocator *alloc)
ctx->ctx_vtable.write = fs_msg_write; ctx->ctx_vtable.write = fs_msg_write;
ctx->ctx_vtable.seek = fs_msg_seek; ctx->ctx_vtable.seek = fs_msg_seek;
ctx->ctx_vtable.map = fs_msg_map; ctx->ctx_vtable.map = fs_msg_map;
ctx->ctx_vtable.getdents = fs_msg_getdents;
return ctx; return ctx;
} }
@@ -140,6 +141,28 @@ kern_handle_t fs_context_get_vm_controller(const struct fs_context *ctx)
return ctx->ctx_vm_controller; return ctx->ctx_vm_controller;
} }
static enum fs_status handle_event(struct fs_context *ctx, xpc_msg_t *msg)
{
switch (msg->msg_event) {
case KERN_MSG_EVENT_CONNECTION:
kern_logf("received connection");
break;
case KERN_MSG_EVENT_DISCONNECTION: {
struct fs_file *f
= fs_context_get_file(ctx, msg->msg_sender.e_port);
if (f) {
fs_context_close_file(ctx, f);
}
break;
}
default:
kern_logf("received unknown event");
break;
}
return FS_SUCCESS;
}
static enum fs_status handle_msg(struct fs_context *ctx) static enum fs_status handle_msg(struct fs_context *ctx)
{ {
xpc_msg_t msg; xpc_msg_t msg;
@@ -153,6 +176,10 @@ static enum fs_status handle_msg(struct fs_context *ctx)
return FS_ERR_INTERNAL_FAILURE; return FS_ERR_INTERNAL_FAILURE;
} }
if (msg.msg_type != KERN_MSG_TYPE_DATA) {
return handle_event(ctx, &msg);
}
switch (msg.msg_header.hdr_interface) { switch (msg.msg_header.hdr_interface) {
case INTERFACE_FS: case INTERFACE_FS:
status = fs_context_dispatch_msg(ctx, &msg); status = fs_context_dispatch_msg(ctx, &msg);
@@ -168,18 +195,43 @@ static enum fs_status handle_msg(struct fs_context *ctx)
return FS_SUCCESS; return FS_SUCCESS;
} }
static enum fs_status handle_page_request(struct fs_context *ctx) static enum fs_status handle_page_request_detach(
struct fs_context *ctx,
equeue_packet_page_request_t *packet,
struct file_mapping *mapping)
{ {
equeue_packet_page_request_t packet; kern_logf(
vm_controller_recv(ctx->ctx_vm_controller, &packet); "received page request (detach) for file %s",
struct file_mapping *mapping = (struct file_mapping *)packet.req_vmo;
kern_tracef(
"received page request [%zx-%zx] for file %s",
packet.req_offset,
packet.req_offset + packet.req_length,
mapping->m_file->f_dent->d_name); mapping->m_file->f_dent->d_name);
size_t length = packet.req_length; struct fs_file *f = mapping->m_file;
switch (mapping->m_type) {
case FILE_MAPPING_PRIVATE:
queue_delete(&f->f_mappings, &mapping->m_entry);
break;
default:
break;
}
kern_handle_close(mapping->m_vmo);
fs_context_free(ctx, mapping);
fs_context_close_file(ctx, f);
return FS_SUCCESS;
}
static enum fs_status handle_page_request_read(
struct fs_context *ctx,
equeue_packet_page_request_t *packet,
struct file_mapping *mapping)
{
kern_tracef(
"received page request (read) [%zx-%zx] for file %s",
packet->req_offset,
packet->req_offset + packet->req_length,
mapping->m_file->f_dent->d_name);
size_t length = packet->req_length;
if (length > TEMP_OBJECT_SIZE) { if (length > TEMP_OBJECT_SIZE) {
length = TEMP_OBJECT_SIZE; length = TEMP_OBJECT_SIZE;
} }
@@ -189,7 +241,7 @@ static enum fs_status handle_page_request(struct fs_context *ctx)
enum fs_status status = fs_file_read_at( enum fs_status status = fs_file_read_at(
mapping->m_file, mapping->m_file,
&buf, &buf,
packet.req_offset, packet->req_offset,
length); length);
if (status != FS_SUCCESS) { if (status != FS_SUCCESS) {
kern_tracef("map-read failed with code %d", status); kern_tracef("map-read failed with code %d", status);
@@ -199,10 +251,34 @@ static enum fs_status handle_page_request(struct fs_context *ctx)
vm_controller_supply_pages( vm_controller_supply_pages(
ctx->ctx_vm_controller, ctx->ctx_vm_controller,
mapping->m_vmo, mapping->m_vmo,
packet.req_offset, packet->req_offset,
ctx->ctx_temp_object, ctx->ctx_temp_object,
0, 0,
packet.req_length); packet->req_length);
return FS_SUCCESS;
}
static enum fs_status handle_page_request(struct fs_context *ctx)
{
equeue_packet_page_request_t packet;
kern_status_t status
= vm_controller_recv(ctx->ctx_vm_controller, &packet);
if (status != KERN_OK) {
return KERN_BAD_STATE;
}
struct file_mapping *mapping = (struct file_mapping *)packet.req_vmo;
switch (packet.req_type) {
case PAGE_REQUEST_READ:
return handle_page_request_read(ctx, &packet, mapping);
case PAGE_REQUEST_DETACH:
return handle_page_request_detach(ctx, &packet, mapping);
default:
kern_logf("unknown page request type %zx", packet.req_type);
break;
}
return FS_SUCCESS; return FS_SUCCESS;
} }
@@ -261,6 +337,16 @@ struct fs_file *fs_context_get_file(struct fs_context *ctx, unsigned long id)
void fs_context_close_file(struct fs_context *ctx, struct fs_file *f) void fs_context_close_file(struct fs_context *ctx, struct fs_file *f)
{ {
if (f->f_ref > 1) {
kern_logf(
"reference to file '%s' has been closed",
f->f_dent->d_name);
f->f_ref--;
return;
}
kern_logf("file '%s' has been closed", f->f_dent->d_name);
btree_delete(&ctx->ctx_filelist, &f->f_node);
} }
static size_t get_first_path_component(const char *in, char *out, size_t max) static size_t get_first_path_component(const char *in, char *out, size_t max)

View File

@@ -52,3 +52,15 @@ enum fs_status fs_file_write(
f->f_seek = seek; f->f_seek = seek;
return status; return status;
} }
enum fs_status fs_file_readdir(struct fs_file *f, struct xpc_buffer *buf)
{
if (!f->f_ops || !f->f_ops->f_readdir) {
return FS_ERR_NOT_IMPLEMENTED;
}
off_t seek = f->f_seek;
enum fs_status status = f->f_ops->f_readdir(f, buf, &seek);
f->f_seek = seek;
return status;
}

View File

@@ -9,6 +9,9 @@
#include <fs/inode.h> #include <fs/inode.h>
struct fs_file { struct fs_file {
/* reference count includes the file descriptor, and any vm-objects
* attached to the file */
unsigned int f_ref;
/* id of the open file, equal to the koid of the port being used to /* id of the open file, equal to the koid of the port being used to
* access the file */ * access the file */
unsigned long f_id; unsigned long f_id;

View File

@@ -19,6 +19,8 @@ struct fs_file_ops {
size_t, size_t,
off_t *); off_t *);
enum fs_status (*f_seek)(struct fs_file *, off_t, int); enum fs_status (*f_seek)(struct fs_file *, off_t, int);
enum fs_status (
*f_readdir)(struct fs_file *, struct xpc_buffer *, off_t *);
}; };
extern struct fs_inode *fs_file_get_inode(const struct fs_file *f); extern struct fs_inode *fs_file_get_inode(const struct fs_file *f);
@@ -37,4 +39,8 @@ extern enum fs_status fs_file_write(
const struct xpc_buffer *buf, const struct xpc_buffer *buf,
size_t count); size_t count);
extern enum fs_status fs_file_readdir(
struct fs_file *f,
struct xpc_buffer *buf);
#endif #endif

View File

@@ -27,7 +27,6 @@ extern kern_status_t fs_msg_read(
const xpc_endpoint_t *sender, const xpc_endpoint_t *sender,
size_t count, size_t count,
int *out_err, int *out_err,
size_t *out_nr_read,
xpc_buffer_t *out_data, xpc_buffer_t *out_data,
void *arg); void *arg);
extern kern_status_t fs_msg_write( extern kern_status_t fs_msg_write(
@@ -55,4 +54,11 @@ extern kern_status_t fs_msg_map(
kern_handle_t *out_vmo, kern_handle_t *out_vmo,
void *arg); void *arg);
extern kern_status_t fs_msg_getdents(
xpc_context_t *ctx,
const xpc_endpoint_t *sender,
int *out_err,
xpc_buffer_t *out_dents,
void *arg);
#endif #endif

View File

@@ -0,0 +1,34 @@
#include "../file.h"
#include <errno.h>
#include <fs/context.h>
#include <fs/file.h>
#include <fs/status.h>
kern_status_t fs_msg_getdents(
xpc_context_t *xpc,
const xpc_endpoint_t *sender,
int *out_err,
xpc_buffer_t *out_dents,
void *arg)
{
struct fs_context *ctx = arg;
struct fs_file *f = fs_context_get_file(ctx, sender->e_port);
if (!f) {
*out_err = EBADF;
return KERN_OK;
}
if (!(f->f_inode->i_mode & FS_INODE_DIR)) {
*out_err = ENOTDIR;
return KERN_OK;
}
size_t start = fs_file_get_cursor(f);
enum fs_status status = fs_file_readdir(f, out_dents);
size_t end = fs_file_get_cursor(f);
*out_err = fs_status_to_errno(status);
return KERN_OK;
}

View File

@@ -105,6 +105,7 @@ extern kern_status_t fs_msg_map(
kern_handle_t vmo; kern_handle_t vmo;
kern_handle_duplicate(mapping->m_vmo, &vmo); kern_handle_duplicate(mapping->m_vmo, &vmo);
f->f_ref++;
*out_err = SUCCESS; *out_err = SUCCESS;
*out_vmo = vmo; *out_vmo = vmo;

View File

@@ -4,6 +4,8 @@
#include <fs/context.h> #include <fs/context.h>
#include <fs/file.h> #include <fs/file.h>
#include <fs/status.h> #include <fs/status.h>
#include <mango/log.h>
#include <stdio.h>
extern kern_status_t fs_msg_open( extern kern_status_t fs_msg_open(
xpc_context_t *xpc, xpc_context_t *xpc,
@@ -39,10 +41,11 @@ extern kern_status_t fs_msg_open(
= fs_context_resolve_path(ctx, path_buf, &dent); = fs_context_resolve_path(ctx, path_buf, &dent);
if (fs_status != FS_SUCCESS) { if (fs_status != FS_SUCCESS) {
fs_context_close_file(ctx, f); fs_context_close_file(ctx, f);
*out_err = fs_status_to_errno(status); *out_err = fs_status_to_errno(fs_status);
return KERN_OK; return KERN_OK;
} }
f->f_ref = 1;
f->f_seek = 0; f->f_seek = 0;
f->f_dent = dent; f->f_dent = dent;
f->f_inode = dent->d_inode; f->f_inode = dent->d_inode;

View File

@@ -8,7 +8,6 @@ extern kern_status_t fs_msg_read(
xpc_endpoint_t *sender, xpc_endpoint_t *sender,
size_t count, size_t count,
int *out_err, int *out_err,
size_t *out_nr_read,
xpc_buffer_t *out_data, xpc_buffer_t *out_data,
void *arg) void *arg)
{ {
@@ -24,7 +23,7 @@ extern kern_status_t fs_msg_read(
size_t end = fs_file_get_cursor(f); size_t end = fs_file_get_cursor(f);
*out_err = fs_status_to_errno(status); *out_err = fs_status_to_errno(status);
*out_nr_read = end - start; out_data->buf_len = end - start;
return KERN_OK; return KERN_OK;
} }

View File

@@ -18,4 +18,4 @@ sysroot_add_library(
HEADER_DIR /usr/include HEADER_DIR /usr/include
LIB_DIR /usr/lib) LIB_DIR /usr/lib)
target_link_libraries(liblaunch librosetta libmango libc-core) target_link_libraries(liblaunch PRIVATE librosetta libmango libc-core)

View File

@@ -70,15 +70,14 @@ static virt_addr_t write_bootstrap_data(
bs->bs_argv = (const char **)remote_argv; bs->bs_argv = (const char **)remote_argv;
} }
if (bs->bs_envc > 0) { /* envc+1 so there is space for a null terminator */
virt_addr_t remote_envp; virt_addr_t remote_envp;
envp = stack_writer_put( envp = stack_writer_put(
stack, stack,
NULL, NULL,
bs->bs_envc * sizeof(char *), (bs->bs_envc + 1) * sizeof(char *),
&remote_envp); &remote_envp);
bs->bs_envp = (const char **)remote_envp; bs->bs_envp = (const char **)remote_envp;
}
size_t i = 0, j = 0; size_t i = 0, j = 0;
if (interpreter) { if (interpreter) {
@@ -95,11 +94,12 @@ static virt_addr_t write_bootstrap_data(
argv[i] = (const char *)arg_ptr; argv[i] = (const char *)arg_ptr;
} }
for (size_t i = 0; i < bs->bs_envc; i++) {
virt_addr_t env_ptr; virt_addr_t env_ptr;
for (i = 0; i < bs->bs_envc; i++) {
stack_writer_put_string(stack, params->p_envp[i], &env_ptr); stack_writer_put_string(stack, params->p_envp[i], &env_ptr);
envp[i] = (const char *)env_ptr; envp[i] = (const char *)env_ptr;
} }
envp[i] = NULL;
return bs_remote; return bs_remote;
} }

View File

@@ -12,4 +12,4 @@ sysroot_add_library(
HEADER_DIR /usr/include HEADER_DIR /usr/include
LIB_DIR /usr/lib) LIB_DIR /usr/lib)
target_link_libraries(librosetta libmango) target_link_libraries(librosetta PRIVATE libmango)

View File

@@ -26,17 +26,17 @@ struct rosetta_bootstrap_channel {
}; };
struct rosetta_bootstrap { struct rosetta_bootstrap {
int bs_argc; uintptr_t bs_argc;
const char **bs_argv; const char **bs_argv;
int bs_envc; uintptr_t bs_envc;
const char **bs_envp; const char **bs_envp;
const struct rosetta_bootstrap_handle *bs_handles; const struct rosetta_bootstrap_handle *bs_handles;
size_t bs_handles_count; uintptr_t bs_handles_count;
const struct rosetta_bootstrap_channel *bs_channels; const struct rosetta_bootstrap_channel *bs_channels;
size_t bs_channels_count; uintptr_t bs_channels_count;
}; };
extern const struct rosetta_bootstrap_channel *rosetta_bootstrap_get_channel( extern const struct rosetta_bootstrap_channel *rosetta_bootstrap_get_channel(

View File

@@ -5,6 +5,7 @@
kern_status_t xpc_buffer_read( kern_status_t xpc_buffer_read(
const xpc_buffer_t *buf, const xpc_buffer_t *buf,
size_t offset,
void *out, void *out,
size_t max, size_t max,
size_t *nr_read) size_t *nr_read)
@@ -14,25 +15,35 @@ kern_status_t xpc_buffer_read(
return KERN_BAD_STATE; return KERN_BAD_STATE;
} }
size_t to_read = max; if (offset >= buf->buf_len) {
if (to_read > buf->buf_len) { if (nr_read) {
to_read = buf->buf_len; *nr_read = 0;
} }
kern_status_t status return KERN_OK;
= xpc_msg_read(buf->buf_origin, buf->buf_offset, out, to_read); }
size_t to_read = max;
if (offset + to_read > buf->buf_len) {
to_read = buf->buf_len - offset;
}
kern_status_t status = xpc_msg_read(
buf->buf_origin,
buf->buf_offset + offset,
out,
to_read,
nr_read);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
/* TODO */
*nr_read = to_read;
return KERN_OK; return KERN_OK;
} }
kern_status_t xpc_buffer_write( kern_status_t xpc_buffer_write(
xpc_buffer_t *buf, xpc_buffer_t *buf,
size_t offset,
const void *in, const void *in,
size_t len, size_t len,
size_t *nr_written) size_t *nr_written)
@@ -41,9 +52,17 @@ kern_status_t xpc_buffer_write(
return KERN_BAD_STATE; return KERN_BAD_STATE;
} }
if (offset >= buf->buf_max) {
if (nr_written) {
*nr_written = 0;
}
return KERN_OK;
}
size_t to_write = len; size_t to_write = len;
if (to_write > buf->buf_max) { if (offset + to_write > buf->buf_max) {
to_write = buf->buf_max; to_write = buf->buf_max - offset;
} }
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) { if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
@@ -54,8 +73,70 @@ kern_status_t xpc_buffer_write(
return xpc_msg_write( return xpc_msg_write(
buf->buf_origin, buf->buf_origin,
buf->buf_offset, buf->buf_offset + offset,
in, in,
to_write, to_write,
nr_written); nr_written);
} }
xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
if (!(buf->buf_flags & XPC_BUFFER_F_IN)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_readv(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_read);
}
xpc_status_t xpc_buffer_writev(
xpc_buffer_t *buf,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
return KERN_BAD_STATE;
}
/* TODO limit to buffer bounds */
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
/* TODO */
return KERN_UNIMPLEMENTED;
}
return xpc_msg_writev(
buf->buf_origin,
buf->buf_offset + offset,
iov,
nr_iov,
nr_written);
}
xpc_status_t xpc_buffer_length(const xpc_buffer_t *s)
{
return s->buf_len;
}
xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s)
{
return s->buf_max;
}

View File

@@ -1,6 +1,7 @@
#ifndef XPC_BUFFER_H_ #ifndef XPC_BUFFER_H_
#define XPC_BUFFER_H_ #define XPC_BUFFER_H_
#include <mango/types.h>
#include <stddef.h> #include <stddef.h>
#include <xpc/status.h> #include <xpc/status.h>
@@ -71,13 +72,31 @@ typedef struct xpc_buffer {
extern xpc_status_t xpc_buffer_read( extern xpc_status_t xpc_buffer_read(
const xpc_buffer_t *s, const xpc_buffer_t *s,
size_t offset,
void *out, void *out,
size_t max, size_t max,
size_t *nr_read); size_t *nr_read);
extern xpc_status_t xpc_buffer_write( extern xpc_status_t xpc_buffer_write(
xpc_buffer_t *s, xpc_buffer_t *s,
size_t offset,
const void *in, const void *in,
size_t len, size_t len,
size_t *nr_written); size_t *nr_written);
extern xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern xpc_status_t xpc_buffer_writev(
xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern xpc_status_t xpc_buffer_length(const xpc_buffer_t *s);
extern xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s);
#endif #endif

View File

@@ -17,10 +17,21 @@ typedef struct xpc_msg_header {
typedef struct xpc_msg { typedef struct xpc_msg {
xpc_endpoint_t msg_sender; xpc_endpoint_t msg_sender;
kern_msg_type_t msg_type;
union {
/* msg_type = KERN_MSG_TYPE_DATA */
struct {
xpc_msg_header_t msg_header; xpc_msg_header_t msg_header;
size_t msg_handles_count; size_t msg_handles_count;
kern_msg_handle_t msg_handles[KERN_MSG_MAX_HANDLES]; kern_msg_handle_t msg_handles[KERN_MSG_MAX_HANDLES];
};
/* msg_type = KERN_MSG_TYPE_EVENT */
struct {
kern_msg_event_type_t msg_event;
};
};
} xpc_msg_t; } xpc_msg_t;
extern void xpc_msg_header_init( extern void xpc_msg_header_init(
@@ -34,7 +45,8 @@ extern kern_status_t xpc_msg_read(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
void *p, void *p,
size_t count); size_t count,
size_t *nr_read);
extern kern_status_t xpc_msg_write( extern kern_status_t xpc_msg_write(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
@@ -42,6 +54,19 @@ extern kern_status_t xpc_msg_write(
size_t count, size_t count,
size_t *nr_written); size_t *nr_written);
extern kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern kern_status_t xpc_msg_reply( extern kern_status_t xpc_msg_reply(
const xpc_msg_t *msg, const xpc_msg_t *msg,
kern_iovec_t *iov, kern_iovec_t *iov,

View File

@@ -54,14 +54,24 @@ static kern_status_t __msg_recv(
return status; return status;
} }
switch (msg.msg_type) {
case KERN_MSG_TYPE_DATA:
if (!xpc_msg_header_validate(&out->msg_header)) { if (!xpc_msg_header_validate(&out->msg_header)) {
return KERN_INVALID_ARGUMENT; return KERN_INVALID_ARGUMENT;
} }
break;
case KERN_MSG_TYPE_EVENT:
out->msg_event = msg.msg_event;
break;
default:
break;
}
out->msg_sender.e_channel = channel; out->msg_sender.e_channel = channel;
out->msg_sender.e_task = msg.msg_sender; out->msg_sender.e_task = msg.msg_sender;
out->msg_sender.e_port = msg.msg_endpoint; out->msg_sender.e_port = msg.msg_endpoint;
out->msg_sender.e_msg = msg.msg_id; out->msg_sender.e_msg = msg.msg_id;
out->msg_type = msg.msg_type;
return KERN_OK; return KERN_OK;
} }
@@ -89,17 +99,17 @@ kern_status_t xpc_msg_read(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
void *p, void *p,
size_t count) size_t count,
size_t *nr_read)
{ {
kern_iovec_t iov = IOVEC(p, count); kern_iovec_t iov = IOVEC(p, count);
size_t r = 0;
return msg_read( return msg_read(
msg->msg_sender.e_channel, msg->msg_sender.e_channel,
msg->msg_sender.e_msg, msg->msg_sender.e_msg,
offset, offset,
&iov, &iov,
1, 1,
&r); nr_read);
} }
kern_status_t xpc_msg_write( kern_status_t xpc_msg_write(
@@ -119,6 +129,38 @@ kern_status_t xpc_msg_write(
nr_written); nr_written);
} }
kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
return msg_read(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_read);
}
kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
return msg_write(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_written);
}
kern_status_t xpc_msg_reply( kern_status_t xpc_msg_reply(
const xpc_msg_t *msg, const xpc_msg_t *msg,
kern_iovec_t *iov, kern_iovec_t *iov,

View File

@@ -19,14 +19,12 @@ xpc_status_t xpc_string_read(
} }
kern_status_t status kern_status_t status
= xpc_msg_read(s->s_origin, s->s_offset, out, to_read); = xpc_msg_read(s->s_origin, s->s_offset, out, to_read, nr_read);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
out[to_read] = '\0'; out[to_read] = '\0';
/* TODO */
*nr_read = to_read;
return KERN_OK; return KERN_OK;
} }

View File

@@ -1,10 +0,0 @@
file(GLOB sources *.c)
add_executable(systemd ${sources})
target_link_libraries(systemd libc libc-runtime liblaunch libmango)
sysroot_add_program(
NAME systemd
BIN_DIR /usr/bin)
bsp_add_program(
NAME systemd
BIN_DIR /usr/bin)

View File

@@ -1,14 +0,0 @@
#include <mango/log.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
kern_logf("systemd");
kern_logf("args:");
for (int i = 0; i < argc; i++) {
kern_logf("[%d]: %s", i, argv[i]);
}
return 0;
}

View File

@@ -1,9 +0,0 @@
add_executable(test test.c)
target_link_libraries(test libc libc-runtime liblaunch)
sysroot_add_program(
NAME test
BIN_DIR /usr/bin)
bsp_add_program(
NAME test
BIN_DIR /usr/bin)

View File

@@ -1,167 +0,0 @@
#include <mango/log.h>
#include <stdio.h>
#include <string.h>
const char *s
= "RHZVNYYFPCGZIKWYLOZAKKLZGKWXDPXSTWNSWDBVDCPUMTAZCRNGNHGQPAGEWVAOCJST"
"PBXVWPKXQAHGETDTDETVYAEQGNBLEQIPHGGWKEDJAULOVMZKNABLUUXOTMHJNAVLSGCZ"
"QIFHIUCBCIRZIOFVHBPSGVBBZSRAQZYRPMYBNJDFTWSUUZVBQZTBUFUDJDYKUXWHDMXD"
"JKBSNWLFPUDGRMQPBCWVJZHOTJBTMGUSXQUZVXLDKWIKINXRFJKSYJEKDAPRQPMQMJPS"
"ICCTMELLKDFFJXOXISIXNVANFHLRPYMNPYCMUOYSPAYCKYJKRBZENHXYRJWRYXZGETMJ"
"XBFTCMSIHZQSCMLESDFKGTTNMCZSXEFMGXZYPWVPODMYTLDUOKGPMTMFBTQQHPBHMNCM"
"LYRGGUAIRSFFBRSKXOLJBWEMEODRQLXZJDRSTXBJOKOMUQKCJVKFHDYXCUUDHDEITHNH"
"VQLJJQMLYWGIDVLYCEJTJFJQLTKSAPZGEEZKVLQPHIVJNJVTXJUGPZODIFXTQNLBSFLG"
"NSPMGLUSEBOFJWXFFRBHIHYGGTILVVOJRPOFOIGDFCHLAZXLSOUCPCLZCBVWGZVKGDON"
"RPYOTSRWUNAGQSPHSGEQHOLUSOZCQQGJBLPKQNGKOPCVKLACDBPAPXDMGKLFPUOFQDWY"
"INIKZPLVFSZZZZHAYKXTETJDPMBHKNRCRLXZHFENZCABDTZULCRHCCVZFETBEBEJFVKJ"
"ADWFSHKKSMMKGTIHPAIAMWXTRJILBMWMBDZGRPZXHMJVCWPKSNPYPPNSAVQDSMANBFZO"
"LJBYKDOZNAPZRWEQDIIZRPNGZGHQWPIONPSAMBNNZERYMIQOVHRGZFXWVUARJMFWNPQP"
"GHDCZABLOYHCBCXAIDSPMDKZVBBOKHAHGTEPRQAIBVWTFBQDGDJPQGMVAGQQVMULVPMG"
"UPGEJUIZZXQRQKRJUCKDDZFTAHAAHMJLSISGFFOXOYNMJCAPPQXAVFSAFFRPRTEQLNCX"
"JVKTHBPZLAEXSIGVJASAERWDGDQDXASXHRSSCNAUMRWSQDZTOJHJGJLLXMJSTXBHOYPH"
"ELYKSXNJSPWPMFAKOOTXXTOEBLYFSOIJDWAOCTHDFOEBEEXVUBXOJDUCJWQOUUDOJNZG"
"PULPYTAOQEXMHSGOOUXHAJOKRHOOMZYMBHQNTQDWZPCXATDEKTYLNBKNUEIINHQTEGTR"
"ZKLMAKIIHHZBQIPXLAGADCFDYWEOJVHFPEMRDIOJYAMWSWEUOPJFEDGRGJOQNTSHRIJY"
"JPTOSWYZXJCGXLYVOWKAFGULLNCKIUZDWUXTHNYSWMMCJGTFVVVPJHEKYQVFRWLIZBBK"
"CNCRITFZYTQZZGZHXELBEYXSVVYRFBGRFPRDROUXKUMAGFYOJRMCLLHJVMQFYOBCXSEL"
"OQAQTRMLSGDAXWMBRSQHCIYYMBQQHMUQOKIANZCBGKHLCPUVUEZVKDTTSOWKKWIUBAIW"
"SOCJAUALJFEQQXJBHRRZBFMJZZMIWTFKQDPOBFIGABJTHFLLSZPWWGGLHLYXKBODKBIV"
"GAYGIKHNMTMJHCPRBQYAACGSFZPJWXUTRZFCGTLFQBVHZBKYBRMYTTCGIDKYWVRPJDTX"
"RKXGOPOQLNSEIGHTSAXGPBROFHQACSIVSLCXTEDUOEPRMGJDYWTKEHCXWINUDCAZWAEY"
"RQDKZRZXKWGHVWJDYHGFLCGKCLYCVHZTWWXPDBKTMBKBASERMURDREKNYVOCPHFSEGBQ"
"LAUHDDCAPPGOAFZYJYXPPAQLUQVKSDEHPPDXMNWAAYLHXBFEFXRLSMQNIYDECYVVPHEE"
"WXFFPEYLSHBXLYJWRABFKJYMJNWAUMVYJKZRDMPUQJKWVNTPRMHTAQGNSDLFTXVNIAIJ"
"HOIISROAJCWEOAIHYMDGWEOABPGIMBTTGWYVJDZOOMUSHYDPCMKWDIXDGJCGTQVXWBKP"
"DBCVJJDYIAPXKINQXACEMTJRCIAENGTTMWXVSQCCXRDVNZZNQDZTTYJHQGXZIJIIKPAU"
"TQJDDQQEPGYZNKCKNMVFCRHUECPVFZYVUWVMSCIQZBVLSTNFAHDDEQRKDOUAQVRVQAVB"
"ZCEMAJRJBVWKVBNEIQWWQSJPUVUKMBJIISCWXGGMWANYYLPCXHCBARMFTFMDXWSMKXPW"
"DZUGFBSGGWXLOFGYJVIDWNTSGODTHQNCKPWRJENDZNSCEYZRLEPNNYVBNUZMXAUWNAJD"
"XGTOLUAAIAHMDJERSESVFSMMHJKHIVIBWZLEAXUKRSWJOTFODRBZIJBRJQTFBVRQHITD"
"TDBAJZCZUKSIZJYDXWTSRPLXULXHGEKMWMICUYVAGNGEICEMMVWLLYWTAKWNGLRYOCIG"
"BEYTLVAZFHBYIJPUAQHITKHPWAQNEBQVAYZEINLRCKUZILAQPAGBJDWWLGCPQZOZVDQP"
"MWTIOAFMEMFKLGVGGHTTKNERTLPPQFALZMCWSOMJQQZMRABNKBCYPFJOWQCXJKXTNOMJ"
"MXAWMPFBJHOYHVOBDNWTKHYTISUQMFSNVBGUHDQFYCSZLZAFABKYQSZRQGKXOXORQPSJ"
"NKRVVAXMMVVPBSWMTHUNXBLSVIOOQPLRPROIBBQGNQVOXQXRNNMSFGUZEIGIYMLMLYYL"
"VINTZYXYXHUFMTQFPDGSFFDVCDMEZXSGQMMGJWMWANFSZNHDIIHVJFOZGMHAOVRUWWVX"
"RCOJJKZLTMAOGSRWNNXPYDCQWSSOFWUKFPKQGYLFSMZBZBKWSBMMZMFPOYYMLVYHQQQF"
"HORVESQYIKEBBKSEUYXUFRNNXZPUYESZWAKQQPAWZUHYJLXRXBFPRFSCHIHHDVAIKYDZ"
"IDLVQBCSGOSGFOUKVMKTODAHQVTACKAONRDYENPGSQFKGKYQROFOEKMJXKFIAEKWNRJH"
"RZCCSMNSSHZNSRTBGFJJDWAPVIOBDCQKMDEMUIWGMETBUTCGMMGXLHWWTXXQYAPMQQGU"
"CHECLYRWNFKHGRWYZISFYKSGTJXKTKIMJKTUWOQFHXUVTOBYUCOZKLCQCUIURHSIGUAU"
"FFSNEHFLHNGBNVTGPKCVCQLHEHLJRWPGSWHKFMMXSSCVTCUOEEZOFOPTDRUPPCYTRSKI"
"NJBPLOHMHQLWKMVBSZLZVDZEKXKSCNWPZTGZUXRYJEPENAYFCEKCAMWQLNYDHCSUUSTJ"
"GFZCTKDQYPEZKOOJQTYMWHZDDTCMYUXCAKFXISWQZDVETOAYIANBRSXLYKOGGHEEEGAX"
"SRIASWZBXTFCHLKMXQDYNLZICZZANCBUVGWFWFHYAWVLQXTQPGPQGRGBEZVIIGZJUVQU"
"PNXEMZDIFXAKSHTCCBQSAXWFBNLRYQKXKXQHAFZTUICFQVYOXQEHASXNSVUTYKSVYTMH"
"UTPBEVILWSKGQXPAEEOPUSMGQVPWFMRZRIMJZRRQRIZBTTRROUWENBHUYVMOMVPFDLZH"
"XMXYRNASODBTLCNRDSLGPTZBZHKTSMHIVNFJOMOFPHDANVSVOYZSTKOQJLDPKLOMAYUU"
"CKWTOTDONTXKCEGVXKZNNFIUXHLJPFFNVMWSFPXZKROEIGQNGXWDRFJWDCUEGJCUJGVG"
"PHYKQEWVOHHPURHBBIEZCKQCFUFFBDXYRNOHAVJISOQYXMRXIEFEISFEZHLNTJXYEAKM"
"EKZPJQVQBKPXPFSOANBBJBAFJQEMPIELYUHYCHUTADTCLFXUQLXWTJEFLJXVBRQXYSIR"
"RPMTNMFMUCHQJEVXUSFYUUYJHLEQBHUQOTVADYQGRXVLUPQXVXEDIGNSCYNMKPWLFLHZ"
"LMQGPTMBDVUJOBSXDFHKSIEXJJQTURPNZVQDLUEJHQZOQSBMPMBEQOCOSEKVXIVSQIQL"
"GSQAUMIAHHLQCBCQWFJWHSYNRFFTBKORISDYNRSMPVERKRJBWGYJRXMKHJDAKRANHFDH"
"WTZOHYRVCTTUXCRAFNOLYPRGDYTXNSOTCDNFVVURJILWVDWOCGPQOZIGGNOEAHCBYGMC"
"XGXAADYMYDAUXPDFADTVEQTHZRGYASPJRDIKJUFIRXGMFSCIURDNFIDUUDEKPFGWECZC"
"OOFZWESHSPSOOBWZKIGODSLXCALULNOLQLCMMLSQDWJDTEOIYXFCLSLKJKGCGURXEEIN"
"SCUQTRDGMYXFZEFBATVSYVAJISCBVDBZAJAPKBBQTQNNRZYBLGWPCIORYJJEKIZXRRCG"
"ZHGQNMGWVNIANJXYJMWRCGDGDFFQISSZOWTQOKWRGXSGRUSJOHABJUEUIHNTLCXJQPNF"
"YUKTQCGRFGZOQWYLJOGOGSRDXESAOTHZVHBEOOYJZYTMOSUUXDQNKTQBVUMRBPJEJIBU"
"TOVXSGYSTADWQKFUEFWJDCAYTEYVZYDCQTHXJWYUESZSLRBKRAMLVVVBMEYSYFNBLKTY"
"UJRQBOKJQTYXTOFPWGWEEANVFYMAVRKMNJARUOKTZTMMJKNVFEVSECABUZGGUEHRJIHO"
"JODXJOOGFZWNURNEXBUCCUHUDYXBZTNJZSQGHAGYLJQSSJERWEGUFAJXGNBXDWVFSCEG"
"SUCLQLHHTRQADZIBKFCBBEXUDLPCFUDONSHUUCREKHDUBQBKMECPPOGFYIUZNUDKTILB"
"IHMYNAMJIDTJEQTVPFZDNONMWFIJEAUOLPWOZVKEFTXRCXNWHWPYDHLWNSWTMUEIBMSK"
"FWROAFBMEOJAVLMNCNWEMGRUDKRPENXCJQQGLPCODNOTGPOQFZTOBEBJIDAMMZARXTMC"
"EAHKYNTYZKWCUFYOSCOPICKIDAUSZHWNTVRRSTIMHFBUALQECIZKYFUYJHDTFDODXXNJ"
"AKZNUMYZSHIGZQQXBTORWFCGQFKFURMZYWBAQSHAJEASIYAFQZDOUHBJXODDUAWNKWVB"
"NABZSUNRULZDXKBRGVCKUIYVRVRMTDFSWCTCDYKBZDELJBDIHLOALYEKHNMECBWRZQBK"
"XLWFYJYECKOJOGXJYBKFSUQZKEUWBHEWNHSZKJPRQRMLRFLJWBDZEJQVYRAFQGEOGUBU"
"SVVWUGKXHSXHRXWCZKASIYPZZDLRUVBNBUQEEPZPHMSNUETUKMYWNJLEZWVOLZBQMLWE"
"YPPVBOTADNFNJWUZKDWRXCJCMDQPGPBIVAVQJVTHEPLXEKPSPJQFNGILKTUETORGMHGH"
"HHXTZIXUXPDLKNYGHNNTKAZFCGCUONFANKRXHGPQLPDJACZDMSSFPJHRPPGGSVEYKQHF"
"JKASAYIFKXXVEYRCLIMLDEUQWIHZXPLKDCHUFYAHLOQUJMJCXTHFAOSOEYWOMFAZHGPE"
"UNYKWLFYQPMRYXDVGWWMOLXHCHQADSYAAQMLBGGNQELFWMYHPWNIDOIFLGHGQUPCVPHS"
"WDGERQMWOZBWFHTOSINKTPXQLFGHLVALHCYSPKFBWSYTUHMZQNZSDAQTAZLPHSYZKROA"
"PSKJEWCRABAGYIIAYAUOVMTYIQOWYWHLLEXOOVZNLXOIPFNRYHDJYVTJLOHODYRBBBSB"
"NPQCNUZHYTWDAQSEBEMDSEDTKORHUCILESZYYYLJNRCFHAWNUMQHDQKXGCJIZOGBDVTU"
"PWNKAHKIRBHINKVRRBOPVAWCSPVMTNQQYDYLCKHPKRFYCAYUPGAOQLJSTHGMCXUUQIVI"
"MNPISKLETFEWNDDTDHLCQXNGRJJZHGJYYWNXKQIWXENKWQAGAXTCTLGWNVXDMMPHYPBQ"
"GWWNCWJWYVBVYOWOEJJPZAZGKJEQHPDBYUQBMOLOIMZXYXFOBNNPMGDCTXLCHBEBHCOS"
"HGKAEBGPLANNUHMOHWHAQEWFJSWPIFTWZNKWHKZYDXDAJODTHPXPIGVFYVDNWEQFKKIC"
"EBMGPSBVTPXODJVAYJAURNSFOCUNJROYEMOELHMIGLFDMJQFVEOSINHIWDUUIPNSBHEC"
"TKUFRERFNYCWSSGCYQWMXOQFCZPCSAVRBMSFZEYDBSWWHYLHIGGIDQJRTLNJOMWQVKES"
"KTFWQIRKJEMAZSMFQQSSTCXKOUZLJJWNYJJKSHPAOTEWEKKABTJDOFRGKVBMJFKFFVSP"
"GPMUCDWAFPHLKKZGEYTQNFJBGJTSATHNVDWRKSMLAJAPHYEJXYEKCTKDFGDILOIRDWLV"
"LAMTOCSMRMXYYHPHYBMKAVDRWYSXVPLZUBPAVUUQDNRCNYPKUSWBTCHJMIHQJNXXXXQX"
"LIUZQDFCTJBHELXALVTAJDFIPIFAKJKCPPPPXAVPTOUTLTIGMBUWOIERHBYOIMWTTXOY"
"KCZKDVRSARRBMSQFZGGSVPVBHKBYXZBITZDBQDBZLQNPVEQTXECOHOJKEXUUIBXSORPF"
"THLTMDDDOYSQZBGMBGZFYAJMHWZOLRUUJAIHOLSCIYGHMRAEIKFLFNLEMHOPKVRTJCMJ"
"DKBKJCMDBPGUGPPZBCXYRLHZUYPMIQOXYOCGKBEHZFHGAAKQINMHUNTSJHPPZGNKFREX"
"HGGFEFDAWMCMIXEDLUPDAXNCTHFDMHJPZOGJILKJXRUQBGXKDXTBZXSPZLZUCNCZZYRU"
"DRUEVXRELACIWMGUIBKEXSYTBIJTJPJJLCIQQBVJGXHPCTSHPASIIAMPATSDCTXZAPCJ"
"ESVMBOTOLKGHVRZSBVOBSAAKRPSAFYNPIDVFUMNMJRGKWOANKHZYCABHWIWUJFLDPSFY"
"SPBXQEFLNEEMIGMWWXYTXNTHRXUZQKXCMBLEHGRBFPSUMGMBJFFWTAEFCLDBOHMNAICE"
"YAZCTBCHKXEIBYUTQEAOVDJVOLTYDJJUCPSXUEPTFZPSJOMQDSSKBAHRIVYHQJFVUQJH"
"HRAQYZLYTOAWWIIPEUPQEBYSKTRETZEDWVALVPISUBTOWJZQLVRWKLLLMWEAZZIGMTRV"
"DXJHBFOTBFYSKQYJSNVKINMYRAMBFMBZUVHEEUWRRCMLAPOKKIODTFIIVTIPTBMVMZIP"
"HKDIQRFOKYTVDLAPPUMYNZBJMZMDDQDTXZWOMAJSJETWLGSAJDNNCODMAMCGADNXJGPP"
"GMPQXTZYICNPVATOCYCCGVSAKGCSGCPVUFGNGJPCRVZQXIDIZYCEBNMLMYHUMJZNHGCZ"
"TIYTNXTCGMGSBGLIDHYABMLEBGAHLOEYVOAMROXQAFDNEIZAOFWDETNEZWJFHTYOEVDH"
"RZDIZNSNBDCERUYZRLFWAANFAETBEWWPNNMUYXVBVDKMWPJUZLEPXOJAZOAYNKZDTBJO"
"MKXEMIAGHIQIHXPZGWDEQJKBNTDIWPLDANSOQJTGVPPSROOXGEBBWKLXMUEKZBKTTQTN"
"HILWSXGGYZZFYPGDVMNGLGGBSZJYWXGVHAACMVKQLPYXWWJMOQJJCXQOUIRCXPYCITBW"
"WCOKSSDXXWHHSOPANMWVIKJFLYNBPQAUHWKZEQBDVWDDULWFVBXUBJVOMHNAELALFGZT"
"FHSVLXJTMSOAKGBXKHKDEKVVFRZPKLTRRKCREVPXQYEVGIHAUNEJDLWERMKWJJBONLPW"
"BNTDWFILGFYOOAPNXVBDGGYDCZWUSJLPLZRVYAVSQFEXRZACHLLGGDEJGURDPYFCQUCX"
"OTNJJUJMMBEYSKJPKBGMQAAWOSPYAWDPJEQRLDJVZMRCYSKBAOQYWTJXSRRRMSFGNFRX"
"VEWFGPXVPZQXGRGOLKIYCCAOAGCZSHGPEGVMWETUWVZXZKCJVGQNEJBICWINFFHIUSUE"
"SVKYPVAOKBQEMQNKAXHFDETVNNFPQAXQXFJSKJCFLAHNRQUQPXYELGDYJDEETNEYGTMQ"
"MYIGQUDGOUMZDQORHNVDXBCJYBFTCDEMATBUCGAEKONTAIRCOHHKJFORZVDQSOWKDLKU"
"UOTTLLKQHVKVYOLJWNRRWXEOJMDZIKPMZFBBJCQSVTMCFFZDCWLRQDKAOKEXFVDZCPHE"
"UGNBVSILDBRPBJKNZXIWTNOZEDDESKOGYFOWPZJBQIQXKQERGWTJCUXGTOHLAOWDLGPF"
"RHVNLXVTKDDCWWZUAXKJZKPMOZCZCYVOIRCJNIJAMFRPAWNKFYAGKHNEPKPFTTRXXGTN"
"XFHFJXQWMKDSODYMNWJIFQZJOCYHUKYNYKXSLJNMBKCUXETKQTSZAXZUEERRGNBFDXJW"
"IKSVAVDNXLHJXVNDGLFZNZYTMJPDDXCOPGEROKJOGHXLDZJTSWOXIVCJKLYYTKANVFIF"
"KRVVEXSZXREAOBPVQRZUQKIWNMPTFUWARTQJCDTPEOVDHTDCWAWTTMNLRTOPYGPBROQA"
"QSMTGDCATMYQDJZQAUBQPOZLXDIJCKEVXDTPDNCHNJXMHNRVLWLKSAUYTHVOIYAAHUCY"
"XUWPHXMFXBDNBSNZIVKZANBYCHTUDOLHVVXGFDRDOIRCCRTZRNPWFTHSQRYTLGETDTGZ"
"KQWQPZYUTFFVFRQCAJAFDJAUMHPRXGUTLMFKOGXQHGOACGELSACTSNJTSOGNJAODFCIB"
"EQGGZETTRWOLAPRYJIGCYSUIMDCRHRGBKJFPDXVGPSPGDMBOLAVARRJSNDMZIOPKTAMA"
"NRZOSWGMPBPDBPCUADFMIEWOEBNNDFHUJCFMWXAFDKSWUTMMSQZSFBOGSSKOITDUGLLA"
"NFCZSGCDFDWUDTBPFKMHROQMIQRLCNGGCSFTNCVXSJJGPUZQREUASWLVOFVHRZPQUYGE"
"TBCJUSBKOJVBDWDEGXWBJPFTBFEALLVFFREQSGIONNYQFBFNKENZKSWLEWGEJJPZLRPV"
"RLDHLELHFXXIEXDJOSAUGITKSWYCPMEBLWOLAEJXXARMXQCBEFKLOOIYRBYVWLNZKNCA"
"ISOZEWVWPUDRGLYYKWWTNCWPZLYYDBKARCATEJHLYYQFNYATGYJIUNMVLEGUYBJVEVVM"
"WBVJYQEGPZUOJYLWNEMODVPHTWTLURFETDHELDHPGEQWLRKZRFCEORRGYSBIJHPVNSNZ"
"CAVXFCESMJIXGJPGLKDREKYGBPQSACESXAAHVQYFBSYWDPHDNTOZTEGSCISTBUMLDOQP"
"WNQCSJUAENKYFCYIYENHTIAARBRTOCYDVMHPCPRGWQVDIFLHWMZWRGCWQTAIKCAJAMLG"
"OKGURQTGNNUSCBKTPUXIGKDUWUGMTLCAOTKMXVTAEYWNWBTIQMLVDIEVBAGJMCWMMGZI"
"USESSUIHYSYOXHFLNZVTCVATIUVWGDETJUEHTVQBJDGHIIDFYHTFDIDPLNGXLIBMKAYG"
"DOZLOFKQXVWSQPRYUKAMGEICLKOMYNLWEMKLWDOPEEZGTXVDQWMULORFGNLKNVVCGQXQ"
"CUIYKIAMJSJVQJKRBNBIEELCZLMPQILCEBLZZTKCPBOQLTMZRGTNWHPIUYWMBCNGIABH"
"WIAILEDQVNWKJGYWMZYWOZGRHQOUFGCAETYUTLYZBCHKANZYPXTLMVREDIWBPAISSWKP"
"IJIBRLWPFXQOLOFIXLUGDVMXNPJWBMMZYJUKUZPPTGVCRIMITUTPYLJOIDQGOMYUFSJB"
"MRAZFVZSFZUSNJYDWBUDMFTFDBRCZCZZERWZSOXVAZISSEOMPKHESJRLUMZBBLBIXPZR"
"UYRFMLZQMMZWMNXULVXZQPOUKPMXISKOPTEDXASVPAIENMUWMBNGIVWVOQQXKGYEAMAT"
"YLDPYAASJSACUYILVJBXLHEMYKRKXEIVCDWKPQUBHACBNBGVTQLFDFPLAGUWUPBNBSIT"
"UEENOTZFWDWNNYZTHJIBDYMCERWQNSDKDDUPPXPJTGDYQTFNSRQZZSZBYGSQHRRGSVAQ"
"QEICLCSLMWQYXGGJEPJWZXKJUCFHJRACHRHLCRQWKXSUFJNBOMGWAIBKNWUDBJTFWVBW"
"UPIUAKBMXXDVVKBEUAEHMOELYCJVEFJEDFBTITDNTEGRAIOACOHFCVERCTRMUZHPRNPQ"
"YCFDKGTRGWFEJAXVTTBMIAYLJZEJAAEOBCTIXHYNDWPXIWOVGXSOLTXIBPBLHYKHIDGX"
"HHXNVRCMUXBZGFIEDZDBZOKSMKRNYTWJGJBIMQIOZQRFROWMLNYPDDKTRESDVHHJNRMN"
"GASH";
int main(void)
{
kern_logf("Test 1");
kern_logf("Test 2");
kern_logf("Test 3");
const char *text = "Hello, world!";
char s2[32];
snprintf(s2, sizeof s2, "%s", text);
size_t v = strlen(s);
kern_logf("%s, %zu", s2, v);
return 0;
}

12
runlevel/CMakeLists.txt Normal file
View File

@@ -0,0 +1,12 @@
file(GLOB runlevels *.runlevel)
foreach (f ${runlevels})
get_filename_component(name ${f} NAME_WLE)
bsp_add_file(
ID runlevel-${name}
SRC_PATH ${f}
DEST_DIR /etc/herdd/runlevels)
sysroot_add_file(
ID runlevel-${name}
SRC_PATH ${f}
DEST_DIR /etc/herdd/runlevels)
endforeach (f)

View File

@@ -0,0 +1,3 @@
[Runlevel]
Description=Minimal
Requires=nsd

View File

View File

@@ -0,0 +1,10 @@
file(GLOB sources *.c)
add_executable(herdd ${sources})
target_link_libraries(herdd libc libc-runtime libmango libpthread)
sysroot_add_program(
NAME herdd
BIN_DIR /usr/bin)
bsp_add_program(
NAME herdd
BIN_DIR /usr/bin)

67
services/herdd/main.c Normal file
View File

@@ -0,0 +1,67 @@
#include <errno.h>
#include <mango/log.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/remote.h>
#include <sys/types.h>
#include <unistd.h>
static void *thread_func(void *arg)
{
kern_logf("started thread with arg %p", arg);
errno = 100;
return (void *)0xdeadbeef;
}
int main(int argc, const char *argv[], const char *envp[])
{
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
kern_logf("herdd");
kern_logf("args:");
for (int i = 0; i < argc; i++) {
kern_logf("[%d]: %s", i, argv[i]);
}
kern_logf("env:");
for (int i = 0; envp[i]; i++) {
kern_logf("[%d]: %s", i, envp[i]);
}
kern_logf("self = %p", pthread_self());
errno = 200;
#if 1
int dir = open("/", 0);
if (dir >= 0) {
kern_logf("opened '/'");
char buf[4096] = {0};
struct dentry *dent = (struct dentry *)buf;
long len = getdents(dir, dent, sizeof buf);
if (len < 0) {
kern_logf("getdents failed (%s)", strerror(errno));
} else {
for (long i = 0; i < len;) {
dent = (struct dentry *)(buf + i);
kern_logf(" - %s", dent->d_name);
i += dent->d_reclen;
}
}
close(dir);
} else {
kern_logf("open() failed: %s", strerror(errno));
}
#endif
pthread_t thread;
pthread_create(&thread, NULL, thread_func, (void *)0xdeafcafe);
kern_logf("started thread %p", thread);
void *ret = NULL;
pthread_join(thread, &ret);
kern_logf("thread returned %p", ret);
return 0;
}

View File

14
services/herdd/runlevel.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef RUNLEVEL_H_
#define RUNLEVEL_H_
#include <stddef.h>
#define RUNLEVEL_DESCRIPTION_MAX 64
struct runlevel {
char rl_description[RUNLEVEL_DESCRIPTION_MAX];
char **rl_requires;
size_t rl_requires_count;
};
#endif

0
services/herdd/service.c Normal file
View File

17
services/herdd/service.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef SERVICE_H_
#define SERVICE_H_
#define SVC_DESCRIPTION_MAX 64
enum service_role {
SVC_ROLE_NONE = 0x00u,
SVC_ROLE_NAMESPACE_PROVIDER = 0x01u,
};
struct service {
char s_description[SVC_DESCRIPTION_MAX];
enum service_role s_roles;
char *s_exec;
};
#endif

View File

@@ -1,10 +0,0 @@
file(GLOB sources *.c)
add_executable(ldd ${sources})
target_link_libraries(ldd libc-core libc-runtime libmango)
sysroot_add_program(
NAME ldd
BIN_DIR /usr/bin)
bsp_add_program(
NAME ldd
BIN_DIR /usr/bin)

View File

@@ -0,0 +1,15 @@
file(GLOB sources *.c)
rosetta_add_service(
NAME nsd
SOURCES ${sources}
CFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/nsd.service)
target_link_libraries(nsd libc libc-runtime)
sysroot_add_service(
NAME nsd
BIN_DIR /usr/bin
SVC_DIR /etc/herdd/services)
bsp_add_service(
NAME nsd
BIN_DIR /usr/bin
SVC_DIR /etc/herdd/services)

6
services/nsd/nsd.service Normal file
View File

@@ -0,0 +1,6 @@
[Unit]
Description=Namespace Service
[Service]
Exec=/usr/bin/nsd
Role=NamespaceProvider

View File

@@ -1,12 +1,14 @@
file(GLOB c_sources *.c *.h) file(GLOB c_sources *.c *.h)
file(GLOB arch_sources arch/${CMAKE_SYSTEM_PROCESSOR}/*.S) file(GLOB arch_sources arch/${CMAKE_SYSTEM_PROCESSOR}/*.S)
set_property(SOURCE ${arch_sources} PROPERTY LANGUAGE C)
add_executable(bootstrap ${c_sources} ${arch_sources}) add_executable(bootstrap ${c_sources} ${arch_sources})
target_link_libraries(bootstrap target_link_libraries(bootstrap
libmango libc-core libc-malloc libc-pthread libfs-static liblaunch libxpc-static libmango librosetta
libc-core libc-malloc libc-pthread
libfs-static
liblaunch
libxpc-static
interface::fs) interface::fs)
target_compile_options(bootstrap PRIVATE target_compile_options(bootstrap PRIVATE

View File

@@ -18,7 +18,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#define INIT_PATH "/usr/bin/systemd" #define INIT_PATH "/usr/bin/herdd"
static enum launch_status resolve_dependency( static enum launch_status resolve_dependency(
struct launch_ctx *ctx, struct launch_ctx *ctx,
@@ -203,31 +203,6 @@ int main(
while (1) { while (1) {
fs_context_handle_request(fs); fs_context_handle_request(fs);
#if 0
xpc_msg_t msg;
kern_status_t status = xpc_msg_recv(channel, &msg);
if (status != KERN_OK) {
kern_logf("message recv error %d", status);
continue;
}
switch (msg.msg_header.hdr_interface) {
case INTERFACE_FS:
status = fs_context_dispatch_msg(fs, &msg);
break;
default:
kern_logf(
"unknown message protocol %u",
msg.msg_header.hdr_interface);
xpc_msg_reply_error(&msg, KERN_UNSUPPORTED);
break;
}
if (status != KERN_OK) {
kern_logf("message reply error %d", status);
continue;
}
#endif
} }
return 0; return 0;

View File

@@ -11,6 +11,7 @@
#include <mango/vm.h> #include <mango/vm.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h>
#include <xpc/buffer.h> #include <xpc/buffer.h>
struct tar_superblock { struct tar_superblock {
@@ -148,6 +149,24 @@ static struct tar_entry *entry_get_child(
return NULL; return NULL;
} }
static struct tar_entry *entry_get_child_at(struct tar_entry *entry, size_t at)
{
struct queue_entry *cur = queue_first(&entry->e_children);
while (cur) {
struct tar_entry *child
= QUEUE_CONTAINER(struct tar_entry, e_entry, cur);
if (at == 0) {
return child;
}
at--;
cur = queue_next(cur);
}
return NULL;
}
static const struct fs_dentry_ops dentry_ops = {}; static const struct fs_dentry_ops dentry_ops = {};
static enum fs_status dir_lookup( static enum fs_status dir_lookup(
@@ -189,7 +208,7 @@ static enum fs_status file_read(
char *src = (char *)entry->e_data + offset; char *src = (char *)entry->e_data + offset;
size_t w; size_t w;
xpc_buffer_write(buf, src, count, &w); xpc_buffer_write(buf, 0, src, count, &w);
offset += w; offset += w;
*seek = offset; *seek = offset;
@@ -197,10 +216,66 @@ static enum fs_status file_read(
return FS_SUCCESS; return FS_SUCCESS;
} }
static enum fs_status dir_readdir(
struct fs_file *f,
xpc_buffer_t *out,
off_t *seek)
{
off_t offset = *seek;
struct tar_entry *entry = entry_from_inode(fs_file_get_inode(f));
if (!entry) {
return FS_ERR_BAD_STATE;
}
size_t bytes_written = 0;
size_t available = xpc_buffer_capacity(out);
while (1) {
struct tar_entry *child = entry_get_child_at(entry, offset);
if (!child) {
break;
}
struct dentry dent = {0};
size_t name_len = strlen(child->e_dentry.d_name);
size_t to_write
= offsetof(struct dentry, d_name) + name_len + 1;
if (to_write > available) {
break;
}
dent.d_reclen = to_write;
kern_iovec_t iov[] = {
IOVEC(&dent, offsetof(struct dentry, d_name)),
IOVEC(child->e_dentry.d_name, name_len + 1),
};
size_t tmp = 0;
kern_status_t status
= xpc_buffer_writev(out, bytes_written, iov, 2, &tmp);
if (status != KERN_OK) {
break;
}
bytes_written += tmp;
available -= tmp;
offset++;
}
*seek = offset;
out->buf_len = bytes_written;
return FS_SUCCESS;
}
static const struct fs_file_ops file_ops = { static const struct fs_file_ops file_ops = {
.f_read = file_read, .f_read = file_read,
}; };
static const struct fs_file_ops dir_ops = {
.f_readdir = dir_readdir,
};
static const struct fs_inode_ops file_inode_ops = { static const struct fs_inode_ops file_inode_ops = {
.i_lookup = NULL, .i_lookup = NULL,
}; };
@@ -224,6 +299,7 @@ static struct tar_entry *create_dir_entry(
entry->e_inode.i_sb = &sb->sb_base; entry->e_inode.i_sb = &sb->sb_base;
entry->e_inode.i_mode = FS_INODE_DIR; entry->e_inode.i_mode = FS_INODE_DIR;
entry->e_inode.i_ops = &dir_inode_ops; entry->e_inode.i_ops = &dir_inode_ops;
entry->e_inode.i_fops = &dir_ops;
entry->e_dentry.d_sb = &sb->sb_base; entry->e_dentry.d_sb = &sb->sb_base;
entry->e_dentry.d_ops = &dentry_ops; entry->e_dentry.d_ops = &dentry_ops;

View File

@@ -1,8 +1,6 @@
file(GLOB c_sources *.c *.h) file(GLOB c_sources *.c *.h)
file(GLOB arch_sources arch/${CMAKE_SYSTEM_PROCESSOR}/*.S) file(GLOB arch_sources arch/${CMAKE_SYSTEM_PROCESSOR}/*.S)
set_property(SOURCE ${arch_sources} PROPERTY LANGUAGE C)
add_executable(ld ${c_sources} ${arch_sources}) add_executable(ld ${c_sources} ${arch_sources})
set_target_properties(ld PROPERTIES set_target_properties(ld PROPERTIES
POSITION_INDEPENDENT_CODE ON POSITION_INDEPENDENT_CODE ON

View File

@@ -12,8 +12,6 @@ _dl_runtime_resolve:
pop %rax pop %rax
pop %r11 pop %r11
push %rsp
push %rbp
push %rdi push %rdi
push %rsi push %rsi
push %rdx push %rdx
@@ -41,7 +39,5 @@ _dl_runtime_resolve:
pop %rdx pop %rdx
pop %rsi pop %rsi
pop %rdi pop %rdi
pop %rbp
pop %rsp
jmp *%rax jmp *%rax

View File

@@ -1,5 +1,7 @@
#include "elf.h" #include "elf.h"
#include "image-list.h"
#include "ld.h"
#include "resolve.h" #include "resolve.h"
#include <errno.h> #include <errno.h>
@@ -181,6 +183,7 @@ static int map_image(struct elf_image *image)
} }
} }
kern_logf("ld: image %s -> %zx", image->e_leaf.l_name, image->e_base);
return SUCCESS; return SUCCESS;
} }
@@ -297,7 +300,7 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
rela->r_addend); rela->r_addend);
break; break;
default: default:
kern_log("Unknown relocation type"); kern_trace("Unknown relocation type");
return ENOEXEC; return ENOEXEC;
} }
@@ -644,7 +647,7 @@ int elf_image_link(struct elf_image *img)
return SUCCESS; return SUCCESS;
} }
extern int elf_image_collect_dependencies( int elf_image_collect_dependencies(
struct elf_image *img, struct elf_image *img,
struct image_list *dest) struct image_list *dest)
{ {
@@ -652,6 +655,7 @@ extern int elf_image_collect_dependencies(
return SUCCESS; return SUCCESS;
} }
kern_tracef("collecting dependencies for %s", img->e_leaf.l_name);
int nr_added = 0; int nr_added = 0;
img->e_links = calloc(img->e_nr_links, sizeof(struct elf_image *)); img->e_links = calloc(img->e_nr_links, sizeof(struct elf_image *));
@@ -663,24 +667,45 @@ extern int elf_image_collect_dependencies(
const char *name = (const char *)img->e_base + img->e_strtab const char *name = (const char *)img->e_base + img->e_strtab
+ img->e_dyn[i].d_un.d_val; + img->e_dyn[i].d_un.d_val;
if (image_list_get(dest, name)) {
continue;
}
struct elf_image *dep = NULL; struct elf_image *dep = NULL;
struct image_list_leaf *leaf = NULL;
if ((leaf = image_list_get(dest, name))) {
dep = QUEUE_CONTAINER(struct elf_image, e_leaf, leaf);
} else {
int status = create_image_with_name(name, &dep); int status = create_image_with_name(name, &dep);
if (status != SUCCESS) { if (status != SUCCESS) {
return -status; return -status;
} }
image_list_put(dest, &dep->e_leaf); image_list_put(dest, &dep->e_leaf);
}
img->e_links[nr_added] = dep; img->e_links[nr_added] = dep;
kern_tracef(
"%s dependency %u = %s",
img->e_leaf.l_name,
nr_added,
dep->e_leaf.l_name);
nr_added++; nr_added++;
} }
return nr_added; return nr_added;
} }
int elf_image_add_dependency(struct elf_image *img, struct elf_image *dep)
{
struct elf_image **deps = realloc(
img->e_links,
sizeof(struct elf_image *) * img->e_nr_links + 1);
if (!deps) {
return ENOMEM;
}
deps[img->e_nr_links++] = dep;
img->e_links = deps;
return SUCCESS;
}
void elf_image_close(struct elf_image *image) void elf_image_close(struct elf_image *image)
{ {
if (image->e_fd) { if (image->e_fd) {
@@ -714,7 +739,7 @@ static uint32_t gnu_hash(const char *name)
return h; return h;
} }
static virt_addr_t find_symbol_stdhash( static const elf_sym_t *find_symbol_stdhash(
struct elf_image *img, struct elf_image *img,
const char *name, const char *name,
uint32_t hash) uint32_t hash)
@@ -733,15 +758,22 @@ static virt_addr_t find_symbol_stdhash(
const uint32_t *chain = &bucket[nbucket]; const uint32_t *chain = &bucket[nbucket];
for (uint32_t i = bucket[hash % nbucket]; i; i = chain[i]) { for (uint32_t i = bucket[hash % nbucket]; i; i = chain[i]) {
if (strcmp(name, strtab + symtab[i].st_name) == 0) { const elf_sym_t *sym = &symtab[i];
return img->e_base + symtab[i].st_value; if (strcmp(name, strtab + sym->st_name) != 0) {
continue;
} }
if (!sym->st_value) {
continue;
}
return sym;
} }
return 0; return 0;
} }
static virt_addr_t find_symbol_gnuhash( static const elf_sym_t *find_symbol_gnuhash(
struct elf_image *img, struct elf_image *img,
const char *name, const char *name,
uint32_t hash) uint32_t hash)
@@ -749,12 +781,14 @@ static virt_addr_t find_symbol_gnuhash(
return 0; return 0;
} }
static virt_addr_t find_symbol_slow(struct elf_image *img, const char *name) static const elf_sym_t *find_symbol_slow(
struct elf_image *img,
const char *name)
{ {
return 0; return 0;
} }
static virt_addr_t find_symbol( static const elf_sym_t *find_symbol(
struct elf_image *img, struct elf_image *img,
const char *name, const char *name,
uint32_t std_hash, uint32_t std_hash,
@@ -770,31 +804,144 @@ static virt_addr_t find_symbol(
} }
} }
virt_addr_t elf_image_find_symbol(struct elf_image *img, const char *name) int elf_image_find_symbol(
struct elf_image *img,
const char *name,
struct elf_symbol *out)
{ {
uint32_t std_hash_val = std_hash(name); uint32_t std_hash_val = std_hash(name);
uint32_t gnu_hash_val = gnu_hash(name); uint32_t gnu_hash_val = gnu_hash(name);
return find_symbol(img, name, std_hash_val, gnu_hash_val); const elf_sym_t *sym
= find_symbol(img, name, std_hash_val, gnu_hash_val);
if (sym) {
out->sym_container = img;
out->sym_info = sym;
return SUCCESS;
}
return ENOENT;
} }
virt_addr_t elf_image_find_linked_symbol( int elf_image_find_linked_symbol(
struct elf_image *img, struct elf_image *img,
const char *name) const char *name,
struct elf_symbol *out)
{ {
uint32_t std_hash_val = std_hash(name); uint32_t std_hash_val = std_hash(name);
uint32_t gnu_hash_val = gnu_hash(name); uint32_t gnu_hash_val = gnu_hash(name);
virt_addr_t sym = 0; struct elf_image *candidate_container = NULL;
const elf_sym_t *candidate = NULL;
const elf_sym_t *sym = NULL;
kern_tracef("searching %p (%zx)", img, img->e_base);
sym = find_symbol(img, name, std_hash_val, gnu_hash_val);
if (sym) {
if (ELF64_ST_BIND(sym->st_info) == STB_WEAK) {
kern_tracef(
"found %s:%s (weak): %zx",
img->e_leaf.l_name,
name,
sym->st_value);
candidate = sym;
candidate_container = img;
} else {
kern_tracef(
"found %s:%s (strong): %zx",
img->e_leaf.l_name,
name,
sym->st_value);
out->sym_container = img;
out->sym_info = sym;
return SUCCESS;
}
}
for (size_t i = 0; i < img->e_nr_links; i++) { for (size_t i = 0; i < img->e_nr_links; i++) {
kern_tracef(
"searching %p (%zx)",
img->e_links[i],
img->e_links[i]->e_base);
sym = find_symbol( sym = find_symbol(
img->e_links[i], img->e_links[i],
name, name,
std_hash_val, std_hash_val,
gnu_hash_val); gnu_hash_val);
if (sym) { if (!sym) {
break; continue;
}
if (ELF64_ST_BIND(sym->st_info) == STB_WEAK) {
kern_tracef(
"found %s:%s (weak): %zx",
img->e_links[i]->e_leaf.l_name,
name,
sym->st_value);
candidate = sym;
candidate_container = img->e_links[i];
} else {
kern_tracef(
"found %s:%s (strong): %zx",
img->e_links[i]->e_leaf.l_name,
name,
sym->st_value);
out->sym_container = img;
out->sym_info = sym;
return SUCCESS;
} }
} }
return sym; if (candidate) {
out->sym_container = candidate_container;
out->sym_info = candidate;
return SUCCESS;
}
return ENOENT;
}
virt_addr_t find_global_symbol(const char *name)
{
struct image_list *images = global_image_list();
if (!images) {
return 0;
}
struct image_list_iterator it;
image_list_iterator_begin(&it, images);
virt_addr_t candidate = 0;
struct elf_symbol sym = {0};
while (it.it_leaf) {
struct elf_image *image
= QUEUE_CONTAINER(struct elf_image, e_leaf, it.it_leaf);
int status = elf_image_find_symbol(image, name, &sym);
if (status == ENOENT) {
image_list_iterator_move_next(&it);
continue;
}
if (ELF64_ST_BIND(sym.sym_info->st_info) == STB_WEAK) {
kern_tracef(
"found %s:%s (weak): %zx",
sym.sym_container->e_leaf.l_name,
name,
sym.sym_info->st_value);
candidate = (virt_addr_t)sym.sym_container->e_base
+ sym.sym_info->st_value;
} else {
kern_tracef(
"found %s:%s (strong): %zx",
sym.sym_container->e_leaf.l_name,
name,
sym.sym_info->st_value);
return (virt_addr_t)sym.sym_container->e_base
+ sym.sym_info->st_value;
}
image_list_iterator_move_next(&it);
}
return candidate;
} }

View File

@@ -344,6 +344,11 @@ struct elf_image {
size_t e_nr_links; size_t e_nr_links;
}; };
struct elf_symbol {
struct elf_image *sym_container;
const elf_sym_t *sym_info;
};
extern const char *elf_image_status_to_string(enum elf_image_status status); extern const char *elf_image_status_to_string(enum elf_image_status status);
extern int elf_image_open(const char *path, struct elf_image **out); extern int elf_image_open(const char *path, struct elf_image **out);
@@ -352,14 +357,25 @@ extern int elf_image_load(struct elf_image *img);
extern int elf_image_collect_dependencies( extern int elf_image_collect_dependencies(
struct elf_image *img, struct elf_image *img,
struct image_list *dest); struct image_list *dest);
extern int elf_image_add_dependency(
struct elf_image *img,
struct elf_image *dep);
extern int elf_image_link(struct elf_image *img); extern int elf_image_link(struct elf_image *img);
extern void elf_image_close(struct elf_image *img); extern void elf_image_close(struct elf_image *img);
extern virt_addr_t elf_image_find_symbol( extern int elf_image_find_symbol(
struct elf_image *img, struct elf_image *img,
const char *name); const char *name,
extern virt_addr_t elf_image_find_linked_symbol( struct elf_symbol *out);
extern int elf_image_find_symbol(
struct elf_image *img, struct elf_image *img,
const char *name); const char *name,
struct elf_symbol *out);
extern int elf_image_find_linked_symbol(
struct elf_image *img,
const char *name,
struct elf_symbol *out);
extern virt_addr_t find_global_symbol(const char *name);
#endif #endif

8
sys/ld/ld.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef LD_H_
#define LD_H_
struct image_list;
extern struct image_list *global_image_list(void);
#endif

View File

@@ -27,6 +27,13 @@ static const char *search_paths[] = {
static const size_t nr_search_paths static const size_t nr_search_paths
= sizeof search_paths / sizeof search_paths[0]; = sizeof search_paths / sizeof search_paths[0];
static struct image_list images = {0};
struct image_list *global_image_list(void)
{
return &images;
}
static void report_error(const char *name, int err, const char *msg, ...) static void report_error(const char *name, int err, const char *msg, ...)
{ {
char buf[1024]; char buf[1024];
@@ -35,7 +42,7 @@ static void report_error(const char *name, int err, const char *msg, ...)
vsnprintf(buf, sizeof buf, msg, arg); vsnprintf(buf, sizeof buf, msg, arg);
va_end(arg); va_end(arg);
kern_tracef("%s: %s: %s", name, buf, strerror(err)); kern_logf("%s: %s: %s", name, buf, strerror(err));
} }
static const char *get_image_name(const char *path) static const char *get_image_name(const char *path)
@@ -71,7 +78,7 @@ static int find_image(struct elf_image *img)
return ENOENT; return ENOENT;
} }
static int load_images(struct image_list *list) static int load_images(const char *task_name, struct image_list *list)
{ {
int status = SUCCESS; int status = SUCCESS;
struct image_list_iterator it; struct image_list_iterator it;
@@ -91,18 +98,33 @@ static int load_images(struct image_list *list)
/* Find the image using its name */ /* Find the image using its name */
status = find_image(image); status = find_image(image);
if (status != SUCCESS) { if (status != SUCCESS) {
report_error(
task_name,
status,
"error while loading %s",
image->e_leaf.l_name);
return status; return status;
} }
case ELF_IMAGE_OPEN: case ELF_IMAGE_OPEN:
/* parse the image */ /* parse the image */
status = elf_image_parse(image); status = elf_image_parse(image);
if (status != SUCCESS) { if (status != SUCCESS) {
report_error(
task_name,
status,
"error while loading %s",
image->e_leaf.l_name);
return status; return status;
} }
case ELF_IMAGE_PARSED: case ELF_IMAGE_PARSED:
/* load the image */ /* load the image */
status = elf_image_load(image); status = elf_image_load(image);
if (status != SUCCESS) { if (status != SUCCESS) {
report_error(
task_name,
status,
"error while loading %s",
image->e_leaf.l_name);
return status; return status;
} }
case ELF_IMAGE_LOADED: case ELF_IMAGE_LOADED:
@@ -114,6 +136,11 @@ static int load_images(struct image_list *list)
} }
if (new_dependencies < 0) { if (new_dependencies < 0) {
report_error(
task_name,
-new_dependencies,
"error while loading %s",
image->e_leaf.l_name);
return -new_dependencies; return -new_dependencies;
} }
@@ -127,7 +154,7 @@ static int load_images(struct image_list *list)
return SUCCESS; return SUCCESS;
} }
static int link_images(struct image_list *list) static int link_images(const char *task_name, struct image_list *list)
{ {
int status = SUCCESS; int status = SUCCESS;
struct image_list_iterator it; struct image_list_iterator it;
@@ -143,6 +170,14 @@ static int link_images(struct image_list *list)
elf_image_status_to_string(image->e_status)); elf_image_status_to_string(image->e_status));
status = elf_image_link(image); status = elf_image_link(image);
if (status != SUCCESS) {
report_error(
task_name,
status,
"error while loading %s",
image->e_leaf.l_name);
return status;
}
image_list_iterator_move_next(&it); image_list_iterator_move_next(&it);
} }
@@ -162,7 +197,6 @@ int main(const struct rosetta_bootstrap *bs)
const char *task_name = bs->bs_argv[2]; const char *task_name = bs->bs_argv[2];
const char *image_name = get_image_name(exec_path); const char *image_name = get_image_name(exec_path);
struct image_list images;
image_list_init(&images); image_list_init(&images);
struct elf_image *exec = NULL; struct elf_image *exec = NULL;
@@ -183,23 +217,13 @@ int main(const struct rosetta_bootstrap *bs)
image_name); image_name);
image_list_put(&images, &exec->e_leaf); image_list_put(&images, &exec->e_leaf);
err = load_images(&images); err = load_images(task_name, &images);
if (err != SUCCESS) { if (err != SUCCESS) {
report_error(
task_name,
err,
"error while loading %s",
exec_path);
return -1; return -1;
} }
err = link_images(&images); err = link_images(task_name, &images);
if (err != SUCCESS) { if (err != SUCCESS) {
report_error(
task_name,
err,
"error while loading %s",
exec_path);
return -1; return -1;
} }
@@ -218,7 +242,12 @@ int main(const struct rosetta_bootstrap *bs)
} }
kern_tracef("ld finished"); kern_tracef("ld finished");
int (*entry)(int, const char **) struct rosetta_bootstrap exec_bsinfo;
= (int (*)(int, const char **))exec->e_entry; memcpy(&exec_bsinfo, bs, sizeof exec_bsinfo);
return entry(bs->bs_argc - 2, bs->bs_argv + 2);
exec_bsinfo.bs_argc -= 2;
exec_bsinfo.bs_argv += 2;
int (*entry)(const struct rosetta_bootstrap *)
= (int (*)(const struct rosetta_bootstrap *))exec->e_entry;
return entry(&exec_bsinfo);
} }

View File

@@ -6,17 +6,46 @@
uintptr_t dl_runtime_resolve(struct elf_image *img, unsigned long sym_id) uintptr_t dl_runtime_resolve(struct elf_image *img, unsigned long sym_id)
{ {
unsigned long slot_id = sym_id;
switch (img->e_rel_entsize[ELF_RT_PLTREL]) {
case sizeof(elf_rela_t): {
elf_rela_t *rela
= (elf_rela_t *)((virt_addr_t)img->e_base
+ img->e_rel_offset[ELF_RT_PLTREL]);
elf_rela_t *rela_sym = &rela[sym_id];
kern_tracef(
"rela %u -> .dynsym %u, .got %u",
sym_id,
ELF64_R_SYM(rela_sym->r_info),
slot_id);
sym_id = ELF64_R_SYM(rela_sym->r_info);
/* the first three entries in the GOT are not symbols. */
slot_id += 3;
break;
}
default:
return 0;
}
elf_sym_t *sym elf_sym_t *sym
= (elf_sym_t *)((virt_addr_t)img->e_base + img->e_dynsym); = (elf_sym_t *)((virt_addr_t)img->e_base + img->e_dynsym);
virt_addr_t *got
= (virt_addr_t *)((virt_addr_t)img->e_base + img->e_got_plt);
const char *sym_name = (const char *)img->e_base + img->e_strtab const char *sym_name = (const char *)img->e_base + img->e_strtab
+ sym[sym_id + 1].st_name; + sym[sym_id].st_name;
// kern_logf("%s: request for symbol %s", img->e_leaf.l_name, sym_name); kern_tracef(
"%s: request for symbol %u: %s",
img->e_leaf.l_name,
sym_id,
sym_name);
#if 0
virt_addr_t sym_addr = elf_image_find_linked_symbol(img, sym_name); virt_addr_t sym_addr = elf_image_find_linked_symbol(img, sym_name);
virt_addr_t *sym_slot #else
= (virt_addr_t *)((virt_addr_t)img->e_base + img->e_got_plt virt_addr_t sym_addr = find_global_symbol(sym_name);
+ ((sym_id + 3) * sizeof(virt_addr_t))); #endif
// kern_logf("symbol %s = %zx", sym_name, sym_addr); kern_tracef("symbol %s = %zx", sym_name, sym_addr);
// kern_logf("slot %s = %zx", sym_name, sym_slot); kern_tracef("slot %s = %zx", sym_name, &got[slot_id]);
*sym_slot = sym_addr; got[slot_id] = sym_addr;
return sym_addr; return sym_addr;
} }

View File

@@ -542,6 +542,11 @@ static int emit_interface_msg_function_send_impl(
emit(ctx, ": KERN_HANDLE_INVALID;\n"); emit(ctx, ": KERN_HANDLE_INVALID;\n");
break; break;
case TYPE_BUFFER: case TYPE_BUFFER:
emit(ctx,
"*out_%s_len = msg_data.msg_response.%s_len;\n",
param->p_name,
param->p_name);
break;
case TYPE_STRING: case TYPE_STRING:
break; break;
default: default:
@@ -627,13 +632,17 @@ static int emit_interface_msg_function_send(
break; break;
case TYPE_STRING: case TYPE_STRING:
emit(ctx, emit(ctx,
"char *out_%s,\nsize_t out_%s_max", "char *out_%s,\nsize_t out_%s_max,\nsize_t "
"*out_%s_len",
param->p_name,
param->p_name, param->p_name,
param->p_name); param->p_name);
break; break;
case TYPE_BUFFER: case TYPE_BUFFER:
emit(ctx, emit(ctx,
"void *out_%s,\nsize_t out_%s_max", "void *out_%s,\nsize_t out_%s_max,\nsize_t "
"*out_%s_len",
param->p_name,
param->p_name, param->p_name,
param->p_name); param->p_name);
break; break;
@@ -679,7 +688,7 @@ static int emit_interface_dispatcher_impl_msg(
msg->msg_name); msg->msg_name);
emit(ctx, emit(ctx,
"status = xpc_msg_read(msg, 0, &" MSG_STRUCT_NAME "status = xpc_msg_read(msg, 0, &" MSG_STRUCT_NAME
", sizeof " MSG_STRUCT_NAME ");\n"); ", sizeof " MSG_STRUCT_NAME ", NULL);\n");
fx_queue_entry *entry = fx_queue_first(&msg->msg_params); fx_queue_entry *entry = fx_queue_first(&msg->msg_params);
while (entry) { while (entry) {
@@ -836,6 +845,13 @@ static int emit_interface_dispatcher_impl_msg(
handle_index); handle_index);
handle_index++; handle_index++;
break; break;
case TYPE_BUFFER:
emit(ctx,
MSG_STRUCT_NAME
".msg_response.%s_len = xpc_buffer_length(&%s);\n",
param->p_name,
param->p_name);
break;
default: default:
break; break;
} }