first commit

This commit is contained in:
Maschell 2020-11-29 12:59:58 +01:00
commit 8f46eb434b
24 changed files with 2902 additions and 0 deletions

58
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,58 @@
name: CI-Release
on:
push:
branches:
- master
jobs:
build-binary:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -t builder
docker run --rm -v ${PWD}:/project builder make
- uses: actions/upload-artifact@master
with:
name: binary
path: "payload.elf"
deploy-binary:
needs: build-binary
runs-on: ubuntu-18.04
steps:
- name: Get environment variables
id: get_repository_name
run: |
echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//") >> $GITHUB_ENV
echo DATETIME=$(echo $(date '+%Y%m%d-%H%M%S')) >> $GITHUB_ENV
- uses: actions/download-artifact@master
with:
name: binary
path: wiiu
- name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip wiiu
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
release_name: Nightly-${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
draft: false
prerelease: true
body: |
Not a stable release:
${{ github.event.head_commit.message }}
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
asset_name: ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
asset_content_type: application/unknown

17
.github/workflows/pr.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: CI-PR
on: [pull_request]
jobs:
build-binary:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: build binary
run: |
docker build . -t builder
docker run --rm -v ${PWD}:/project builder make
- uses: actions/upload-artifact@master
with:
name: binary
path: "*.elf"

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
/*.elf
/*.cbp
/build
*.rpx
*.bin
*.cscope_file_list
*.layout
cmake-build-debug/
.idea/
CMakeLists.txt

3
Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM wiiuenv/devkitppc:20200810
WORKDIR project

339
LICENSE Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

212
Makefile Normal file
View File

@ -0,0 +1,212 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
PREFIX := powerpc-eabi-
export AS := $(PREFIX)as
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := payload
BUILD := build
BUILD_DBG := $(TARGET)_dbg
SOURCES := src \
src/utils
DATA := data
INCLUDES := src
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS := -std=c2x -g -Wall -O2 -ffunction-sections -DESPRESSO -mcpu=750 -meabi -mhard-float $(INCLUDE)
CXXFLAGS := -std=c++20 -g -Wall -O2 -ffunction-sections -DESPRESSO -mcpu=750 -meabi -mhard-float $(INCLUDE)
ASFLAGS := -mregnames
LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition
#---------------------------------------------------------------------------------
Q := @
MAKEFLAGS += --no-print-directory
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwut
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) \
$(DEVKITPPC)/lib \
$(DEVKITPRO)/wut \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB) -L$(PORTLIBS)/lib
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean install
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.elf: link.ld $(OFILES)
@echo "linking ... $(TARGET).elf"
$(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS)
$(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@
$(Q)$(OBJCOPY) -O binary -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@.bin
#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
@echo $(notdir $@)
@rm -f $@
@$(AR) -rc $@ $^
#---------------------------------------------------------------------------------
%.o: %.cpp
@echo $(notdir $<)
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.c
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.S
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.png.o : %.png
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.bin.o : %.bin
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.wav.o : %.wav
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.mp3.o : %.mp3
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ogg.o : %.ogg
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.tga.o : %.tga
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

38
README.md Normal file
View File

@ -0,0 +1,38 @@
# PayloadLoaderPayload
This payload.elf loader which can be used with any `payload.elf` loader. (For example [PayloadFromRPX](https://github.com/wiiu-env/PayloadFromRPX) or [JsTypeHax](https://github.com/wiiu-env/JsTypeHax))
## Usage
Place the `payload.elf` in the `sd:/wiiu` folder of your sd card and run a exploit which loads `payload.elf`.
Per default this will chainload `sd:/wiiu/payloads/default/payload.elf`, but when holding B while loading this payload, the target payload can be selected.
Place payloads into seperate folder in `sd:/wiiu/payloads/` example:
```
sd:/wiiu/payloads/default/payload.elf
sd:/wiiu/payloads/legacy_env/payload.elf
sd:/wiiu/payloads/fw_img_loader/payload.elf
```
## Building
For building you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command.
## Building using the Dockerfile
It's possible to use a docker image for building. This way you don't need anything installed on your host system.
```
# Build docker image (only needed once)
docker build . -t payloadloaderpayload-builder
# make
docker run -it --rm -v ${PWD}:/project payloadloaderpayload-builder make
# make clean
docker run -it --rm -v ${PWD}:/project payloadloaderpayload-builder make clean
```
## Credits
- Maschell
- orboditilt
- Copy pasted the solution for using wut header in .elf files from [RetroArch](https://github.com/libretro/RetroArch)

44
src/dynamic.c Normal file
View File

@ -0,0 +1,44 @@
#include <coreinit/dynload.h>
#include <coreinit/debug.h>
#define IMPORT(name) void* addr_##name
#define IMPORT_BEGIN(lib)
#define IMPORT_END()
#include "imports.h"
#undef IMPORT
#undef IMPORT_BEGIN
#undef IMPORT_END
#define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0)
#define IMPORT_BEGIN(lib) OSDynLoad_Acquire(#lib ".rpl", &handle)
/* #define IMPORT_END() OSDynLoad_Release(handle) */
#define IMPORT_END()
#define EXPORT_VAR(type, var) type var __attribute__((section(".data")));
EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap);
EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx);
EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap);
void InitFunctionPointers(void) {
OSDynLoad_Module handle;
addr_OSDynLoad_Acquire = (void *) 0x0102A3B4;
addr_OSDynLoad_FindExport = (void *) 0x0102B828;
OSDynLoad_Acquire("coreinit.rpl", &handle);
uint32_t **value = 0;
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &value);
MEMAllocFromDefaultHeap = *value;
OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &value);
MEMAllocFromDefaultHeapEx = *value;
OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &value);
MEMFreeToDefaultHeap = *value;
#include "imports.h"
// override failed __rplwrap_exit find export
OSDynLoad_FindExport(handle, 0, "exit", (void **) &addr___rplwrap_exit);
}

