Basic start of a Wii U Toolchain.

This commit is contained in:
James Benton 2015-12-26 18:10:38 -08:00
commit 8a9dfb1835
20 changed files with 374 additions and 0 deletions

26
Makefile Normal file
View File

@ -0,0 +1,26 @@
WUT_ROOT := $(CURDIR)
TARGETS := crt rpl
all:
@for dir in $(TARGETS); do \
echo; \
echo Entering Directory $$dir; \
$(MAKE) --no-print-directory -C $$dir; \
echo Leaving Directory $$dir; \
done
clean:
@rm -rf lib
@for dir in $(TARGETS); do \
echo Cleaning $$dir; \
$(MAKE) --no-print-directory -C $$dir clean; \
done
install:
@mkdir -p lib
@for dir in $(TARGETS); do \
echo Installing $$dir; \
$(MAKE) --no-print-directory -C $$dir install; \
done
.PHONY: all clean install

24
crt/Makefile Normal file
View File

@ -0,0 +1,24 @@
WUT_ROOT := $(CURDIR)/..
include $(WUT_ROOT)/rules/ppc.mk
CFILES := $(wildcard *.c)
SFILES := $(wildcard *.S)
CRT0 := crt0.o
STUBS := $(SFILES:.S=.o) $(CFILES:.c=.o)
all: $(STUBS) $(CRT0)
clean:
@echo "[RM] $(notdir $(CRT0))"
@rm -f $(STUBS) $(CRT0)
install: all
@mkdir -p $(WUT_ROOT)/lib
@cp -f *.o $(WUT_ROOT)/lib
%.o: %.S
@echo "[CC] $(notdir $<)"
@$(CC) $(CFLAGS) -c $< -o $@
.PHONY: all clean

10
crt/crt0.S Normal file
View File

@ -0,0 +1,10 @@
.extern main
.extern _Exit
.global _start
_start:
bl main
b _Exit
.global __eabi
__eabi:
blr

12
include/coreinit_crt.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void
_Exit();
#ifdef __cplusplus
}
#endif

12
include/coreinit_debug.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void
OSFatal(const char *msg);
#ifdef __cplusplus
}
#endif

12
include/gx2_init.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void
GX2Init();
#ifdef __cplusplus
}
#endif

25
rpl/Makefile Normal file
View File

