mirror of
https://github.com/wiiu-env/wut.git
synced 2025-01-06 14:48:17 +01:00
Add newlib syscalls.
This commit is contained in:
parent
11adfb8f07
commit
5b8b60b390
@ -9,8 +9,7 @@ Licensed under the terms of the GNU General Public License, version 2 or later (
|
||||
This branch is an WIP experimental rewrite to simplify how elf2rpl works and hopefully make it more correct for more advanced C++ programs.
|
||||
|
||||
## TODO:
|
||||
- Bring back the old tools (readrpl etc)
|
||||
- newlib / devoptab
|
||||
- Maybe add fopen for sdcard ?
|
||||
|
||||
## Linux
|
||||
Requires CMake + Make + [devkitPPC](https://devkitpro.org/wiki/Getting_Started/devkitPPC) + libzdev
|
||||
|
@ -4,3 +4,4 @@ project(libraries C)
|
||||
add_subdirectory(libdefaultheap)
|
||||
add_subdirectory(libgfd)
|
||||
add_subdirectory(libwhb)
|
||||
add_subdirectory(wutnewlib)
|
||||
|
12
libraries/wutnewlib/CMakeLists.txt
Normal file
12
libraries/wutnewlib/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(wutnewlib C)
|
||||
|
||||
set_property(SOURCE crt0.s PROPERTY LANGUAGE C)
|
||||
|
||||
add_library(wutnewlib
|
||||
crt0.s
|
||||
syscalls.c)
|
||||
target_include_directories(wutnewlib PRIVATE "${WUT_ROOT}/include")
|
||||
|
||||
install(TARGETS wutnewlib
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
|
15
libraries/wutnewlib/crt0.s
Normal file
15
libraries/wutnewlib/crt0.s
Normal file
@ -0,0 +1,15 @@
|
||||
.extern main
|
||||
.extern exit
|
||||
.extern __init_wut_newlibc
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
stwu 1, -0x8(1)
|
||||
stw 3, 0(1)
|
||||
stw 4, 4(1)
|
||||
bl __init_wut_newlibc
|
||||
lwz 3, 0(1)
|
||||
lwz 4, 4(1)
|
||||
bl main
|
||||
addi 1, 1, 0x8
|
||||
b exit
|
181
libraries/wutnewlib/syscalls.c
Normal file
181
libraries/wutnewlib/syscalls.c
Normal file
@ -0,0 +1,181 @@
|
||||
#include <wut.h>
|
||||
|
||||
#include <coreinit/atomic.h>
|
||||
#include <coreinit/baseheap.h>
|
||||
#include <coreinit/exit.h>
|
||||
#include <coreinit/expandedheap.h>
|
||||
#include <coreinit/mutex.h>
|
||||
#include <coreinit/time.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <sys/reent.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static OSMutex sMallocMutex;
|
||||
static uint8_t *sHeapBase = NULL;
|
||||
static uint32_t sHeapMaxSize = 0;
|
||||
static volatile uint32_t sHeapSize = 0;
|
||||
|
||||
void
|
||||
__init_wut_newlibc();
|
||||
|
||||
static void *
|
||||
__libwut_sbrk_r(struct _reent *r,
|
||||
ptrdiff_t incr)
|
||||
{
|
||||
uint32_t oldSize, newSize;
|
||||
|
||||
do {
|
||||
oldSize = sHeapSize;
|
||||
newSize = oldSize + incr;
|
||||
|
||||
if (newSize > sHeapMaxSize) {
|
||||
r->_errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
} while (!OSCompareAndSwapAtomic(&sHeapSize, oldSize, newSize));
|
||||
|
||||
return sHeapBase + oldSize;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_init(int *lock,
|
||||
int recursive)
|
||||
{
|
||||
OSMutex *mutex = NULL;
|
||||
if (!lock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex = (OSMutex *)malloc(sizeof(OSMutex));
|
||||
if (!mutex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSInitMutex(mutex);
|
||||
*lock = (int)mutex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_close(int *lock)
|
||||
{
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
free((void *)*lock);
|
||||
*lock = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_acquire(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_release(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSUnlockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_malloc_lock(struct _reent *r)
|
||||
{
|
||||
OSLockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_malloc_unlock(struct _reent *r)
|
||||
{
|
||||
OSUnlockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_exit(int code)
|
||||
{
|
||||
exit(code);
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_gettod_r(struct _reent *ptr,
|
||||
struct timeval *tp,
|
||||
struct timezone *tz)
|
||||
{
|
||||
OSCalendarTime tm;
|
||||
OSTicksToCalendarTime(OSGetTime(), &tm);
|
||||
|
||||
if (tp != NULL) {
|
||||
tp->tv_sec = tm.tm_sec;
|
||||
tp->tv_usec = tm.tm_usec + tm.tm_msec * 1000;
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
tz->tz_minuteswest = 0;
|
||||
tz->tz_dsttime = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__init_malloc_lock()
|
||||
{
|
||||
OSInitMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__init_libc_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
uint32_t freeSize = MEMGetAllocatableSizeForExpHeapEx(heap, 0x1000);
|
||||
|
||||
sHeapMaxSize = (uint32_t)(0.9f * (float)freeSize) & ~0xFFF;
|
||||
sHeapBase = (uint8_t *)MEMAllocFromExpHeapEx(heap, sHeapMaxSize, 0x1000);
|
||||
sHeapSize = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__free_libc_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
MEMFreeToExpHeap(heap, sHeapBase);
|
||||
}
|
||||
|
||||
static void
|
||||
__init_syscall_array()
|
||||
{
|
||||
__syscalls.sbrk_r = __libwut_sbrk_r;
|
||||
__syscalls.lock_init = __libwut_lock_init;
|
||||
__syscalls.lock_close = __libwut_lock_close;
|
||||
__syscalls.lock_acquire = __libwut_lock_acquire;
|
||||
__syscalls.lock_release = __libwut_lock_release;
|
||||
__syscalls.malloc_lock = __libwut_malloc_lock;
|
||||
__syscalls.malloc_unlock = __libwut_malloc_unlock;
|
||||
__syscalls.exit = __libwut_exit;
|
||||
__syscalls.gettod_r = __libwut_gettod_r;
|
||||
}
|
||||
|
||||
void
|
||||
__init_wut_newlibc()
|
||||
{
|
||||
__init_libc_heap();
|
||||
__init_malloc_lock();
|
||||
__init_syscall_array();
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
macro(wut_create_rpx target source)
|
||||
add_custom_target(${target} ALL
|
||||
COMMAND ${WUT_ELF2RPL} ${source} ${target}
|
||||
DEPENDS ${source}
|
||||
COMMENT "Converting to RPX ${target}"
|
||||
)
|
||||
target_link_libraries(${source}
|
||||
wutnewlib
|
||||
coreinit)
|
||||
|
||||
add_custom_target(${target} ALL
|
||||
COMMAND ${WUT_ELF2RPL} ${source} ${target}
|
||||
DEPENDS ${source}
|
||||
COMMENT "Converting to RPX ${target}")
|
||||
|
||||
add_dependencies(${target} ${source})
|
||||
endmacro(wut_create_rpx)
|
||||
|
107
share/wut.ld
107
share/wut.ld
@ -8,8 +8,8 @@ MEMORY {
|
||||
loadmem (rwx) : ORIGIN = 0xC0000000, LENGTH = 128M
|
||||
}
|
||||
|
||||
EXTERN(main)
|
||||
ENTRY(main)
|
||||
EXTERN(_start)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
@ -19,76 +19,135 @@ SECTIONS
|
||||
} > codemem
|
||||
|
||||
.text ALIGN(32) : {
|
||||
*(.text .text.*)
|
||||
*(.init)
|
||||
*(.fini)
|
||||
KEEP (*crt0.o(*.init))
|
||||
KEEP (*(.init))
|
||||
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
KEEP (*(.fini))
|
||||
} > codemem
|
||||
|
||||
. = ORIGIN(datamem);
|
||||
.rodata ALIGN(32) : {
|
||||
*(.rodata .rodata.*)
|
||||
*(.ctors)
|
||||
*(.dtors)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
|
||||
*(.preinit_array)
|
||||
*(.init_array)
|
||||
*(.fini_array)
|
||||
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
|
||||
*(.jcr)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
*(.dynamic)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
KEEP (*(.eh_frame))
|
||||
*(.fixup)
|
||||
*(.gcc_except_table)
|
||||
*(.gcc_except_table.*)
|
||||
*(.got)
|
||||
*(.got1)
|
||||
*(.got2)
|
||||
*(.got.plt)
|
||||
*(.plt)
|
||||
*(.tm_clone_table)
|
||||
} > datamem
|
||||
|
||||
.data ALIGN(32) : {
|
||||
*(.data .data.*)
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
|
||||
. = ALIGN(32);
|
||||
__sdata_start = .;
|
||||
*(.sdata .sdata.*)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
. = ALIGN(32);
|
||||
__sdata_end = .;
|
||||
|
||||
. = ALIGN(32);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2 .sdata2.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
. = ALIGN(32);
|
||||
__sdata2_end = .;
|
||||
} > datamem
|
||||
|
||||
__bss_start = .;
|
||||
.bss ALIGN(64) : {
|
||||
*(.bss .bss.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(64);
|
||||
__sbss_start = .;
|
||||
*(.sbss .sbss.*)
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
__sbss_end = .;
|
||||
|
||||
. = ALIGN(64);
|
||||
__sbss2_start = .;
|
||||
*(.sbss2 .sbss2.*)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
|
||||
|
||||
. = ALIGN(32);
|
||||
}
|
||||
__bss_end = .;
|
||||
|
||||
. = ORIGIN(relmem);
|
||||
.rela.text ALIGN(4) : {
|
||||
*(.rela.text .rela.text.*)
|
||||
*(.rela.text)
|
||||
*(.rela.text.*)
|
||||
*(.rela.gnu.linkonce.t.*)
|
||||
*(.rela.init)
|
||||
*(.rela.fini)
|
||||
} > relmem
|
||||
.rela.data ALIGN(4) : {
|
||||
*(.rela.data .rela.data.*)
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.gnu.linkonce.d.*)
|
||||
*(.rela.sdata)
|
||||
*(.rela.gnu.linkonce.s.*)
|
||||
*(.rela.sdata2)
|
||||
*(.rela.gnu.linkonce.s2.*)
|
||||
*(.rela.init_array)
|
||||
*(.rela.fini_array)
|
||||
*(.rela.gcc_except_table .rela.gcc_except_table.*)
|
||||
*(.rela.eh_frame)
|
||||
*(.rela.got)
|
||||
*(.rela.got1)
|
||||
*(.rela.got2)
|
||||
*(.rela.got.plt)
|
||||
*(.rela.plt)
|
||||
} > relmem
|
||||
.rela.rodata ALIGN(4) : {
|
||||
*(.rela.rodata .rela.rodata.*)
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata.*)
|
||||
*(.rel.gnu.linkonce.r.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
} > relmem
|
||||
|
||||
. = ORIGIN(loadmem);
|
||||
@ -137,9 +196,11 @@ SECTIONS
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2);
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.fixup)
|
||||
*(.gnu.attributes)
|
||||
*(.abs)
|
||||
*(.comment)
|
||||
*(.gnu.attributes)
|
||||
*(.gnu.version)
|
||||
*(.gnu.version_d)
|
||||
*(.gnu.version_r)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user