11
src/dynamic.h Normal file
View File

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

24
src/import_stub.S Normal file
View File

@ -0,0 +1,24 @@
/*#define IMPORT(name) \
.global name; \
name: \
lis %r11, addr_##name@h; \
lwz %r11, addr_##name@l(%r11); \
mtctr %r11; \
bctr*/
#define IMPORT(name) \
.global name; \
name: \
lis %r11, addr_##name@h; \
ori %r11, %r11, addr_##name@l; \
lwz %r11, 0(%r11); \
mtctr %r11; \
bctr
#define IMPORT_BEGIN(lib)
#define IMPORT_END()
.align 2;
.section ".text";
#include "imports.h"

295
src/imports.h Normal file
View File

@ -0,0 +1,295 @@
/* coreinit */
IMPORT_BEGIN(coreinit);
IMPORT(OSScreenInit);
IMPORT(OSScreenGetBufferSizeEx);
IMPORT(OSScreenSetBufferEx);
IMPORT(OSScreenEnableEx);
IMPORT(OSScreenFlipBuffersEx);
IMPORT(OSScreenClearBufferEx);
IMPORT(OSScreenPutFontEx);
IMPORT(OSFatal);
IMPORT(OSDynLoad_Acquire);
IMPORT(OSDynLoad_FindExport);
IMPORT(OSDynLoad_Release);
IMPORT(OSSetExceptionCallback);
IMPORT(OSSavesDone_ReadyToRelease);
IMPORT(OSInitMutex);
IMPORT(OSLockMutex);
IMPORT(OSUnlockMutex);
IMPORT(OSInitCond);
IMPORT(OSWaitCond);
IMPORT(OSSignalCond);
IMPORT(OSInitSpinLock);
IMPORT(OSUninterruptibleSpinLock_Acquire);
IMPORT(OSUninterruptibleSpinLock_Release);
IMPORT(OSFastMutex_Init);
IMPORT(OSFastMutex_Lock);
IMPORT(OSFastMutex_Unlock);
IMPORT(OSSleepTicks);
IMPORT(OSGetTitleID);
IMPORT(OSIsThreadTerminated);
IMPORT(OSSetThreadPriority);
IMPORT(OSCreateThread);
IMPORT(OSSetThreadCleanupCallback);
IMPORT(OSResumeThread);
IMPORT(OSIsThreadSuspended);
IMPORT(OSSuspendThread);
IMPORT(OSGetCurrentThread);
IMPORT(OSExitThread);
IMPORT(OSJoinThread);
IMPORT(OSYieldThread);
IMPORT(OSGetCoreId);
IMPORT(OSIsMainCore);
IMPORT(OSGetSystemTime);
IMPORT(OSGetSystemTick);
IMPORT(OSGetTime);
IMPORT(OSGetSymbolName);
IMPORT(OSGetSharedData);
IMPORT(OSEffectiveToPhysical);
IMPORT(OSInitSemaphore);
IMPORT(OSInitSemaphoreEx);
IMPORT(OSGetSemaphoreCount);
IMPORT(OSSignalSemaphore);
IMPORT(OSWaitSemaphore);
IMPORT(OSTryWaitSemaphore);
IMPORT(OSCompareAndSwapAtomicEx);
IMPORT(OSCompareAndSwapAtomic);
IMPORT(OSGetThreadSpecific);
IMPORT(OSSetThreadSpecific);
IMPORT(exit);
IMPORT(_Exit);
IMPORT(__os_snprintf);
IMPORT(DisassemblePPCRange);
IMPORT(ICInvalidateRange);
IMPORT(DCInvalidateRange);
IMPORT(DCFlushRange);
IMPORT(DCStoreRange);
IMPORT(DCStoreRangeNoSync);
IMPORT(__gh_errno_ptr);
IMPORT(MEMGetBaseHeapHandle);
IMPORT(MEMCreateExpHeapEx);
IMPORT(MEMDestroyExpHeap);
IMPORT(MEMAllocFromExpHeapEx);
IMPORT(MEMFreeToExpHeap);
IMPORT(MEMGetSizeForMBlockExpHeap);
IMPORT(MEMAllocFromFrmHeapEx);
IMPORT(MEMFreeToFrmHeap);
IMPORT(MEMGetAllocatableSizeForFrmHeapEx);
IMPORT(FSInit);
IMPORT(FSShutdown);
IMPORT(FSAddClient);
IMPORT(FSAddClientEx);
IMPORT(FSDelClient);
IMPORT(FSInitCmdBlock);
IMPORT(FSChangeDir);
IMPORT(FSGetFreeSpaceSize);
IMPORT(FSGetStat);
IMPORT(FSRemove);
IMPORT(FSOpenFile);
IMPORT(FSCloseFile);
IMPORT(FSOpenDir);
IMPORT(FSMakeDir);
IMPORT(FSReadDir);
IMPORT(FSRewindDir);
IMPORT(FSCloseDir);
IMPORT(FSGetStatFile);
IMPORT(FSReadFile);
IMPORT(FSWriteFile);
IMPORT(FSSetPosFile);
IMPORT(FSFlushFile);
IMPORT(FSTruncateFile);
IMPORT(FSRename);
IMPORT(FSGetMountSource);
IMPORT(FSMount);
IMPORT(FSUnmount);
IMPORT(FSChangeMode);
IMPORT(FSGetPosFile);
IMPORT(OSTicksToCalendarTime);
IMPORT(__rplwrap_exit);
IMPORT(IOS_Open);
IMPORT(IOS_Close);
IMPORT(IOS_Ioctl);
IMPORT(IOS_IoctlAsync);
IMPORT(IMIsAPDEnabled);
IMPORT(IMIsDimEnabled);
IMPORT(IMEnableAPD);
IMPORT(IMEnableDim);
IMPORT(IMDisableAPD);
IMPORT(IMDisableDim);
IMPORT(OSGetSystemInfo);
IMPORT_END();
/* nsysnet */
IMPORT_BEGIN(nsysnet);
IMPORT(socket_lib_init);
IMPORT(getaddrinfo);
IMPORT(freeaddrinfo);
IMPORT(getnameinfo);
IMPORT(inet_ntoa);
IMPORT(inet_ntop);
IMPORT(inet_aton);
IMPORT(inet_pton);
IMPORT(ntohl);
IMPORT(ntohs);
IMPORT(htonl);
IMPORT(htons);
IMPORT(accept);
IMPORT(bind);
IMPORT(socketclose);
IMPORT(connect);
IMPORT(getpeername);
IMPORT(getsockname);
IMPORT(getsockopt);
IMPORT(listen);
IMPORT(recv);
IMPORT(recvfrom);
IMPORT(send);
IMPORT(sendto);
IMPORT(setsockopt);
IMPORT(shutdown);
IMPORT(socket);
IMPORT(select);
IMPORT(socketlasterr);
IMPORT(socket_lib_finish);
IMPORT_END();
/* gx2 */
IMPORT_BEGIN(gx2);
IMPORT(GX2Invalidate);
IMPORT(GX2Init);
IMPORT(GX2GetSystemTVScanMode);
IMPORT(GX2CalcTVSize);
IMPORT(GX2SetTVBuffer);
IMPORT(GX2CalcDRCSize);
IMPORT(GX2SetDRCBuffer);
IMPORT(GX2CalcSurfaceSizeAndAlignment);
IMPORT(GX2InitColorBufferRegs);
IMPORT(GX2SetupContextStateEx);
IMPORT(GX2SetContextState);
IMPORT(GX2SetColorBuffer);
IMPORT(GX2SetViewport);
IMPORT(GX2SetScissor);
IMPORT(GX2SetDepthOnlyControl);
IMPORT(GX2SetColorControl);
IMPORT(GX2SetBlendControl);
IMPORT(GX2SetBlendConstantColor);
IMPORT(GX2SetCullOnlyControl);
IMPORT(GX2CalcFetchShaderSizeEx);
IMPORT(GX2InitFetchShaderEx);
IMPORT(GX2SetFetchShader);
IMPORT(GX2SetVertexShader);
IMPORT(GX2SetPixelShader);
IMPORT(GX2SetGeometryShader);
IMPORT(GX2SetGeometryUniformBlock);
IMPORT(GX2SetVertexUniformBlock);
IMPORT(GX2SetPixelUniformBlock);
IMPORT(GX2CalcGeometryShaderInputRingBufferSize);
IMPORT(GX2CalcGeometryShaderOutputRingBufferSize);
IMPORT(GX2SetGeometryShaderInputRingBuffer);
IMPORT(GX2SetGeometryShaderOutputRingBuffer);
IMPORT(GX2SetShaderModeEx);
IMPORT(GX2SetAttribBuffer);
IMPORT(GX2InitTextureRegs);
IMPORT(GX2InitSampler);
IMPORT(GX2SetPixelTexture);
IMPORT(GX2SetPixelSampler);
IMPORT(GX2ClearColor);
IMPORT(GX2CopyColorBufferToScanBuffer);
IMPORT(GX2SwapScanBuffers);
IMPORT(GX2Flush);
IMPORT(GX2WaitForVsync);
IMPORT(GX2SetTVEnable);
IMPORT(GX2SetDRCEnable);
IMPORT(GX2SetSwapInterval);
IMPORT(GX2DrawDone);
IMPORT(GX2Shutdown);
IMPORT(GX2DrawEx);
IMPORT(GX2WaitForFlip);
IMPORT(GX2GetSwapStatus);
IMPORT_END();
/* nn_ac */
IMPORT_BEGIN(nn_ac);
IMPORT(ACInitialize);
IMPORT(ACFinalize);
IMPORT(ACConnect);
IMPORT(ACClose);
IMPORT(ACGetAssignedAddress);
IMPORT(ACGetAssignedSubnet);
IMPORT(Initialize__Q2_2nn3actFv);
IMPORT(GetSlotNo__Q2_2nn3actFv);
IMPORT(GetDefaultAccount__Q2_2nn3actFv);
IMPORT(Finalize__Q2_2nn3actFv);
IMPORT_END();
/* proc_ui */
IMPORT_BEGIN(proc_ui);
IMPORT(ProcUIInit);
IMPORT(ProcUIShutdown);
IMPORT(ProcUIDrawDoneRelease);
IMPORT(ProcUIProcessMessages);
IMPORT_END();
/* sndcore2 */
IMPORT_BEGIN(sndcore2);
IMPORT(AXInitWithParams);
IMPORT(AXQuit);
IMPORT(AXRegisterFrameCallback);
IMPORT(AXAcquireMultiVoice);
IMPORT(AXSetMultiVoiceDeviceMix);
IMPORT(AXSetMultiVoiceOffsets);
IMPORT(AXSetMultiVoiceCurrentOffset);
IMPORT(AXSetMultiVoiceState);
IMPORT(AXSetMultiVoiceVe);
IMPORT(AXSetMultiVoiceSrcType);
IMPORT(AXSetMultiVoiceSrcRatio);
IMPORT(AXIsMultiVoiceRunning);
IMPORT(AXFreeMultiVoice);
IMPORT_END();
/* sysapp */
IMPORT_BEGIN(sysapp);
IMPORT(SYSRelaunchTitle);
IMPORT(_SYSGetSystemApplicationTitleId);
IMPORT(SYSLaunchMenu);
IMPORT(_SYSLaunchMenuWithCheckingAccount);
IMPORT_END();
/* vpad */
IMPORT_BEGIN(vpad);
IMPORT(VPADRead);
IMPORT(VPADInit);
IMPORT(VPADGetTPCalibratedPoint);
IMPORT_END();
/* nsyskbd */
IMPORT_BEGIN(zlib125);
IMPORT(inflateInit_);
IMPORT(inflate);
IMPORT(inflateEnd);
IMPORT_END();