@ -0,0 +1,25 @@
WUT_ROOT := $(CURDIR)/..
TARGETS := libcoreinit libgx2
all:
@for dir in $(TARGETS); do \
echo; \
echo Entering Directory $$dir; \
$(MAKE) --no-print-directory -C $$dir; \
echo Leaving Directory $$dir; \
done
clean:
@for dir in $(TARGETS); do \
echo Cleaning $$dir; \
$(MAKE) --no-print-directory -C $$dir clean; \
done
install: all
@mkdir -p $(WUT_ROOT)/lib
@for dir in $(TARGETS); do \
echo Installing $$dir; \
cp $$dir/*.a $(WUT_ROOT)/lib; \
done
.PHONY: all install clean

20
rpl/common/lib.c Normal file
View File

@ -0,0 +1,20 @@
#include "config.h"
typedef struct {
const char* name;
const void* fstub;
} __attribute__((__packed__)) rpl_header;
static const void* fstub[0] __attribute__((section(".data.rplFuncStubs")));
static const const char name[] __attribute__((section(".rodata.rplNames"))) = LIBRARY_NAME;
static rpl_header header __attribute__((section(".lib.rplLibs"))) = {
name,
fstub,
};
#define EXPORT(name) \
extern void* name; \
const void* name##_stub __attribute__((section(".data.rplFuncStubs"))) = &name; \
#include "exports.h"

68
rpl/common/rules.mk Normal file
View File

@ -0,0 +1,68 @@
.SUFFIXES:
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCE := ../common .
INCLUDE := .
DATA := data
LIBS :=
ifneq ($(BUILD),$(notdir $(CURDIR)))
WUT_ROOT := $(CURDIR)/../..
else
WUT_ROOT := $(CURDIR)/../../..
endif
include $(WUT_ROOT)/rules/ppc.mk
LD := $(PREFIX)ld
RPLCFLAGS := -Wno-unused-variable -fPIC -fpic -fno-builtin
CFLAGS += -O2 -Wall -std=c11 $(RPLCFLAGS)
ODEPS := stub.o lib.o
ifneq ($(BUILD),$(notdir $(CURDIR)))
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCE),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export BUILDDIR := $(CURDIR)/$(BUILD)
export DEPSDIR := $(BUILDDIR)
CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
export OFILES := $(CFILES:.c=.o) \
$(CXXFILES:.cpp=.o) \
$(SFILES:.S=.o)
export INCLUDES := $(foreach dir,$(INCLUDE),-I$(CURDIR)/$(dir)) \
-I$(CURDIR)/$(BUILD)
.PHONY: $(BUILD) clean
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
clean:
@echo "[RM] $(notdir $(OUTPUT))"
@rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).a
else
DEPENDS := $(OFILES:.o=.d)
OFILES := $(filter-out $(ODEPS),$(OFILES))
$(OUTPUT).a: rpl.o $(OFILES)
lib.o: lib.c
@echo "[CC] $(notdir $<)"
@$(CC) $(DEPSOPTIONS) $(RPLCFLAGS) -S $(INCLUDES) $< -o lib.S
@$(CC) $(DEPSOPTIONS) $(RPLCFLAGS) -c lib.S -o $@
rpl.o: $(ODEPS)
@$(LD) $(LDFLAGS) -r $(ODEPS) -o $@
-include $(DEPENDS)
endif

13
rpl/common/stub.S Normal file
View File

@ -0,0 +1,13 @@
#include "config.h"
#define EXPORT(name) \
.align 2; \
.section ".rplTramp.text","ax"; \
.global name; \
name: \
li %r0, 0; \
oris %r0, %r0, 0; \
mtctr %r0; \
bctr; \
#include "exports.h"

2
rpl/libcoreinit/Makefile Normal file
View File

@ -0,0 +1,2 @@
-include ../common/rules.mk
-include ../../common/rules.mk

2
rpl/libcoreinit/config.h Normal file
View File

@ -0,0 +1,2 @@
#define LIBRARY_NAME "coreinit.rpl"
#define LIBRARY_SYMBOL coreinit

View File

@ -0,0 +1,2 @@
EXPORT(_Exit);
EXPORT(OSFatal);

2
rpl/libgx2/Makefile Normal file
View File

@ -0,0 +1,2 @@
-include ../common/rules.mk
-include ../../common/rules.mk

2
rpl/libgx2/config.h Normal file
View File

@ -0,0 +1,2 @@
#define LIBRARY_NAME "gx2.rpl"
#define LIBRARY_SYMBOL gx2

1
rpl/libgx2/exports.h Normal file
View File

@ -0,0 +1 @@
EXPORT(GX2Init);

54
rules/base.mk Normal file
View File

@ -0,0 +1,54 @@
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please ensure DEVKITPRO is in your environment.")
endif
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please ensure DEVKITPPC is in your environment.")
endif
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
PREFIX := powerpc-eabi-
OBJCOPY := $(PREFIX)objcopy
AR := $(PREFIX)ar
AS := $(PREFIX)gcc
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
STRIP := $(PREFIX)strip
ifeq ($(findstring $(PREFIX),$(LD)),)
LD := $(CC)
endif
DEPSOPTIONS = -MMD -MP -MF $(DEPSDIR)/$*.d
ifdef VERBOSE
DEPSOPTIONS += -v
endif
%.o: %.c
@echo "[CC] $(notdir $<)"
@$(CC) $(DEPSOPTIONS) $(CFLAGS) $(INCLUDES) -c $< -o $@
%.o: %.cpp
@echo "[CXX] $(notdir $<)"
@$(CXX) $(DEPSOPTIONS) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
%.o: %.s
@echo "[CC] $(notdir $<)"
@$(AS) $(DEPSOPTIONS) -x assembler-with-cpp $(ASFLAGS) $(INCLUDES) -c $< -o $@
%.o: %.S
@echo "[CC] $(notdir $<)"
@$(AS) $(DEPSOPTIONS) -x assembler-with-cpp $(ASFLAGS) $(INCLUDES) -c $< -o $@
%.a:
@echo "[AR] $(notdir $@)"
@$(AR) -rcs $@ $^
%.elf:
@echo "[LD] $(notdir $@)"
@echo "[LD] $(LIBPATHS)"
@echo "[LD] $(LDFLAGS)"
@$(LD) -v $^ $(LIBPATHS) $(LIBS) $(LDFLAGS) -o $@

9
rules/ppc.mk Normal file
View File

@ -0,0 +1,9 @@
LIBPATHS := -L$(WUT_ROOT)/lib
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding
CXXFLAGS := $(CFLAGS)
LDFLAGS := -nostdlib -nostartfiles -T $(WUT_ROOT)/rules/rpl.ld
include $(WUT_ROOT)/rules/base.mk
%.rpx: %.elf
@$(STRIP) $< -o $(BUILDDIR)/$(notdir $<)

66
rules/rpl.ld Normal file
View File

@ -0,0 +1,66 @@
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
MEMORY {
system (rw) : ORIGIN = 0x01000000, LENGTH = 32M
code (rwx) : ORIGIN = 0x02000000, LENGTH = 224M
data (rw) : ORIGIN = 0x10000000, LENGTH = 800M
}
PHDRS {
}
SECTIONS {
. = ORIGIN(code);
/* Standard code section */
.text . : { *(.text .stub .text.*) }
/*
* Trampolines for each RPL function, have the same symbol name of
* than the function they should import.
*
* There will be 2 relocations in each trampoline pointing to the
* function stub inside the .data.rplFuncStubs, we can edit these
* relocation entries to use the RPL import during conversion to RPL.
*
* li r0, func_stub@lo -> .data.rplFuncStubs
* oris r0, func_stub@hi -> .data.rplFuncStubs
* mtctr r0
* bctr
*/
.rplTramp.text . : {
*(.rplTramp.text)
*(SORT(.rplTramp.text.*))
}
/* Standard data sections */
. = ORIGIN(data);
.rodata . : { *(.rodata .rodata.*) }
.data . : { *(.data) }
.bss . : { *(.bss) }
/* System stuff is for our elf2rpl converter to go through */
. = ORIGIN(system);
/*
* Contains the name of RPLs, referenced by .lib.rplLibs
*/
.rodata.rplNames . : { KEEP (*(.rodata.rplNames)) }
/*
* List of RPL libraries to import, in format:
* uint32_t nameAddress -> .rodata.rplNames
* uint32_t firstFuncEntry -> .data.rplFuncStubs
*/
.lib.rplLibs . : { KEEP (*(.lib.rplLibs)) }
/*
* List of functions an RPL exports, in format:
* uint32_t trampAddress
*/
.data.rplFuncStubs . : { KEEP (*(.data.rplFuncStubs)) }
}

12
rules/rpl.mk Normal file
View File

@ -0,0 +1,12 @@
LIBPATHS := -L$(WUT_ROOT)/lib
CFLAGS := -I$(WUT_ROOT)/include -fno-builtin -ffreestanding
CXXFLAGS := $(CFLAGS)
LDFLAGS := -nostdlib -nostartfiles $(WUT_ROOT)/lib/crt0.o -T $(WUT_ROOT)/rules/rpl.ld
include $(WUT_ROOT)/rules/base.mk
%.rpx: %.elf
@$(STRIP) $< -o $(BUILDDIR)/$(notdir $<)
%.rpl: %.elf
@$(STRIP) $< -o $(BUILDDIR)/$(notdir $<)