mirror of
https://github.com/wiiu-env/wut.git
synced 2024-12-05 03:24:17 +01:00
Adjustments for linking, rpx/rpl generation
This commit is contained in:
parent
2c69f7d9be
commit
9173f0f6c3
@ -5,6 +5,10 @@ _start:
|
||||
bl main
|
||||
b exit
|
||||
|
||||
.global __eabi
|
||||
__eabi:
|
||||
.global __wrap___eabi
|
||||
__wrap___eabi:
|
||||
blr
|
||||
|
||||
.global __init
|
||||
__init:
|
||||
blr
|
||||
|
103
crt/memory.c
Normal file
103
crt/memory.c
Normal file
@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2015 Dimok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <coreinit/baseheap.h>
|
||||
#include <coreinit/expandedheap.h>
|
||||
|
||||
//!-------------------------------------------------------------------------------------------
|
||||
//! wraps
|
||||
//!-------------------------------------------------------------------------------------------
|
||||
void *__wrap_malloc(size_t size)
|
||||
{
|
||||
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, 4);
|
||||
}
|
||||
|
||||
void *__wrap_memalign(size_t align, size_t size)
|
||||
{
|
||||
if (align < 4)
|
||||
align = 4;
|
||||
|
||||
// pointer to a function resolve
|
||||
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, align);
|
||||
}
|
||||
|
||||
void __wrap_free(void *p)
|
||||
{
|
||||
// pointer to a function resolve
|
||||
if(p != 0)
|
||||
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), p);
|
||||
}
|
||||
|
||||
void *__wrap_calloc(size_t n, size_t size)
|
||||
{
|
||||
void *p = __wrap_malloc(n * size);
|
||||
if (p != 0) {
|
||||
memset(p, 0, n * size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t __wrap_malloc_usable_size(void *p)
|
||||
{
|
||||
//! TODO: this is totally wrong and needs to be addressed
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
void *__wrap_realloc(void *p, size_t size)
|
||||
{
|
||||
void *new_ptr = __wrap_malloc(size);
|
||||
if (new_ptr != 0)
|
||||
{
|
||||
memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size);
|
||||
__wrap_free(p);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
//!-------------------------------------------------------------------------------------------
|
||||
//! reent versions
|
||||
//!-------------------------------------------------------------------------------------------
|
||||
void *__wrap__malloc_r(struct _reent *r, size_t size)
|
||||
{
|
||||
return __wrap_malloc(size);
|
||||
}
|
||||
|
||||
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
|
||||
{
|
||||
return __wrap_calloc(n, size);
|
||||
}
|
||||
|
||||
void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size)
|
||||
{
|
||||
return __wrap_memalign(align, size);
|
||||
}
|
||||
|
||||
void __wrap__free_r(struct _reent *r, void *p)
|
||||
{
|
||||
__wrap_free(p);
|
||||
}
|
||||
|
||||
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
|
||||
{
|
||||
return __wrap_malloc_usable_size(p);
|
||||
}
|
||||
|
||||
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
|
||||
{
|
||||
return __wrap_realloc(p, size);
|
||||
}
|
13
include/coreinit/internal.h
Normal file
13
include/coreinit/internal.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <wut.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
__os_snprintf(char *buf, size_t n, const char *format, ... );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -297,3 +297,6 @@ EXPORT(MEMAllocFromUnitHeap);
|
||||
EXPORT(MEMFreeToUnitHeap);
|
||||
EXPORT(MEMCountFreeBlockForUnitHeap);
|
||||
EXPORT(MEMCalcHeapSizeForUnitHeap);
|
||||
|
||||
// coreinit/internal.h
|
||||
EXPORT(__os_snprintf);
|
||||
|
@ -5,7 +5,7 @@ WUT_ROOT := $(WUT_ROOT)
|
||||
endif
|
||||
|
||||
LIBPATHS := -L$(WUT_ROOT)/lib
|
||||
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding
|
||||
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding -fno-jump-tables
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -nostdlib -nostartfiles
|
||||
|
||||
|
194
rules/rpl.ld
194
rules/rpl.ld
@ -20,12 +20,154 @@ PHDRS {
|
||||
SECTIONS {
|
||||
. = ORIGIN(code);
|
||||
|
||||
.syscall ALIGN(32) : { *(.syscall) } : hdr_text
|
||||
|
||||
/* Standard code section */
|
||||
.text ALIGN(32) : {
|
||||
*(.text .stub .text.*)
|
||||
/* .init */
|
||||
KEEP( *(.crt0) )
|
||||
KEEP( *(.init) )
|
||||
. = ALIGN(4);
|
||||
|
||||
/* .text */
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.stub)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
. = ALIGN(4);
|
||||
|
||||
*(.rplTramp.text)
|
||||
*(SORT(.rplTramp.text.*))
|
||||
. = ALIGN(4);
|
||||
|
||||
/* .fini */
|
||||
KEEP( *(.fini) )
|
||||
. = ALIGN(4);
|
||||
|
||||
} : hdr_text
|
||||
|
||||
/* Standard data sections */
|
||||
. = ORIGIN(data);
|
||||
|
||||
.rodata ALIGN(256) : {
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
} : hdr_sdata
|
||||
.rodata1 : { *(.rodata1) }
|
||||
|
||||
.data ALIGN(256) : {
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.eh_frame)
|
||||
*(.eh_frame_hdr)
|
||||
*(.gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
|
||||
. = ALIGN(32);
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
__sdata_end = .;
|
||||
|
||||
. = ALIGN(32);
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
__sdata2_end = .;
|
||||
} : hdr_sdata
|
||||
|
||||
.tdata ALIGN(256) :
|
||||
{
|
||||
__tdata_lma = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
. = ALIGN(4);
|
||||
__tdata_lma_end = .;
|
||||
} : hdr_data
|
||||
|
||||
.tbss ALIGN(256) :
|
||||
{
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
*(.tcommon)
|
||||
. = ALIGN(4);
|
||||
} : hdr_data
|
||||
|
||||
.preinit_array ALIGN(256) :
|
||||
{
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
} : hdr_data
|
||||
|
||||
.init_array ALIGN(256) :
|
||||
{
|
||||
PROVIDE (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE (__init_array_end = .);
|
||||
} : hdr_data
|
||||
|
||||
.fini_array ALIGN(256) :
|
||||
{
|
||||
PROVIDE (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE (__fini_array_end = .);
|
||||
} : hdr_data
|
||||
|
||||
.ctors ALIGN(256) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} : hdr_data
|
||||
|
||||
.dtors ALIGN(256) :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
} : hdr_data
|
||||
|
||||
__bss_start__ = .;
|
||||
.bss ALIGN(4) :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
__sbss_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
/* Reserve space for the TLS segment of the main thread */
|
||||
__tls_start = .;
|
||||
. += + SIZEOF(.tdata) + SIZEOF(.tbss);
|
||||
__tls_end = .;
|
||||
. = ALIGN(32);
|
||||
} : hdr_data
|
||||
__bss_end__ = .;
|
||||
|
||||
/* System stuff is for our elf2rpl converter to go through */
|
||||
. = ORIGIN(system);
|
||||
@ -53,7 +195,8 @@ SECTIONS {
|
||||
}
|
||||
|
||||
/* Required compiler trash */
|
||||
.got ALIGN(32) : { *(.got) }
|
||||
.fixup ALIGN(32) : { *(.fixup*) }
|
||||
.got ALIGN(32) : { *(.got*) }
|
||||
.hash ALIGN(32) : { *(.hash) }
|
||||
.dynsym ALIGN(32) : { *(.dynsym) }
|
||||
|
||||
@ -94,51 +237,6 @@ SECTIONS {
|
||||
.symtab ALIGN(32) : { *(.symtab) }
|
||||
.strtab ALIGN(32) : { *(.strtab) }
|
||||
|
||||
/* Standard data sections */
|
||||
. = ORIGIN(data);
|
||||
|
||||
.rodata ALIGN(256) : {
|
||||
*(.rodata .rodata.*)
|
||||
} : hdr_srodata
|
||||
|
||||
.data ALIGN(256) : {
|
||||
*(.data)
|
||||
*(.eh_frame)
|
||||
*(.eh_frame_hdr)
|
||||
} : hdr_sdata
|
||||
|
||||
.bss ALIGN(256) : {
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
.sdata ALIGN(256) : {
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
__sdata_end = .;
|
||||
}
|
||||
|
||||
.sbss ALIGN(256) : {
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
__sbss_end = .;
|
||||
}
|
||||
|
||||
.sdata2 ALIGN(256) : {
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
__sdata2_end = .;
|
||||
}
|
||||
|
||||
.sbss2 ALIGN(256) : {
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
__sbss2_end = .;
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.interp)
|
||||
*(.dynstr)
|
||||
@ -152,6 +250,6 @@ SECTIONS {
|
||||
__SDATA2_START__ = __sdata2_start;
|
||||
__SBSS2_END__ = __sbss2_end;
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2);
|
||||
_SDA_BASE_ = __sbss_end;
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2);
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
LIBPATHS := -L$(WUT_ROOT)/lib
|
||||
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding
|
||||
LIBPATHS := -L$(WUT_ROOT)/lib -L$(DEVKITPPC)/lib
|
||||
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding -fno-jump-tables
|
||||
CXXFLAGS := $(CFLAGS)
|
||||
LDFLAGS := -nostdlib -nostartfiles -T $(WUT_ROOT)/rules/rpl.ld -pie -fPIE -z common-page-size=64 -z max-page-size=64 -lcoreinit -lcrt
|
||||
LDFLAGS := -nostartfiles -T $(WUT_ROOT)/rules/rpl.ld -pie -fPIE -z common-page-size=64 -z max-page-size=64 -lcrt \
|
||||
-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
|
||||
ELF2RPL := $(WUT_ROOT)/bin/elf2rpl
|
||||
|
||||
include $(WUT_ROOT)/rules/base.mk
|
||||
|
@ -434,12 +434,12 @@ read(ElfFile &file, const std::string &filename)
|
||||
|
||||
auto addend = static_cast<uint32_t>(rela.addend);
|
||||
|
||||
if (auto symbol = findSymbol(file, addend)) {
|
||||
relocation->symbol = symbol;
|
||||
relocation->addend = 0;
|
||||
} else if (auto import = findImport(file, addend)) {
|
||||
if (auto import = findImport(file, addend)) {
|
||||
relocation->symbol = import->stubSymbol;
|
||||
relocation->addend = 0;
|
||||
} else if (auto symbol = findSymbol(file, addend)) {
|
||||
relocation->symbol = symbol;
|
||||
relocation->addend = 0;
|
||||
} else if (addend >= DataAddress && addend < WiiuLoadAddress) {
|
||||
relocation->symbol = findSymbol(file, DataAddress);
|
||||
relocation->addend = addend - DataAddress;
|
||||
@ -453,6 +453,73 @@ read(ElfFile &file, const std::string &filename)
|
||||
file.relocations.emplace_back(relocation);
|
||||
}
|
||||
}
|
||||
|
||||
// Read dyn relocations
|
||||
for (auto §ion : inSections) {
|
||||
if (section.header.type != elf::SHT_RELA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto name = std::string { shStrTab + section.header.name };
|
||||
|
||||
if (name.compare(".rela.dyn") != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto symSection = inSections[section.header.link];
|
||||
auto relas = reinterpret_cast<elf::Rela *>(section.data.data());
|
||||
auto count = section.data.size() / sizeof(elf::Rela);
|
||||
|
||||
for (auto i = 0u; i < count; ++i) {
|
||||
auto relocation = new ElfFile::Relocation();
|
||||
auto &rela = relas[i];
|
||||
|
||||
auto type = rela.info & 0xff;
|
||||
auto index = rela.info >> 8;
|
||||
auto symbol = getSectionSymbol(symSection, index);
|
||||
auto addr = symbol->value + rela.addend;
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
auto addend = static_cast<uint32_t>(rela.addend);
|
||||
|
||||
if (auto import = findImport(file, addend)) {
|
||||
relocation->symbol = import->stubSymbol;
|
||||
relocation->addend = 0;
|
||||
} else if (auto symbol = findSymbol(file, addend)) {
|
||||
relocation->symbol = symbol;
|
||||
relocation->addend = 0;
|
||||
} else if (addr >= CodeAddress && addr < DataAddress) {
|
||||
index = 1;
|
||||
relocation->symbol = findSymbol(file, CodeAddress);
|
||||
relocation->addend = rela.addend - CodeAddress;
|
||||
} else if (addr >= DataAddress && addr < WiiuLoadAddress) {
|
||||
index = 2;
|
||||
relocation->symbol = findSymbol(file, DataAddress);
|
||||
relocation->addend = rela.addend - DataAddress;
|
||||
} else {
|
||||
std::cout << "Unexpected symbol address in .rela.dyn section" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case elf::R_PPC_RELATIVE:
|
||||
type = elf::R_PPC_ADDR32;
|
||||
break;
|
||||
default:
|
||||
std::cout << "Unexpected relocation type in .rela.dyn section" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
relocation->target = rela.offset;
|
||||
relocation->type = static_cast<elf::RelocationType>(type);
|
||||
|
||||
// Scrap any compiler/linker garbage
|
||||
if(relocation->target >= CodeAddress && relocation->target < WiiuLoadAddress)
|
||||
file.relocations.emplace_back(relocation);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -656,7 +723,7 @@ write(ElfFile &file, const std::string &filename)
|
||||
|
||||
// Prune out unneeded symbols
|
||||
for (auto i = 0u; i < file.symbols.size(); ++i) {
|
||||
if (!file.symbols[i]->name.empty() && file.symbols[i]->type == elf::STT_NOTYPE) {
|
||||
if (!file.symbols[i]->name.empty() && file.symbols[i]->type == elf::STT_NOTYPE && file.symbols[i]->size == 0) {
|
||||
file.symbols.erase(file.symbols.begin() + i);
|
||||
i--;
|
||||
}
|
||||
@ -691,16 +758,32 @@ write(ElfFile &file, const std::string &filename)
|
||||
return val.get() == relocation->symbol;
|
||||
});
|
||||
|
||||
if (itr == file.symbols.end()) {
|
||||
std::cout << "Could not find matching symbol for relocation" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto idx = itr - file.symbols.begin();
|
||||
|
||||
// If the symbol doesn't exist but it is within DATA or TEXT, use those symbols + an addend
|
||||
if (itr == file.symbols.end()) {
|
||||
if (relocation->symbol->address >= CodeAddress && relocation->symbol->address < DataAddress) {
|
||||
idx = 1;
|
||||
relocation->addend = relocation->symbol->address - CodeAddress;
|
||||
relocation->symbol = findSymbol(file, CodeAddress);
|
||||
} else if (relocation->symbol->address >= DataAddress && relocation->symbol->address < WiiuLoadAddress) {
|
||||
idx = 2;
|
||||
relocation->addend = relocation->symbol->address - DataAddress;
|
||||
relocation->symbol = findSymbol(file, DataAddress);
|
||||
} else {
|
||||
std::cout << "Could not find matching symbol for relocation" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create relocation
|
||||
elf::Rela rela;
|
||||
rela.info = relocation->type | idx << 8;
|
||||
|
||||
if(relocation->type == elf::R_PPC_RELATIVE) {
|
||||
rela.info = elf::R_PPC_ADDR32 | idx << 8;
|
||||
}
|
||||
|
||||
rela.addend = relocation->addend;
|
||||
rela.offset = relocation->target;
|
||||
|
||||
@ -799,7 +882,7 @@ write(ElfFile &file, const std::string &filename)
|
||||
sym.info = symbol->type | (symbol->binding << 4);
|
||||
sym.other = 0;
|
||||
sym.shndx = shndx;
|
||||
|
||||
|
||||
//Compound symbol crc into section crc
|
||||
auto crcSection = outSections[shndx];
|
||||
if(crcSection->header.type == elf::SHT_RPL_IMPORTS && symbol->type != elf::STT_SECTION) {
|
||||
@ -925,7 +1008,7 @@ write(ElfFile &file, const std::string &filename)
|
||||
fileInfo.loadSize = val;
|
||||
}
|
||||
} else if (section->header.type == elf::SHT_RELA) {
|
||||
fileInfo.tempSize += size;
|
||||
fileInfo.tempSize += align_up(size, 64);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user