mirror of
https://github.com/wiiu-env/wut.git
synced 2024-12-13 04:22:37 +01:00
Update to support linking with newlib.
This commit is contained in:
parent
cdc07cac23
commit
e04b987390
@ -44,7 +44,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
set(DEVKIT_COMPILE_FLAGS "-fno-builtin -ffreestanding")
|
||||
set(DEVKIT_COMPILE_FLAGS "-mcpu=750 -meabi -mhard-float -msdata")
|
||||
set(DEVKIT_LINKER_FLAGS "-nostartfiles -L${DEVKITPPC}/lib")
|
||||
|
||||
set(RPX_COMPILE_FLAGS "\
|
||||
@ -52,10 +52,8 @@ set(RPX_COMPILE_FLAGS "\
|
||||
|
||||
set(RPX_LINKER_FLAGS "\
|
||||
${DEVKIT_LINKER_FLAGS} \
|
||||
-pie -fPIE -z common-page-size=64 -z max-page-size=64 -T ${WUT_ROOT}/rules/rpl.ld -L${WUT_ROOT}/lib \
|
||||
-Wl,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size \
|
||||
-Wl,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r \
|
||||
-Wl,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,-wrap,__eabi")
|
||||
-pie -fPIE -z common-page-size=64 -z max-page-size=64 -T ${WUT_ROOT}/rules/rpl.ld -L${WUT_ROOT}/lib\
|
||||
-Wl,-wrap,__eabi")
|
||||
|
||||
set(ELF_TO_RPL ${WUT_ROOT}/bin/elf2rpl${CMAKE_EXECUTABLE_SUFFIX})
|
||||
|
||||
@ -70,5 +68,5 @@ macro(add_rpx target)
|
||||
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "${ELF_TO_RPL}" "$<TARGET_FILE:${target}>" "$<TARGET_FILE:${target}>.rpx"
|
||||
COMMENT "Converting elf to rpx")
|
||||
COMMENT "Converting $<TARGET_FILE:${target}> to rpx")
|
||||
endmacro()
|
||||
|
@ -8,9 +8,10 @@ set_property(SOURCE crt0.S PROPERTY LANGUAGE C)
|
||||
add_library(crt
|
||||
crt0.S
|
||||
fs_dev.c
|
||||
memory.c)
|
||||
newlib.c)
|
||||
set_target_properties(crt PROPERTIES
|
||||
COMPILE_FLAGS "-fno-builtin -ffreestanding")
|
||||
COMPILE_FLAGS "-fno-builtin -ffreestanding"
|
||||
LINKER_FLAGS "-fPIC")
|
||||
target_include_directories(crt PRIVATE "../include")
|
||||
|
||||
install(TARGETS crt ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
@ -1,8 +1,11 @@
|
||||
.extern main
|
||||
.extern exit
|
||||
.extern __init_wut_newlibc
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
stwu 1, -0x8(1)
|
||||
bl __init_wut_newlibc
|
||||
stw 3, 0(1)
|
||||
stw 4, 4(1)
|
||||
bl fsDevInit
|
||||
|
102
crt/memory.c
102
crt/memory.c
@ -1,102 +0,0 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <coreinit/baseheap.h>
|
||||
#include <coreinit/memheap.h>
|
||||
#include <coreinit/expandedheap.h>
|
||||
|
||||
void *
|
||||
__wrap_memalign(size_t alignment, size_t size) {
|
||||
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, alignment);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap_malloc(size_t size) {
|
||||
return __wrap_memalign(4, size);
|
||||
}
|
||||
|
||||
void
|
||||
__wrap_free(void *ptr) {
|
||||
if (ptr) {
|
||||
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
__wrap_malloc_usable_size(void *ptr) {
|
||||
return MEMGetSizeForMBlockExpHeap(ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap_realloc(void *ptr, size_t size) {
|
||||
if (!ptr) {
|
||||
return __wrap_malloc(size);
|
||||
}
|
||||
|
||||
if (__wrap_malloc_usable_size(ptr) >= size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *realloc_ptr = __wrap_malloc(size);
|
||||
|
||||
if(!realloc_ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(realloc_ptr, ptr, __wrap_malloc_usable_size(ptr));
|
||||
__wrap_free(ptr);
|
||||
|
||||
return realloc_ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap_calloc(size_t num, size_t size) {
|
||||
void *ptr = __wrap_malloc(num*size);
|
||||
|
||||
if(ptr) {
|
||||
memset(ptr, 0, num*size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap_valloc(size_t size) {
|
||||
return __wrap_memalign(64, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
__wrap__memalign_r(struct _reent *r, size_t alignment, size_t size) {
|
||||
return __wrap_memalign(alignment, size);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap__malloc_r(struct _reent *r, size_t size) {
|
||||
return __wrap_malloc(size);
|
||||
}
|
||||
|
||||
void
|
||||
__wrap__free_r(struct _reent *r, void *ptr) {
|
||||
return __wrap_free(ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap__realloc_r(struct _reent *r, void *ptr, size_t size) {
|
||||
return __wrap_realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap__calloc_r(struct _reent *r, size_t num, size_t size) {
|
||||
return __wrap_calloc(num, size);
|
||||
}
|
||||
|
||||
size_t
|
||||
__wrap__malloc_usable_size_r(struct _reent *r, void *ptr) {
|
||||
return __wrap_malloc_usable_size(ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
__wrap__valloc_r(struct _reent *r, size_t size) {
|
||||
return __wrap_valloc(size);
|
||||
}
|
170
crt/newlib.c
Normal file
170
crt/newlib.c
Normal file
@ -0,0 +1,170 @@
|
||||
#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 = NULL;
|
||||
static volatile uint32_t sHeapSize = NULL;
|
||||
|
||||
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 = NULL;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __libwut_lock_release(int *lock)
|
||||
{
|
||||
OSMutex *mutex = NULL;
|
||||
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();
|
||||
}
|
10
rules/rpl.ld
10
rules/rpl.ld
@ -1,6 +1,7 @@
|
||||
OUTPUT_FORMAT("elf32-powerpc")
|
||||
OUTPUT_ARCH(powerpc:common)
|
||||
|
||||
EXTERN(_start)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
@ -126,7 +127,12 @@ SECTIONS {
|
||||
KEEP (*(.dtors))
|
||||
} : hdr_data
|
||||
|
||||
__bss_start__ = .;
|
||||
.jcr ALIGN(256) :
|
||||
{
|
||||
KEEP (*(.jcr))
|
||||
} : hdr_data
|
||||
|
||||
__bss_start = .;
|
||||
.bss ALIGN(256) :
|
||||
{
|
||||
*(.dynbss)
|
||||
@ -163,7 +169,7 @@ SECTIONS {
|
||||
__tls_end = .;
|
||||
. = ALIGN(32);
|
||||
} : hdr_data
|
||||
__bss_end__ = .;
|
||||
__bss_end = .;
|
||||
|
||||
/* System stuff is for our elf2rpl converter to go through */
|
||||
. = ORIGIN(system);
|
||||
|
Loading…
Reference in New Issue
Block a user