94
src/kernel.cpp Normal file
View File

@ -0,0 +1,94 @@
/****************************************************************************
* Copyright (C) 2018-2020 Maschell
*
* 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 <cstdint>
#include <cstdio>
#include <cstring>
#include <coreinit/cache.h>
#include <coreinit/memorymap.h>
#include "kernel.h"
/* assembly functions */
extern "C" void Syscall_0x36(void);
extern "C" void KernelPatchesRevertHook(void);
extern "C" void KernelPatches(void);
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
extern "C" void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
extern "C" void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
void KernelWriteU32(uint32_t addr, uint32_t value) {
ICInvalidateRange(&value, 4);
DCFlushRange(&value, 4);
auto dst = (uint32_t) OSEffectiveToPhysical(addr);
auto src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value);
SC_0x25_KernelCopyData(dst, src, 4);
DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *) addr, 4);
}
void revertMainHook() {
KernelWriteU32(0x0101c56c, 0x4E800421);
}
void doKernelSetup() {
kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches);
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches);
Syscall_0x36();
}
void revertKernelHook() {
kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatchesRevertHook);
kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatchesRevertHook);
kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatchesRevertHook);
kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatchesRevertHook);
kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatchesRevertHook);
Syscall_0x36();
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}

38
src/kernel.h Normal file
View File

