Adjustments for linking, rpx/rpl generation

This commit is contained in:
shinyquagsire23 2016-07-20 22:45:53 -07:00
parent 2c69f7d9be
commit 9173f0f6c3
8 changed files with 373 additions and 66 deletions

View File

@ -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
View 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);
}

View 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

View File

@ -297,3 +297,6 @@ EXPORT(MEMAllocFromUnitHeap);
EXPORT(MEMFreeToUnitHeap);
EXPORT(MEMCountFreeBlockForUnitHeap);
EXPORT(MEMCalcHeapSizeForUnitHeap);
// coreinit/internal.h
EXPORT(__os_snprintf);

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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 &section : 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);
}
}