@ -0,0 +1,38 @@
/****************************************************************************
* Copyright (C) 2018-2020 Maschell
*
* 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/>.
****************************************************************************/
#pragma once
#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
#ifdef __cplusplus
extern "C" {
#endif
void doKernelSetup();
void doKernelSetup2();
void revertKernelHook();
#ifdef __cplusplus
}
#endif

210
src/kernel_asm.S Normal file
View File

@ -0,0 +1,210 @@
.section ".kernel_code"
.globl SaveAndResetDataBATs_And_SRs_hook
SaveAndResetDataBATs_And_SRs_hook:
# setup CTR to the position we need to return to
mflr r5
mtctr r5
# set link register to its original value
mtlr r7
# setup us a nice DBAT for our code data with same region as our code
mfspr r5, 560
mtspr 570, r5
mfspr r5, 561
mtspr 571, r5
# restore the original kernel instructions that we replaced
lwz r5, 0x34(r3)
lwz r6, 0x38(r3)
lwz r7, 0x3C(r3)
lwz r8, 0x40(r3)
lwz r9, 0x44(r3)
lwz r10, 0x48(r3)
lwz r11, 0x4C(r3)
lwz r3, 0x50(r3)
isync
mtsr 7, r5
# jump back to the position in kernel after our patch (from LR)
bctr
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06B6C
#define BAT_SET_NOP_ADDR_2 0xFFF06BF8
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D70C
#define BAT_SET_NOP_ADDR_6 0xFFF1D728
#define BAT_SET_NOP_ADDR_7 0xFFF1D82C
#define BAT_SET_NOP_ADDR_8 0xFFEE11C4
#define BAT_SET_NOP_ADDR_9 0xFFEE11C8
#define BAT_SETUP_HOOK_ENTRY 0x00FD0000
#define BAT4U_VAL 0x008000FF
#define BAT4L_VAL 0x30800012
#define SET_R4_TO_ADDR(addr) \
lis r3, addr@h ; \
ori r3, r3, addr@l ; \
stw r4, 0(r3) ; \
dcbf 0, r3 ; \
icbi 0, r3 ;
.globl Syscall_0x36
Syscall_0x36:
li r0, 0x3600
sc
blr
.globl KernelPatches
KernelPatches:
# store the old DBAT0
mfdbatu r5, 0
mfdbatl r6, 0
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFF0
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFF0
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
# just chosen because its simple
lis r3, BAT_SETUP_HOOK_ADDR@h
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
# make the kernel setup our section in IBAT4 and
# jump to our function to restore the replaced instructions
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
ori r4, r4, BAT4L_VAL@h
stw r4, 0x00(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
ori r4, r4, BAT4L_VAL@l
stw r4, 0x04(r3)
lis r4, 0x7cf1 # mtspr 561, r7
ori r4, r4, 0x8ba6
stw r4, 0x08(r3)
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
ori r4, r4, BAT4U_VAL@h
stw r4, 0x0C(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
ori r4, r4, BAT4U_VAL@l
stw r4, 0x10(r3)
lis r4, 0x7cf0 # mtspr 560, r7
ori r4, r4, 0x8ba6
stw r4, 0x14(r3)
lis r4, 0x7c00 # eieio
ori r4, r4, 0x06ac
stw r4, 0x18(r3)
lis r4, 0x4c00 # isync
ori r4, r4, 0x012c
stw r4, 0x1C(r3)
lis r4, 0x7ce8 # mflr r7
ori r4, r4, 0x02a6
stw r4, 0x20(r3)
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
stw r4, 0x24(r3)
# flush and invalidate the replaced instructions
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
dcbf 0, r3
icbi 0, r3
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
dcbf 0, r3
icbi 0, r3
sync
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
# IBATL 4
lis r3, BAT4L_VAL@h
ori r3, r3, BAT4L_VAL@l
mtspr 561, r3
# IBATU 4
lis r3, BAT4U_VAL@h
ori r3, r3, BAT4U_VAL@l
mtspr 560, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
# nop on IBATU 4 and DBAT 5 set/reset
#ifdef BAT_SET_NOP_ADDR_1
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
#endif
#ifdef BAT_SET_NOP_ADDR_2
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
#endif
#ifdef BAT_SET_NOP_ADDR_3
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
#endif
#ifdef BAT_SET_NOP_ADDR_4
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
#endif
#ifdef BAT_SET_NOP_ADDR_5
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
#endif
#ifdef BAT_SET_NOP_ADDR_6
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
#endif
#ifdef BAT_SET_NOP_ADDR_7
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
#endif
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFEE
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFEE
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
#endif
# memory barrier
eieio
isync
# restore DBAT 0 and return from interrupt
mtdbatu 0, r5
mtdbatl 0, r6
# memory barrier
eieio
isync
blr

84
src/kernel_asm_revert.S Normal file
View File

@ -0,0 +1,84 @@
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
.globl KernelPatchesRevertHook
KernelPatchesRevertHook:
# store the old DBAT0
mfdbatu r5, 0
mfdbatl r6, 0
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFF0
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFF0
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# restore kernel hook
lis r3, BAT_SETUP_HOOK_ADDR@h
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
lis r4, 0x80a3 # lwz r5 ,0x34 (r3 )
ori r4, r4, 0x0034
stw r4, 0x00(r3)
lis r4, 0x80c3 # lwz r6 ,0x38 (r3 )
ori r4, r4, 0x0038
stw r4, 0x04(r3)
lis r4, 0x80e3 # lwz r7 ,0x3c (r3 )
ori r4, r4, 0x003c
stw r4, 0x08(r3)
lis r4, 0x8103 # lwz r8 ,0x40 (r3 )
ori r4, r4, 0x0040
stw r4, 0x0C(r3)
lis r4, 0x8123 # lwz r9 ,0x44 (r3 )
ori r4, r4, 0x0044
stw r4, 0x10(r3)
lis r4, 0x8143 # lwz r10 ,0x48 (r3 )
ori r4, r4, 0x0048
stw r4, 0x14(r3)
lis r4, 0x8163 # lwz r11 ,0x4c (r3 )
ori r4, r4, 0x004c
stw r4, 0x18(r3)
lis r4, 0x8063 # lwz r3 ,0x50 (r3 )
ori r4, r4, 0x0050
stw r4, 0x1C(r3)
lis r4, 0x4c00 # isync
ori r4, r4, 0x012c
stw r4, 0x20(r3)
lis r4, 0x7ca7 # mtsr sr7 ,r5
ori r4, r4, 0x01a4
stw r4, 0x24(r3)
# flush and invalidate the replaced instructions
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
dcbf 0, r3
icbi 0, r3
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
dcbf 0, r3
icbi 0, r3
sync
# memory barrier
eieio
isync
# restore DBAT 0 and return from interrupt
mtdbatu 0, r5
mtdbatl 0, r6
# memory barrier
eieio
isync
blr

27
src/kernel_copy.S Normal file
View File

@ -0,0 +1,27 @@
.global SCKernelCopyData
SCKernelCopyData:
// Disable data address translation
mfmsr %r6
li %r7, 0x10
andc %r6, %r6, %r7
mtmsr %r6
// Copy data
addi %r3, %r3, -1
addi %r4, %r4, -1
mtctr %r5
SCKernelCopyData_loop:
lbzu %r5, 1(%r4)
stbu %r5, 1(%r3)
bdnz SCKernelCopyData_loop
// Enable data address translation
ori %r6, %r6, 0x10
mtmsr %r6
blr
.global SC_0x25_KernelCopyData
SC_0x25_KernelCopyData:
li %r0, 0x2500
sc
blr

26
src/link.ld Normal file
View File

@ -0,0 +1,26 @@
OUTPUT(payload.elf);
ENTRY(_start);
SECTIONS {
. = 0x00FD0000;
.text : {
*(.kernel_code*);
*(.text*);
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
KEEP(*(.kernel_code*));
}
.data : {
*(.rodata*);
*(.data*);
*(.sdata*);
*(.bss*);
*(.sbss*);
}
__CODE_END = .;
/DISCARD/ : {
*(*);
}
}
ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x30000, "elf is too big");

241
src/main.cpp Normal file
View File

@ -0,0 +1,241 @@
/****************************************************************************
* Copyright (C) 2018-2020 Maschell
*
* 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 <cstdint>
#include <coreinit/dynload.h>
#include <coreinit/screen.h>
#include "utils/ElfUtils.h"
#include "utils/logger.h"
#include "dynamic.h"
#include "kernel.h"
#include <whb/log_udp.h>
#include <coreinit/filesystem.h>
#include <whb/sdcard.h>
#include <sys/stat.h>
#include <cstdio>
#include <string>
#include <vpad/input.h>
#include <vector>
#include <map>
#include <utils/StringTools.h>
std::map<std::string, std::string> get_all_payloads(const char *relativefilepath);
std::vector<std::string> readDirFull(const char *base_path, const char *path, FSCmdBlock &cmd, FSClient &client, int filter);
std::string PayloadSelectionScreen(const std::map<std::string, std::string> &payloads);
extern "C" void __init_wut();
extern "C" void __fini_wut();
extern "C" uint32_t start_wrapper(int argc, char **argv) {
doKernelSetup();
InitFunctionPointers();
__init_wut();
WHBLogUdpInit();
DEBUG_FUNCTION_LINE("Hello from payload");
VPADReadError err;
VPADStatus vpad_data;
VPADRead(VPAD_CHAN_0, &vpad_data, 1, &err);
uint32_t btn = vpad_data.hold | vpad_data.trigger;
std::map<std::string, std::string> payloads = get_all_payloads("wiiu/payloads");
uint32_t entryPoint = 0;
std::string payload_path = "wiiu/payloads/default/payload.elf";
if ((btn & VPAD_BUTTON_B) == VPAD_BUTTON_B) {
payload_path = PayloadSelectionScreen(payloads);
DEBUG_FUNCTION_LINE("Selected %s", payload_path.c_str());
}
entryPoint = load_loader_elf_from_sd(nullptr, payload_path.c_str());
if (entryPoint != 0) {
DEBUG_FUNCTION_LINE("loaded payload entrypoint at %08X", entryPoint);
} else {
DEBUG_FUNCTION_LINE("failed to load elf");
}
WHBLogUdpDeinit();
__fini_wut();
revertKernelHook();
return entryPoint;
}
extern "C" int _start(int argc, char **argv) {
uint32_t entryPoint = start_wrapper(argc, argv);
int res = -1;
if (entryPoint != 0) {
res = ((int (*)(int, char **)) entryPoint)(argc, argv);
}
return res;
}
std::map<std::string, std::string> get_all_payloads(const char *relativefilepath) {
std::map<std::string, std::string> result;
const char *sdRootPath = "";
std::vector<std::string> payload_folders;
std::vector<std::string> files_inFolder;
bool clientAdded = false;
if (!WHBMountSdCard()) {
DEBUG_FUNCTION_LINE("Failed to mount SD Card...");
goto exit;
}
FSCmdBlock cmd;
FSClient client;
sdRootPath = WHBGetSdCardMountPath();
FSAddClient(&client, -1);
clientAdded = true;
FSInitCmdBlock(&cmd);
payload_folders = readDirFull(sdRootPath, relativefilepath, cmd, client, 1);
for (auto &e : payload_folders) {
DEBUG_FUNCTION_LINE("Reading path %s", e.c_str());
files_inFolder = readDirFull(sdRootPath, e.c_str(), cmd, client, 2);
for (auto &child : files_inFolder) {
if (StringTools::EndsWith(child, "payload.elf")) {
std::vector<std::string> folders = StringTools::stringSplit(e, "/");
std::string folder_name = e;
if (folders.size() > 1) {
folder_name = folders.at(folders.size() - 1);
}
DEBUG_FUNCTION_LINE("%s is valid!", folder_name.c_str());
result[folder_name] = child;
break;
}
}
}
exit:
WHBUnmountSdCard();
if (clientAdded) {
FSDelClient(&client, -1);
}
return result;
}
std::vector<std::string> readDirFull(const char *base_path, const char *path, FSCmdBlock &cmd, FSClient &client, int filter) {
std::string full_dir_path = StringTools::strfmt("%s/%s", base_path, path);
FSStatus status;
FSDirectoryHandle handle;
std::vector<std::string> result;
if (FSOpenDir(&client, &cmd, full_dir_path.c_str(), &handle, -1) == FS_STATUS_OK) {
FSDirectoryEntry entry;
while (true) {
status = FSReadDir(&client, &cmd, handle, &entry, -1);
if (status < 0) {
break;
}
std::string filepath = StringTools::strfmt("%s/%s", path, entry.name);
if (entry.info.flags & FS_STAT_DIRECTORY && filter <= 1) {
result.push_back(filepath);
} else if (filter == 0 || filter == 2) {
result.push_back(filepath);
}
}
} else {
DEBUG_FUNCTION_LINE("Failed to open dir %s", path);
}
return result;
}
std::string PayloadSelectionScreen(const std::map<std::string, std::string> &payloads) {
int32_t screen_buf0_size = 0;
// Init screen and screen buffers
OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
OSScreenSetBufferEx(SCREEN_TV, (void *) 0xF4000000);
OSScreenSetBufferEx(SCREEN_DRC, (void *) (0xF4000000 + screen_buf0_size));
OSScreenEnableEx(SCREEN_TV, 1);
OSScreenEnableEx(SCREEN_DRC, 1);
// Clear screens
OSScreenClearBufferEx(SCREEN_TV, 0);
OSScreenClearBufferEx(SCREEN_DRC, 0);
OSScreenFlipBuffersEx(SCREEN_TV);
OSScreenFlipBuffersEx(SCREEN_DRC);
VPADStatus vpad_data;
VPADReadError error;
int selected = 0;
while (true) {
// Clear screens
OSScreenClearBufferEx(SCREEN_TV, 0);
OSScreenClearBufferEx(SCREEN_DRC, 0);
int pos = 0;
int i = 0;
for (auto const&[key, val] : payloads) {
std::string text = StringTools::strfmt("%s %s", i == selected ? "> " : " ", key.c_str());
OSScreenPutFontEx(SCREEN_TV, 0, pos, text.c_str());
OSScreenPutFontEx(SCREEN_DRC, 0, pos, text.c_str());
i++;
pos++;
}
VPADRead(VPAD_CHAN_0, &vpad_data, 1, &error);
if (vpad_data.trigger == VPAD_BUTTON_A) {
break;
}
if (vpad_data.trigger == VPAD_BUTTON_UP) {
selected--;
if (selected < 0) {
selected = 0;
}
} else if (vpad_data.trigger == VPAD_BUTTON_DOWN) {
selected++;
if ((uint32_t) selected >= payloads.size()) {
selected = payloads.size() - 1;
}
}
OSScreenFlipBuffersEx(SCREEN_TV);
OSScreenFlipBuffersEx(SCREEN_DRC);
OSSleepTicks(OSMillisecondsToTicks(16));
}
int i = 0;
for (auto const&[key, val] : payloads) {
if (i == selected) {
return val;
}
i++;
}
return "";
}

149
src/utils/ElfUtils.c Normal file
View File

@ -0,0 +1,149 @@
#include <stdio.h>
#include <string.h>
#include <coreinit/debug.h>
#include <coreinit/cache.h>
#include <coreinit/memdefaultheap.h>
#include <whb/sdcard.h>
#include <whb/file.h>
#include <whb/log.h>
#include <utils/logger.h>
#include "elf_abi.h"
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) {
char path[256];
int result = 0;
const char *sdRootPath = "";
if (!WHBMountSdCard()) {
DEBUG_FUNCTION_LINE("Failed to mount SD Card...");
result = -1;
goto exit;
}
sdRootPath = WHBGetSdCardMountPath();
sprintf(path, "%s/%s", sdRootPath, relativefilepath);
DEBUG_FUNCTION_LINE("Loading file %s.", path);
*fileOut = WHBReadWholeFile(path, sizeOut);
if (!(*fileOut)) {
result = -2;
DEBUG_FUNCTION_LINE("WHBReadWholeFile(%s) returned NULL", path);
goto exit;
}
exit:
WHBUnmountSdCard();
WHBDeInitFileSystem();
return result;
}
static void InstallMain(void *data_elf);
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
char *elf_data = NULL;
uint32_t fileSize = 0;
if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
return 0;
}
InstallMain(elf_data);
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data;
uint32_t res = ehdr->e_entry;
MEMFreeToDefaultHeap((void *) elf_data);
return res;
}
static unsigned int get_section(void *data, const char *name, unsigned int *size, unsigned int *addr, int fail_on_not_found) {
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if (!data
|| !IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_PPC)) {
OSFatal("Invalid elf file");
}
Elf32_Shdr *shdr = (Elf32_Shdr *) ((uint32_t) data + ehdr->e_shoff);
int i;
for (i = 0; i < ehdr->e_shnum; i++) {
const char *section_name = ((const char *) data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if (strcmp(section_name, name) == 0) {
if (addr) {
*addr = shdr[i].sh_addr;
}
if (size) {
*size = shdr[i].sh_size;
}
return shdr[i].sh_offset;
}
}
if (fail_on_not_found) {
OSFatal((char *) name);
}
return 0;
}
/* ****************************************************************** */
/* INSTALL MAIN CODE */
/* ****************************************************************** */
static void InstallMain(void *data_elf) {
// get .text section
unsigned int main_text_addr = 0;
unsigned int main_text_len = 0;
unsigned int section_offset = get_section(data_elf, ".text", &main_text_len, &main_text_addr, 1);
unsigned char *main_text = (unsigned char *)((uint32_t) data_elf + section_offset);
/* Copy main .text to memory */
if (section_offset > 0) {
DEBUG_FUNCTION_LINE("Copy section to %08X from %08X (size: %d)", main_text_addr, main_text, main_text_len);
memcpy((void *) (main_text_addr), (void *) main_text, main_text_len);
DCFlushRange((void *) main_text_addr, main_text_len);
ICInvalidateRange((void *) main_text_addr, main_text_len);
}
// get the .rodata section
unsigned int main_rodata_addr = 0;
unsigned int main_rodata_len = 0;
section_offset = get_section(data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0);
if (section_offset > 0) {
unsigned char *main_rodata = (unsigned char *)((uint32_t) data_elf + section_offset);
/* Copy main rodata to memory */
memcpy((void *) (main_rodata_addr), (void *) main_rodata, main_rodata_len);
DCFlushRange((void *) main_rodata_addr, main_rodata_len);
ICInvalidateRange((void *) main_rodata_addr, main_rodata_len);
}
// get the .data section
unsigned int main_data_addr = 0;
unsigned int main_data_len = 0;
section_offset = get_section(data_elf, ".data", &main_data_len, &main_data_addr, 0);
if (section_offset > 0) {
unsigned char *main_data = (unsigned char *)((uint32_t) data_elf + section_offset);
/* Copy main data to memory */
memcpy((void *) (main_data_addr), (void *) main_data, main_data_len);
DCFlushRange((void *) main_data_addr, main_data_len);
ICInvalidateRange((void *) main_data_addr, main_data_len);
}
// get the .bss section
unsigned int main_bss_addr = 0;
unsigned int main_bss_len = 0;
section_offset = get_section(data_elf, ".bss", &main_bss_len, &main_bss_addr, 0);
if (section_offset > 0) {
unsigned char *main_bss = (unsigned char *)((uint32_t) data_elf + section_offset);
/* Copy main data to memory */
memcpy((void *) (main_bss_addr), (void *) main_bss, main_bss_len);
DCFlushRange((void *) main_bss_addr, main_bss_len);
ICInvalidateRange((void *) main_bss_addr, main_bss_len);
}
}

7
src/utils/ElfUtils.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <cstdint>
extern "C" int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut);
extern "C" uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath);

304
src/utils/StringTools.cpp Normal file
View File

@ -0,0 +1,304 @@
/***************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* for WiiXplorer 2010
***************************************************************************/
#include <vector>
#include <string>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <strings.h>
#include <wut_types.h>
#include <stdio.h>
#include <utils/StringTools.h>
BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
if (b.size() > a.size()) {
return false;
}
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
}
const char *StringTools::byte_to_binary(int32_t x) {
static char b[9];
b[0] = '\0';
int32_t z;
for (z = 128; z > 0; z >>= 1) {
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
std::string output = input;
size_t position;
while (1) {
position = output.find(toBeRemoved);
if (position == std::string::npos) {
break;
}
output.erase(position, 1);
}
return output;
}
const char *StringTools::fmt(const char *format, ...) {
static char strChar[512];
strChar[0] = 0;
va_list va;
va_start(va, format);
if ((vsprintf(strChar, format, va) >= 0)) {
va_end(va);
return (const char *) strChar;
}
va_end(va);
return NULL;
}
const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512];
static wchar_t strWChar[512];
strWChar[0] = 0;
tmp[0] = 0;
if (!format) {
return (const wchar_t *) strWChar;
}
if (strcmp(format, "") == 0) {
return (const wchar_t *) strWChar;
}
va_list va;
va_start(va, format);
if ((vsprintf(tmp, format, va) >= 0)) {
int bt;
int32_t strlength = strlen(tmp);
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
if (bt > 0) {
strWChar[bt] = 0;
return (const wchar_t *) strWChar;
}
}
va_end(va);
return NULL;
}
int32_t StringTools::strprintf(std::string &str, const char *format, ...) {
static char tmp[512];
tmp[0] = 0;
int32_t result = 0;
va_list va;
va_start(va, format);
if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp;
result = str.size();
}
va_end(va);
return result;
}
std::string StringTools::strfmt(const char *format, ...) {
std::string str;
static char tmp[512];
tmp[0] = 0;
va_list va;
va_start(va, format);
if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp;
}
va_end(va);
return str;
}
BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
if (!strChar || !dest) {
return false;
}
int bt;
bt = mbstowcs(dest, strChar, strlen(strChar));
if (bt > 0) {
dest[bt] = 0;
return true;
}
return false;
}
int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
if (!string || !compare) {
return -1;
}
char TokCopy[512];
strncpy(TokCopy, compare, sizeof(TokCopy));
TokCopy[511] = '\0';
char *strTok = strtok(TokCopy, separator);
while (strTok != NULL) {
if (strcasecmp(string, strTok) == 0) {
return 0;
}
strTok = strtok(NULL, separator);
}
return -1;
}
int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
if (!string || !extension) {
return -1;
}
char *ptr = strrchr(string, seperator);
if (!ptr) {
return -1;
}
return strcasecmp(ptr + 1, extension);
}
std::vector<std::string> StringTools::stringSplit(const std::string &inValue, const std::string &splitter) {
std::string value = inValue;
std::vector<std::string> result;
while (true) {
uint32_t index = value.find(splitter);
if (index == std::string::npos) {
result.push_back(value);
break;
}
std::string first = value.substr(0, index);
result.push_back(first);
if (index + splitter.size() == value.length()) {
result.push_back("");
break;
}
if (index + splitter.size() > value.length()) {
break;
}
value = value.substr(index + splitter.size(), value.length());
}
return result;
}
const char *StringTools::FullpathToFilename(const char *path) {
if (!path) {
return path;
}
const char *ptr = path;
const char *Filename = ptr;
while (*ptr != '\0') {
if (ptr[0] == '/' && ptr[1] != '\0') {
Filename = ptr + 1;
}
++ptr;
}
return Filename;
}
void StringTools::RemoveDoubleSlashs(std::string &str) {
uint32_t length = str.size();
//! clear path of double slashes
for (uint32_t i = 1; i < length; ++i) {
if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1);
i--;
length--;
}
}
}
// You must free the result if result is non-NULL.
char *StringTools::str_replace(char *orig, char *rep, char *with) {
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
int len_rep; // length of rep (the string to remove)
int len_with; // length of with (the string to replace rep with)
int len_front; // distance between rep and end of last rep
int count; // number of replacements
// sanity checks and initialization
if (!orig || !rep) {
return NULL;
}
len_rep = strlen(rep);
if (len_rep == 0) {
return NULL;
} // empty rep causes infinite loop during count
if (!with) {
with = (char *) "";
}
len_with = strlen(with);
// count the number of replacements needed
ins = orig;
for (count = 0; (tmp = strstr(ins, rep)); ++count) {
ins = tmp + len_rep;
}
tmp = result = (char *) malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result) {
return NULL;
}
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result;
}

61
src/utils/StringTools.h Normal file
View File

@ -0,0 +1,61 @@
/***************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* for WiiXplorer 2010
***************************************************************************/
#pragma once
#include <vector>
#include <string>
#include <wut_types.h>
class StringTools {
public:
static BOOL EndsWith(const std::string &a, const std::string &b);
static const char *byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string &input, char toBeRemoved);
static const char *fmt(const char *format, ...);
static const wchar_t *wfmt(const char *format, ...);
static int32_t strprintf(std::string &str, const char *format, ...);
static std::string strfmt(const char *format, ...);
static BOOL char2wchar_t(const char *src, wchar_t *dest);
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
static int32_t strextcmp(const char *string, const char *extension, char seperator);
static char *str_replace(char *orig, char *rep, char *with);
static const char *FullpathToFilename(const char *path);
static void RemoveDoubleSlashs(std::string &str);
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
};

591
src/utils/elf_abi.h Normal file
View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

19
src/utils/logger.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <whb/log.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
#ifdef __cplusplus
}
#endif