diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8510dc7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.2) +project(utilswut) +include("${WUT_ROOT}/share/wut.cmake" REQUIRED) + +file(GLOB_RECURSE SOURCE_FILES *.c *.cpp) +file(GLOB_RECURSE HEADER_FILES *.h) + +add_library(utilswut STATIC ${SOURCE_FILES} ${HEADER_FILES}) + +target_include_directories(utilswut PUBLIC "include") + +wut_enable_stdcpp(utilswut) +wut_default_malloc(utilswut) + +target_include_directories(utilswut PUBLIC "include") + + +install(TARGETS utilswut + ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ + DESTINATION "${CMAKE_INSTALL_PREFIX}/include/libutils" + FILES_MATCHING PATTERN "*.h*") \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index e9a3c42..0000000 --- a/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -DO_LOGGING := 1 - -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC) -endif - -export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) -export PORTLIBS := $(DEVKITPRO)/portlibs/ppc - -PREFIX := powerpc-eabi- - -export AS := $(PREFIX)as -export CC := $(PREFIX)gcc -export CXX := $(PREFIX)g++ -export AR := $(PREFIX)ar -export OBJCOPY := $(PREFIX)objcopy - -include $(DEVKITPPC)/base_rules - -#--------------------------------------------------------------------------------- -# 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 -# DATA is a list of directories containing binary files -# LIBDIR is where the built library will be placed -# all directories are relative to this makefile -#--------------------------------------------------------------------------------- -BUILD ?= release -SOURCES := source \ - source/fs \ - source/utils \ - source/language \ - source/network \ - source/system \ - source/kernel -INCLUDES := include \ - source -DATA := -LIB := lib - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -CFLAGS = -g -Os -Wall -D__wiiu__ -D_GNU_SOURCE $(MACHDEP) $(INCLUDE) -CXXFLAGS = $(CFLAGS) - -ifeq ($(DO_LOGGING), 1) - CFLAGS += -D__LOGGING__ - CXXFLAGS += -D__LOGGING__ -endif - -ASFLAGS := -mregnames - -export WIIUBIN := $(LIB)/libutils.a - -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := -ldynamiclibs - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := - -#--------------------------------------------------------------------------------- -# 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 TOPDIR ?= $(CURDIR)/.. -export DEPSDIR := $(CURDIR)/$(BUILD) - -export INCLUDEDIR := $(PORTLIBS)/include/libutils - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -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)/*.*))) - - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) $(sFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) -I$(LIBOGC_INC) \ - -I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(PORTLIBS)/lib - -.PHONY: $(BUILD) clean - -#--------------------------------------------------------------------------------- -$(BUILD): - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr debug release $(LIB) include - -all: $(WIIUBIN) - -install: - @cp $(BUILD)/lib/libutils.a $(PORTLIBS)/lib - @mkdir -p $(INCLUDEDIR)/utils/ - @mkdir -p $(INCLUDEDIR)/kernel/ - @mkdir -p $(INCLUDEDIR)/system/ - @mkdir -p $(INCLUDEDIR)/network/ - @mkdir -p $(INCLUDEDIR)/language/ - @mkdir -p $(INCLUDEDIR)/fs/ - @cp source/utils/*.h $(INCLUDEDIR)/utils/ - @cp source/utils/*.hpp $(INCLUDEDIR)/utils/ - @cp source/system/*.h $(INCLUDEDIR)/system/ - @cp source/language/*.h $(INCLUDEDIR)/language/ - @cp source/network/*.h $(INCLUDEDIR)/network/ - @cp source/fs/*.h $(INCLUDEDIR)/fs/ - @cp source/fs/*.hpp $(INCLUDEDIR)/fs/ - @cp source/kernel/*.h $(INCLUDEDIR)/kernel/ - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(WIIUBIN) : $(OFILES) $(LIB) - @rm -f "$(WIIUBIN)" - @$(AR) rcs "$(WIIUBIN)" $(OFILES) - @echo built ... $(notdir $@) - - -$(LIB): - mkdir $(LIB) - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- - diff --git a/README.md b/README.md index 7758020..66a9702 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,15 @@ -# libutils for WiiU homebrew. -[![Build Status](https://travis-ci.org/Maschell/libutils.svg?branch=master)](https://travis-ci.org/Maschell/libutils) +# libutils for WiiU homebrew. (WUT edition) +[![Build Status](https://travis-ci.org/Maschell/libutils.svg?branch=wut)](https://travis-ci.org/Maschell/libutils) This is a library for common functions. ## Features - FS utility functions -- Wrapper for easy kernel read/write (KernelCopyData to copy data to any place) - Multiple language support via gettext - Common system functions (Exception handler, memory functions, Thread wrapper etc.) -- Built in function patcher engine - String tools -(For some features the application need to be loaded from the homebrew_launcher to have kernel access) - ## Logging usage To able to use the logging, you need to compile the target application with follow C/C++ flag: ``` @@ -22,6 +18,7 @@ To able to use the logging, you need to compile the target application with foll Usage in the application: ``` +socket_lib_init(); log_init(); // Enables broadcast logging. printf("Just prints this text\n"); DEBUG_FUNCTION_LINE("This prints my current function, file and line\n"); @@ -34,31 +31,32 @@ Read the logs via the [udp_debug_reader](https://github.com/dimok789/loadiine_gx Link the application with ``` --lutils -ldynamiclibs +-lutilswut ``` You also need to add the include path to your Makefile. Example: ``` -export INCLUDE := [...] -I$(PORTLIBS)/include/libutils +export INCLUDE := [...] -I$(WUT_ROOT)/include/libutils ``` Check out the header for more information. ## Compiling -For compiling and using this lib, you need the [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) installed to your portlibs folder. +For compiling and using this lib, you need the [wut](https://github.com/decaf-emu/wut) installed. -Install this static library into your portlibs folder via: +Install this static library into your wut folder via: ``` -make && make install +mkdir build && cd build +cmake -DCMAKE_TOOLCHAIN_FILE=$WUT_ROOT/share/wut.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$WUT_ROOT ../ +make install ``` ## Dependencies -- Application needs to be loaded from the [homebrew_launcher](https://github.com/dimok789/homebrew_launcher) -- [dynamic_libs](https://github.com/Maschell/dynamic_libs/tree/lib) for access to the functions. +- [wut](https://github.com/decaf-emu/wut) # Credits (TODO) diff --git a/source/fs/CFile.hpp b/include/fs/CFile.hpp similarity index 96% rename from source/fs/CFile.hpp rename to include/fs/CFile.hpp index 1c59eac..c078720 100644 --- a/source/fs/CFile.hpp +++ b/include/fs/CFile.hpp @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include class CFile { public: diff --git a/source/fs/DirList.h b/include/fs/DirList.h similarity index 98% rename from source/fs/DirList.h rename to include/fs/DirList.h index 3e9e5bf..e4325ed 100644 --- a/source/fs/DirList.h +++ b/include/fs/DirList.h @@ -29,7 +29,7 @@ #include #include -#include +#include typedef struct { char * FilePath; diff --git a/source/fs/FSUtils.h b/include/fs/FSUtils.h similarity index 91% rename from source/fs/FSUtils.h rename to include/fs/FSUtils.h index a76edb9..6d09708 100644 --- a/source/fs/FSUtils.h +++ b/include/fs/FSUtils.h @@ -1,6 +1,7 @@ #ifndef __FS_UTILS_H_ #define __FS_UTILS_H_ -#include + +#include class FSUtils { public: diff --git a/source/fs/disc_io.h b/include/fs/disc_io.h similarity index 98% rename from source/fs/disc_io.h rename to include/fs/disc_io.h index c63a7cf..be277cb 100644 --- a/source/fs/disc_io.h +++ b/include/fs/disc_io.h @@ -31,8 +31,6 @@ #define OGC_DISC_IO_INCLUDE #include -#include - #define FEATURE_MEDIUM_CANREAD 0x00000001 #define FEATURE_MEDIUM_CANWRITE 0x00000002 diff --git a/source/language/gettext.h b/include/language/gettext.h similarity index 100% rename from source/language/gettext.h rename to include/language/gettext.h diff --git a/source/utils/net.h b/include/network/net.h similarity index 90% rename from source/utils/net.h rename to include/network/net.h index 3d648b0..e94fbf6 100644 --- a/source/utils/net.h +++ b/include/network/net.h @@ -1,12 +1,12 @@ #ifndef _UTILS_NET_H_ #define _UTILS_NET_H_ -#include - #ifdef __cplusplus extern "C" { #endif +#include + s32 recvwait(s32 sock, void *buffer, s32 len); u8 recvbyte(s32 sock); u32 recvword(s32 sock); diff --git a/source/system/AsyncDeleter.h b/include/system/AsyncDeleter.h similarity index 97% rename from source/system/AsyncDeleter.h rename to include/system/AsyncDeleter.h index 0ef7ce6..b5b1dc0 100644 --- a/source/system/AsyncDeleter.h +++ b/include/system/AsyncDeleter.h @@ -38,7 +38,7 @@ public: static void pushForDelete(AsyncDeleter::Element *e) { if(!deleterInstance) { - deleterInstance = new AsyncDeleter; + deleterInstance = new AsyncDeleter(); } deleterInstance->deleteElements.push(e); } diff --git a/source/system/CMutex.h b/include/system/CMutex.h similarity index 91% rename from source/system/CMutex.h rename to include/system/CMutex.h index 410aa1d..fecd54c 100644 --- a/source/system/CMutex.h +++ b/include/system/CMutex.h @@ -18,12 +18,13 @@ #define _CMUTEX_H_ #include -#include +#include -class CMutex { +class CMutex +{ public: CMutex() { - pMutex = malloc(OS_MUTEX_SIZE); + pMutex = (OSMutex*) malloc(sizeof(OSMutex)); if(!pMutex) return; @@ -49,10 +50,11 @@ public: return (OSTryLockMutex(pMutex) != 0); } private: - void *pMutex; + OSMutex *pMutex; }; -class CMutexLock { +class CMutexLock +{ public: CMutexLock() { mutex.lock(); diff --git a/source/system/CThread.h b/include/system/CThread.h similarity index 85% rename from source/system/CThread.h rename to include/system/CThread.h index bf484f0..ebc008d 100644 --- a/source/system/CThread.h +++ b/include/system/CThread.h @@ -20,8 +20,8 @@ #include #include -#include -#include "utils/logger.h" +#include +#include class CThread { public: @@ -36,13 +36,12 @@ public: //! save attribute assignment iAttributes = iAttr; //! allocate the thread - pThread = (OSThread*) memalign(8, 0x1000); + pThread = (OSThread*)memalign(8, sizeof(OSThread)); //! allocate the stack pThreadStack = (u8 *) memalign(0x20, iStackSize); //! create the thread - if(pThread && pThreadStack) { - OSCreateThread(pThread, &CThread::threadCallback, 1, this, (u32)pThreadStack+iStackSize, iStackSize, iPriority, iAttributes); - } + if(pThread && pThreadStack) + OSCreateThread(pThread, &CThread::threadCallback, 1, (char*)this, pThreadStack+iStackSize, iStackSize, iPriority, iAttributes); } //! destructor @@ -74,7 +73,7 @@ public: if(pThread) OSResumeThread(pThread); } //! Set thread priority - virtual void setThreadPriority(s32 prio) { + virtual void setThreadPriority(int prio) { if(pThread) OSSetThreadPriority(pThread, prio); } //! Check if thread is suspended @@ -91,29 +90,21 @@ public: virtual bool isThreadRunning(void) const { return !isThreadSuspended() && !isThreadRunning(); } - - //! Gets the thread affinity. - virtual u16 getThreadAffinity(void) const { - if(pThread) return OSGetThreadAffinity(pThread); - return 0; - } - //! Shutdown thread virtual void shutdownThread(void) { //! wait for thread to finish if(pThread && !(iAttributes & eAttributeDetach)) { - while(isThreadSuspended()) { + if(isThreadSuspended()) resumeThread(); - } + OSJoinThread(pThread, NULL); } //! free the thread stack buffer - if(pThreadStack) { + if(pThreadStack) free(pThreadStack); - } - if(pThread) { + if(pThread) free(pThread); - } + pThread = NULL; pThreadStack = NULL; } @@ -127,12 +118,12 @@ public: eAttributePinnedAff = 0x10 }; private: - static s32 threadCallback(s32 argc, void *arg) { + static int threadCallback(int argc, const char **argv) { //! After call to start() continue with the internal function - ((CThread *) arg)->executeThread(); + ((CThread *) argv)->executeThread(); return 0; } - s32 iAttributes; + int iAttributes; OSThread *pThread; u8 *pThreadStack; Callback pCallback; diff --git a/source/utils/StringTools.h b/include/utils/StringTools.h similarity index 98% rename from source/utils/StringTools.h rename to include/utils/StringTools.h index a66aeca..972fb8f 100644 --- a/source/utils/StringTools.h +++ b/include/utils/StringTools.h @@ -28,7 +28,7 @@ #include #include -#include +#include class StringTools{ public: diff --git a/source/utils/TCPServer.hpp b/include/utils/TCPServer.hpp similarity index 89% rename from source/utils/TCPServer.hpp rename to include/utils/TCPServer.hpp index b832ffb..d4d35c0 100644 --- a/source/utils/TCPServer.hpp +++ b/include/utils/TCPServer.hpp @@ -1,9 +1,14 @@ #ifndef _TCPSERVER_H_ #define _TCPSERVER_H_ -#include -#include +#include + +#include #include +#include + +#include +#include "utils/logger.h" class TCPServer { public: diff --git a/include/utils/elf_abi.h b/include/utils/elf_abi.h new file mode 100644 index 0000000..4d9c796 --- /dev/null +++ b/include/utils/elf_abi.h @@ -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 */ diff --git a/include/utils/elf_utils.h b/include/utils/elf_utils.h new file mode 100644 index 0000000..64d4455 --- /dev/null +++ b/include/utils/elf_utils.h @@ -0,0 +1,24 @@ +#ifndef __ELF_UTILS_H_ +#define __ELF_UTILS_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +unsigned int elf_get_section(unsigned char *data, const char *name, unsigned int * size, unsigned int * addr, int fail_on_not_found); + +bool elf_copy_section(unsigned char * elf_data, const char * section_name, bool errorOnFailure); + +u32 elf_copy_common_sections(unsigned char * elf_data); + +u32 elf_get_entry_addr(unsigned char * elf_data); + +#ifdef __cplusplus +} +#endif + +#endif // __ELF_UTILS_H_ diff --git a/source/utils/logger.h b/include/utils/logger.h similarity index 100% rename from source/utils/logger.h rename to include/utils/logger.h diff --git a/include/utils/utils.h b/include/utils/utils.h new file mode 100644 index 0000000..e69e02e --- /dev/null +++ b/include/utils/utils.h @@ -0,0 +1,17 @@ +#ifndef __UTILS_H_ +#define __UTILS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//Needs to have log_init() called beforehand. +void dumpHex(const void* data, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif // __UTILS_H_ diff --git a/libutils.cscope_file_list b/libutils.cscope_file_list new file mode 100644 index 0000000..d57ff30 --- /dev/null +++ b/libutils.cscope_file_list @@ -0,0 +1,54 @@ +"G:\Programmieren\libutils\source\fs\DirList.h" +"G:\Programmieren\libutils\source\system\memory.c" +"G:\Programmieren\libutils\release\function_patcher.d" +"G:\Programmieren\libutils\source\utils\TCPServer.cpp" +"G:\Programmieren\libutils\source\fs\CFile.cpp" +"G:\Programmieren\libutils\source\utils\logger.c" +"G:\Programmieren\libutils\source\fs\FSUtils.cpp" +"G:\Programmieren\libutils\source\utils\logger.h" +"G:\Programmieren\libutils\release\memory.d" +"G:\Programmieren\libutils\source\system\AsyncDeleter.cpp" +"G:\Programmieren\libutils\release\gettext.d" +"G:\Programmieren\libutils\release\AsyncDeleter.d" +"G:\Programmieren\libutils\source\system\CMutex.h" +"G:\Programmieren\libutils\source\fs\DirList.cpp" +"G:\Programmieren\libutils\release\StringTools.d" +"G:\Programmieren\libutils\source\utils\net.c" +"G:\Programmieren\libutils\release\utils.d" +"G:\Programmieren\libutils\source\fs\FSUtils.h" +"G:\Programmieren\libutils\source\utils\net.h" +"G:\Programmieren\libutils\release\TCPServer.d" +"G:\Programmieren\libutils\release\FSOSUtils.d" +"G:\Programmieren\libutils\source\system\CThread.h" +"G:\Programmieren\libutils\source\fs\FSOSUtils.h" +"G:\Programmieren\libutils\source\utils\utils.h" +"G:\Programmieren\libutils\source\utils\StringTools.cpp" +"G:\Programmieren\libutils\source\fs\disc_io.h" +"G:\Programmieren\libutils\source\utils\TCPServer.hpp" +"G:\Programmieren\libutils\source\utils\function_patcher.cpp" +"G:\Programmieren\libutils\source\fs\sd_fat_devoptab.cpp" +"G:\Programmieren\libutils\source\utils\utils.c" +"G:\Programmieren\libutils\release\FSUtils.d" +"G:\Programmieren\libutils\source\system\exception_handler.h" +"G:\Programmieren\libutils\source\system\memory.h" +"G:\Programmieren\libutils\source\fs\sd_fat_devoptab.h" +"G:\Programmieren\libutils\source\kernel\kernel_defs.h" +"G:\Programmieren\libutils\source\utils\function_patcher.h" +"G:\Programmieren\libutils\source\kernel\syscalls.h" +"G:\Programmieren\libutils\source\system\exception_handler.c" +"G:\Programmieren\libutils\source\fs\CFile.hpp" +"G:\Programmieren\libutils\release\DirList.d" +"G:\Programmieren\libutils\release\exception_handler.d" +"G:\Programmieren\libutils\source\utils\utils_asm.s" +"G:\Programmieren\libutils\source\fs\FSOSUtils.cpp" +"G:\Programmieren\libutils\source\kernel\syscalls_asm.s" +"G:\Programmieren\libutils\release\CFile.d" +"G:\Programmieren\libutils\source\utils\StringTools.h" +"G:\Programmieren\libutils\source\language\gettext.cpp" +"G:\Programmieren\libutils\release\syscalls_asm.d" +"G:\Programmieren\libutils\release\net.d" +"G:\Programmieren\libutils\release\logger.d" +"G:\Programmieren\libutils\release\sd_fat_devoptab.d" +"G:\Programmieren\libutils\source\system\AsyncDeleter.h" +"G:\Programmieren\libutils\release\utils_asm.d" +"G:\Programmieren\libutils\source\language\gettext.h" diff --git a/libutils.layout b/libutils.layout new file mode 100644 index 0000000..77ac67d --- /dev/null +++ b/libutils.layout @@ -0,0 +1,4 @@ + + + + diff --git a/source/fs/FSOSUtils.cpp b/source/fs/FSOSUtils.cpp deleted file mode 100644 index 22bd56d..0000000 --- a/source/fs/FSOSUtils.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include -#include "FSOSUtils.h" -#include -#include -#include - -s32 FSOSUtils::MountFS(void *pClient, void *pCmd, char **mount_path) { - InitOSFunctionPointers(); - InitFSFunctionPointers(); - s32 result = -1; - - void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE); - if(!mountSrc) - return -3; - - char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE); - if(!mountPath) { - free(mountSrc); - mountSrc = NULL; - return -4; - } - - memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE); - memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); - - // Mount sdcard - if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0) { - result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); - if((result == 0) && mount_path) { - *mount_path = (char*)malloc(strlen(mountPath) + 1); - if(*mount_path) - strcpy(*mount_path, mountPath); - } - } - - free(mountPath); - free(mountSrc); - - mountPath = NULL; - mountSrc = NULL; - - return result; -} - -s32 FSOSUtils::UmountFS(void *pClient, void *pCmd, const char *mountPath) { - s32 result = -1; - result = FSUnmount(pClient, pCmd, mountPath, -1); - - return result; -} diff --git a/source/fs/FSOSUtils.h b/source/fs/FSOSUtils.h deleted file mode 100644 index 44d4a2e..0000000 --- a/source/fs/FSOSUtils.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __FS_OS_UTILS_H_ -#define __FS_OS_UTILS_H_ - -#include - -class FSOSUtils { -public: - - static s32 MountFS(void *pClient, void *pCmd, char **mount_path); - static s32 UmountFS(void *pClient, void *pCmd, const char *mountPath); -}; - -#endif // __FS_OS_UTILS_H_ diff --git a/source/fs/sd_fat_devoptab.cpp b/source/fs/sd_fat_devoptab.cpp deleted file mode 100644 index 6f51511..0000000 --- a/source/fs/sd_fat_devoptab.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * 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. - ***************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "disc_io.h" -#include "FSOSUtils.h" -#include "sd_fat_devoptab.h" -#include "utils/StringTools.h" -#include "utils/logger.h" - -#define FS_ALIGNMENT 0x40 -#define FS_ALIGN(x) (((x) + FS_ALIGNMENT - 1) & ~(FS_ALIGNMENT - 1)) - -typedef struct _sd_fat_private_t { - char *mount_path; - void *pClient; - void *pCmd; - void *pMutex; -} sd_fat_private_t; - -typedef struct _sd_fat_file_state_t { - sd_fat_private_t *dev; - int fd; /* File descriptor */ - int flags; /* Opening flags */ - bool read; /* True if allowed to read from file */ - bool write; /* True if allowed to write to file */ - bool append; /* True if allowed to append to file */ - u64 pos; /* Current position within the file (in bytes) */ - u64 len; /* Total length of the file (in bytes) */ - struct _sd_fat_file_state_t *prevOpenFile; /* The previous entry in a double-linked FILO list of open files */ - struct _sd_fat_file_state_t *nextOpenFile; /* The next entry in a double-linked FILO list of open files */ -} sd_fat_file_state_t; - -typedef struct _sd_fat_dir_entry_t { - sd_fat_private_t *dev; - int dirHandle; -} sd_fat_dir_entry_t; - -static sd_fat_private_t *sd_fat_get_device_data(const char *path) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Search the devoptab table for the specified device name - // NOTE: We do this manually due to a 'bug' in GetDeviceOpTab - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - return (sd_fat_private_t *)devoptab->deviceData; - } - } - } - - return NULL; -} - -static char *sd_fat_real_path (const char *path, sd_fat_private_t *dev) { - // Sanity check - if (!path) - return NULL; - - // Move the path pointer to the start of the actual path - if (strchr(path, ':') != NULL) { - path = strchr(path, ':') + 1; - } - - int mount_len = strlen(dev->mount_path); - - char *new_name = (char*)malloc(mount_len + strlen(path) + 1); - if(new_name) { - strcpy(new_name, dev->mount_path); - strcpy(new_name + mount_len, path); - return new_name; - } - return new_name; -} - -static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fileStruct; - - file->dev = dev; - // Determine which mode the file is opened for - file->flags = flags; - - const char *mode_str; - - if ((flags & 0x03) == O_RDONLY) { - file->read = true; - file->write = false; - file->append = false; - mode_str = "r"; - } else if ((flags & 0x03) == O_WRONLY) { - file->read = false; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a" : "w"; - } else if ((flags & 0x03) == O_RDWR) { - file->read = true; - file->write = true; - file->append = (flags & O_APPEND); - mode_str = file->append ? "a+" : "r+"; - } else { - r->_errno = EACCES; - return -1; - } - - s32 fd = -1; - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, &fd, -1); - - free(real_path); - - if(result == 0) { - FSStat stats; - result = FSGetStatFile(dev->pClient, dev->pCmd, fd, &stats, -1); - if(result != 0) { - FSCloseFile(dev->pClient, dev->pCmd, fd, -1); - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - file->fd = fd; - file->pos = 0; - file->len = stats.size; - OSUnlockMutex(dev->pMutex); - return (int)file; - } - - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; -} - - -static int sd_fat_close_r (struct _reent *r, void *fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSCloseFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static off_t sd_fat_seek_r (struct _reent *r, void* fd, off_t pos, int dir) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - switch(dir) { - case SEEK_SET: - file->pos = pos; - break; - case SEEK_CUR: - file->pos += pos; - break; - case SEEK_END: - file->pos = file->len + pos; - break; - default: - r->_errno = EINVAL; - return -1; - } - - int result = FSSetPosFile(file->dev->pClient, file->dev->pCmd, file->fd, file->pos, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result == 0) { - return file->pos; - } - - return result; -} - -static ssize_t sd_fat_write_r (struct _reent *r, void *fd, const char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->write) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t write_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - memcpy(tmpBuf, ptr + done, write_size); - - int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - break; - } else if(result == 0) { - if(write_size > 0) - done = 0; - break; - } else { - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - -static ssize_t sd_fat_read_r (struct _reent *r, void* fd, char *ptr, size_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return 0; - } - - if(!file->read) { - r->_errno = EACCES; - return 0; - } - - OSLockMutex(file->dev->pMutex); - - size_t len_aligned = FS_ALIGN(len); - if(len_aligned > 0x4000) - len_aligned = 0x4000; - - unsigned char *tmpBuf = (unsigned char *)memalign(FS_ALIGNMENT, len_aligned); - if(!tmpBuf) { - r->_errno = ENOMEM; - OSUnlockMutex(file->dev->pMutex); - return 0; - } - - size_t done = 0; - - while(done < len) { - size_t read_size = (len_aligned < (len - done)) ? len_aligned : (len - done); - - int result = FSReadFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, read_size, file->fd, 0, -1); - if(result < 0) { - r->_errno = result; - done = 0; - break; - } else if(result == 0) { - //! TODO: error on read_size > 0 - break; - } else { - memcpy(ptr + done, tmpBuf, read_size); - done += result; - file->pos += result; - } - } - - free(tmpBuf); - OSUnlockMutex(file->dev->pMutex); - return done; -} - - -static int sd_fat_fstat_r (struct _reent *r, void* fd, struct stat *st) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - FSStat stats; - int result = FSGetStatFile(file->dev->pClient, file->dev->pCmd, file->fd, &stats, -1); - if(result != 0) { - r->_errno = result; - OSUnlockMutex(file->dev->pMutex); - return -1; - } - - st->st_mode = S_IFREG; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - st->st_nlink = 1; - - // Fill in the generic entry stats - st->st_dev = stats.ent_id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.ent_id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - OSUnlockMutex(file->dev->pMutex); - return 0; -} - -static int sd_fat_ftruncate_r (struct _reent *r, void* fd, off_t len) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSTruncateFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_fsync_r (struct _reent *r, void* fd) { - sd_fat_file_state_t *file = (sd_fat_file_state_t *)fd; - if(!file->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(file->dev->pMutex); - - int result = FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1); - - OSUnlockMutex(file->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_stat_r (struct _reent *r, const char *path, struct stat *st) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(st, 0, sizeof(struct stat)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - FSStat stats; - - int result = FSGetStat(dev->pClient, dev->pCmd, real_path, &stats, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // mark root also as directory - st->st_mode = ((stats.flag & 0x80000000) || (strlen(dev->mount_path) + 1 == strlen(real_path)))? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = stats.size; - st->st_blocks = (stats.size + 511) >> 9; - // Fill in the generic entry stats - st->st_dev = stats.ent_id; - st->st_uid = stats.owner_id; - st->st_gid = stats.group_id; - st->st_ino = stats.ent_id; - st->st_atime = stats.mtime; - st->st_ctime = stats.ctime; - st->st_mtime = stats.mtime; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static int sd_fat_link_r (struct _reent *r, const char *existing, const char *newLink) { - r->_errno = ENOTSUP; - return -1; -} - -static int sd_fat_unlink_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - - int result = FSRemove(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_chdir_r (struct _reent *r, const char *name) { - sd_fat_private_t *dev = sd_fat_get_device_data(name); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(name, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSChangeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_rename_r (struct _reent *r, const char *oldName, const char *newName) { - sd_fat_private_t *dev = sd_fat_get_device_data(oldName); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_oldpath = sd_fat_real_path(oldName, dev); - if(!real_oldpath) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - char *real_newpath = sd_fat_real_path(newName, dev); - if(!real_newpath) { - r->_errno = ENOMEM; - free(real_oldpath); - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSRename(dev->pClient, dev->pCmd, real_oldpath, real_newpath, -1); - - free(real_oldpath); - free(real_newpath); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; - -} - -static int sd_fat_mkdir_r (struct _reent *r, const char *path, int mode) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - int result = FSMakeDir(dev->pClient, dev->pCmd, real_path, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - - return 0; -} - -static int sd_fat_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dev->pMutex); - - // Zero out the stat buffer - memset(buf, 0, sizeof(struct statvfs)); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return -1; - } - - u64 size; - - int result = FSGetFreeSpaceSize(dev->pClient, dev->pCmd, real_path, &size, -1); - - free(real_path); - - if(result < 0) { - r->_errno = result; - OSUnlockMutex(dev->pMutex); - return -1; - } - - // File system block size - buf->f_bsize = 512; - - // Fundamental file system block size - buf->f_frsize = 512; - - // Total number of blocks on file system in units of f_frsize - buf->f_blocks = size >> 9; // this is unknown - - // Free blocks available for all and for non-privileged processes - buf->f_bfree = buf->f_bavail = size >> 9; - - // Number of inodes at this point in time - buf->f_files = 0xffffffff; - - // Free inodes available for all and for non-privileged processes - buf->f_ffree = 0xffffffff; - - // File system id - buf->f_fsid = (int)dev; - - // Bit mask of f_flag values. - buf->f_flag = 0; - - // Maximum length of filenames - buf->f_namemax = 255; - - OSUnlockMutex(dev->pMutex); - - return 0; -} - -static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { - sd_fat_private_t *dev = sd_fat_get_device_data(path); - if(!dev) { - r->_errno = ENODEV; - return NULL; - } - - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - - OSLockMutex(dev->pMutex); - - char *real_path = sd_fat_real_path(path, dev); - if(!real_path) { - r->_errno = ENOMEM; - OSUnlockMutex(dev->pMutex); - return NULL; - } - - s32 dirHandle; - - int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, &dirHandle, -1); - - free(real_path); - - OSUnlockMutex(dev->pMutex); - - if(result < 0) { - r->_errno = result; - return NULL; - } - - dirIter->dev = dev; - dirIter->dirHandle = dirHandle; - - return dirState; -} - -static int sd_fat_dirclose_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSCloseDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirreset_r (struct _reent *r, DIR_ITER *dirState) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - int result = FSRewindDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, -1); - - OSUnlockMutex(dirIter->dev->pMutex); - - if(result < 0) { - r->_errno = result; - return -1; - } - return 0; -} - -static int sd_fat_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { - sd_fat_dir_entry_t *dirIter = (sd_fat_dir_entry_t *)dirState->dirStruct; - if(!dirIter->dev) { - r->_errno = ENODEV; - return -1; - } - - OSLockMutex(dirIter->dev->pMutex); - - FSDirEntry * dir_entry = (FSDirEntry *)malloc(sizeof(FSDirEntry)); - - int result = FSReadDir(dirIter->dev->pClient, dirIter->dev->pCmd, dirIter->dirHandle, dir_entry, -1); - if(result < 0) { - free(dir_entry); - r->_errno = result; - OSUnlockMutex(dirIter->dev->pMutex); - return -1; - } - - // Fetch the current entry - strcpy(filename, dir_entry->name); - - if(st) { - memset(st, 0, sizeof(struct stat)); - st->st_mode = (dir_entry->stat.flag & 0x80000000) ? S_IFDIR : S_IFREG; - st->st_nlink = 1; - st->st_size = dir_entry->stat.size; - st->st_blocks = (dir_entry->stat.size + 511) >> 9; - st->st_dev = dir_entry->stat.ent_id; - st->st_uid = dir_entry->stat.owner_id; - st->st_gid = dir_entry->stat.group_id; - st->st_ino = dir_entry->stat.ent_id; - st->st_atime = dir_entry->stat.mtime; - st->st_ctime = dir_entry->stat.ctime; - st->st_mtime = dir_entry->stat.mtime; - } - - free(dir_entry); - OSUnlockMutex(dirIter->dev->pMutex); - return 0; -} - -// SD device driver devoptab -static const devoptab_t devops_sd_fat = { - NULL, /* Device name */ - sizeof (sd_fat_file_state_t), - sd_fat_open_r, - sd_fat_close_r, - sd_fat_write_r, - sd_fat_read_r, - sd_fat_seek_r, - sd_fat_fstat_r, - sd_fat_stat_r, - sd_fat_link_r, - sd_fat_unlink_r, - sd_fat_chdir_r, - sd_fat_rename_r, - sd_fat_mkdir_r, - sizeof (sd_fat_dir_entry_t), - sd_fat_diropen_r, - sd_fat_dirreset_r, - sd_fat_dirnext_r, - sd_fat_dirclose_r, - sd_fat_statvfs_r, - sd_fat_ftruncate_r, - sd_fat_fsync_r, - NULL, /* Device data */ - NULL, /* sd_fat_chmod_r */ - NULL, /* sd_fat_fchmod_r */ - NULL /* sd_fat_rmdir_r */ -}; - - -static int sd_fat_add_device (const char *name, const char *mount_path, void *pClient, void *pCmd) { - devoptab_t *dev = NULL; - char *devname = NULL; - char *devpath = NULL; - int i; - - // Sanity check - if (!name) { - errno = EINVAL; - return -1; - } - - // Allocate a devoptab for this device - dev = (devoptab_t *) malloc(sizeof(devoptab_t) + strlen(name) + 1); - if (!dev) { - errno = ENOMEM; - return -1; - } - - // Use the space allocated at the end of the devoptab for storing the device name - devname = (char*)(dev + 1); - strcpy(devname, name); - - // create private data - int mount_path_len = 0; - if(mount_path != NULL) { - mount_path_len = strlen(mount_path); - } - sd_fat_private_t *priv = (sd_fat_private_t *)malloc(sizeof(sd_fat_private_t) + mount_path_len + 1); - if(!priv) { - free(dev); - errno = ENOMEM; - return -1; - } - - devpath = (char*)(priv+1); - if(mount_path != NULL) { - strcpy(devpath, mount_path); - } - - // setup private data - priv->mount_path = devpath; - priv->pClient = pClient; - priv->pCmd = pCmd; - priv->pMutex = malloc(OS_MUTEX_SIZE); - - if(!priv->pMutex) { - free(dev); - free(priv); - errno = ENOMEM; - return -1; - } - - OSInitMutex(priv->pMutex); - - // Setup the devoptab - memcpy(dev, &devops_sd_fat, sizeof(devoptab_t)); - dev->name = devname; - dev->deviceData = priv; - - // Add the device to the devoptab table (if there is a free slot) - for (i = 3; i < STD_MAX; i++) { - if (devoptab_list[i] == devoptab_list[0]) { - devoptab_list[i] = dev; - return 0; - } - } - - // failure, free all memory - free(priv); - free(dev); - - // If we reach here then there are no free slots in the devoptab table for this device - errno = EADDRNOTAVAIL; - return -1; -} - -/* -Because of some weird reason unmounting doesn't work properly. -This fix if mainly when a usb drive is connected. -It resets the devoptab_list, otherwise mounting again would throw an exception (in strlen). -No memory is free'd here. Maybe a problem?!?!? -*/ - -void deleteDevTabsNames() { - const devoptab_t * devoptab = NULL; - u32 last_entry = (u32) devoptab_list[STD_MAX-1]; - for (int i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - - if (devoptab) { - //log_printf("check devotab %d %08X\n",i,devoptab); - if((u32) devoptab != last_entry) { - devoptab_list[i] = (const devoptab_t *)last_entry; - //log_printf("Removed devotab %d %08X %08X %08X\n",i,devoptab,devoptab->name,devoptab->deviceData); - } - } - } -} - -static int sd_fat_remove_device (const char *path, void **pClient, void **pCmd, char **mountPath) { - const devoptab_t *devoptab = NULL; - char name[128] = {0}; - int i; - - // Get the device name from the path - strncpy(name, path, 127); - strtok(name, ":/"); - - // Find and remove the specified device from the devoptab table - // NOTE: We do this manually due to a 'bug' in RemoveDevice - // which ignores names with suffixes and causes names - // like "ntfs" and "ntfs1" to be seen as equals - for (i = 3; i < STD_MAX; i++) { - devoptab = devoptab_list[i]; - if (devoptab && devoptab->name) { - if (strcmp(name, devoptab->name) == 0) { - devoptab_list[i] = devoptab_list[0]; - - if(devoptab->deviceData) { - sd_fat_private_t *priv = (sd_fat_private_t *)devoptab->deviceData; - if(pClient != NULL) *pClient = priv->pClient; - if(pCmd != NULL) *pCmd = priv->pCmd; - if(mountPath != NULL) { - *mountPath = (char*) malloc(strlen(priv->mount_path)+1); - if(*mountPath) - strcpy(*mountPath, priv->mount_path); - } - if(priv->pMutex) - free(priv->pMutex); - free(devoptab->deviceData); - } - - free((devoptab_t*)devoptab); - return 0; - } - } - } - - return -1; -} - -s32 mount_sd_fat(const char *path) { - int result = -1; - - // get command and client - void* pClient = malloc(FS_CLIENT_SIZE); - void* pCmd = malloc(FS_CMD_BLOCK_SIZE); - - if(!pClient || !pCmd) { - // just in case free if not 0 - if(pClient) - free(pClient); - if(pCmd) - free(pCmd); - return -2; - } - - FSInit(); - FSInitCmdBlock(pCmd); - FSAddClientEx(pClient, 0, -1); - - char *mountPath = NULL; - - if(FSOSUtils::MountFS(pClient, pCmd, &mountPath) == 0) { - result = sd_fat_add_device(path, mountPath, pClient, pCmd); - free(mountPath); - } - - return result; -} - -s32 unmount_sd_fat(const char *path) { - void *pClient = 0; - void *pCmd = 0; - char *mountPath = 0; - - int result = sd_fat_remove_device(path, &pClient, &pCmd, &mountPath); - if(result == 0) { - FSOSUtils::UmountFS(pClient, pCmd, mountPath); - FSDelClient(pClient); - free(pClient); - free(pCmd); - free(mountPath); - //FSShutdown(); - } - return result; -} - -s32 mount_fake() { - return sd_fat_add_device("fake", NULL, NULL, NULL); -} - -s32 unmount_fake() { - return sd_fat_remove_device ("fake", NULL,NULL,NULL); -} diff --git a/source/fs/sd_fat_devoptab.h b/source/fs/sd_fat_devoptab.h deleted file mode 100644 index af28db7..0000000 --- a/source/fs/sd_fat_devoptab.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 - * 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. - ***************************************************************************/ -#ifndef __SD_FAT_DEVOPTAB_H_ -#define __SD_FAT_DEVOPTAB_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -s32 mount_sd_fat(const char *path); -s32 unmount_sd_fat(const char *path); -s32 mount_fake(); -s32 unmount_fake(); -void deleteDevTabsNames(); -#ifdef __cplusplus -} -#endif - -#endif // __SD_FAT_DEVOPTAB_H_ diff --git a/source/kernel/kernel_defs.h b/source/kernel/kernel_defs.h deleted file mode 100644 index fc60d62..0000000 --- a/source/kernel/kernel_defs.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef __KERNEL_DEFS_H_ -#define __KERNEL_DEFS_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// original structure in the kernel that is originally 0x1270 long -typedef struct { - uint32_t version_cos_xml; // version tag from cos.xml - uint64_t os_version; // os_version from app.xml - uint64_t title_id; // title_id tag from app.xml - uint32_t app_type; // app_type tag from app.xml - uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure) - char rpx_name[0x1000]; // rpx name from cos.xml - uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?) - uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2 - uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app - uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?) - uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?) - uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?) - uint32_t max_codesize; // max_codesize in cos.xml - uint32_t overlay_arena; // overlay_arena in cos.xml - uint32_t unknown4[59]; // all zeros it seems - uint32_t default_stack0_size; // not sure because always 0 but very likely - uint32_t default_stack1_size; // not sure because always 0 but very likely - uint32_t default_stack2_size; // not sure because always 0 but very likely - uint32_t default_redzone0_size; // not sure because always 0 but very likely - uint32_t default_redzone1_size; // not sure because always 0 but very likely - uint32_t default_redzone2_size; // not sure because always 0 but very likely - uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker - uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker - uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker - uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker - uint32_t title_version; // from app.xml, 0x32 on mii maker - /* - // --------------------------------------------------------------------------------------------------------------------------------------------- - // the next part might be changing from title to title?! I don't think its important but nice to know maybe.... - // --------------------------------------------------------------------------------------------------------------------------------------------- - char mlc[4]; // string "mlc" on mii maker and sysmenu - uint32_t unknown5[7]; // all zeros on mii maker and sysmenu - uint32_t unknown6_one; // 0x01 on mii maker and sysmenu - // --------------------------------------------------------------------------------------------------------------------------------------------- - char ACP[4]; // string "ACP" on mii maker and sysmenu - uint32_t unknown7[15]; // all zeros on mii maker and sysmenu - uint32_t unknown8_5; // 0x05 on mii maker and sysmenu - uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu - uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu - // --------------------------------------------------------------------------------------------------------------------------------------------- - char UVD[4]; // string "UVD" on mii maker and sysmenu - uint32_t unknown11[15]; // all zeros on mii maker and sysmenu - uint32_t unknown12_5; // 0x05 on mii maker and sysmenu - uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu - uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu - // --------------------------------------------------------------------------------------------------------------------------------------------- - char SND[4]; // string "SND" on mii maker and sysmenu - uint32_t unknown15[15]; // all zeros on mii maker and sysmenu - uint32_t unknown16_5; // 0x05 on mii maker and sysmenu - uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu - uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu - // --------------------------------------------------------------------------------------------------------------------------------------------- - uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu - */ - // after that only zeros follow -} __attribute__((packed)) CosAppXmlInfo; - - -// Our own cos/app.xml struct which uses only uses as much memory as really needed, since many things are just zeros in the above structure -// This structure is only 0x64 bytes long + RPX name length (dynamic up to 0x1000 theoretically) -typedef struct { - uint32_t version_cos_xml; // version tag from cos.xml - uint64_t os_version; // os_version from app.xml - uint64_t title_id; // title_id tag from app.xml - uint32_t app_type; // app_type tag from app.xml - uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure) - uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app - uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?) - uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?) - uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?) - uint32_t max_codesize; // max_codesize in cos.xml - uint32_t overlay_arena; // overlay_arena in cos.xml - uint32_t default_stack0_size; // not sure because always 0 but very likely - uint32_t default_stack1_size; // not sure because always 0 but very likely - uint32_t default_stack2_size; // not sure because always 0 but very likely - uint32_t default_redzone0_size; // not sure because always 0 but very likely - uint32_t default_redzone1_size; // not sure because always 0 but very likely - uint32_t default_redzone2_size; // not sure because always 0 but very likely - uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker - uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker - uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker - uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker - uint32_t title_version; // from app.xml, 0x32 on mii maker - char rpx_name[FS_MAX_ENTNAME_SIZE]; // rpx name from cos.xml, length 256 as it can't get bigger from FS anyway -} __attribute__((packed)) ReducedCosAppXmlInfo; - -#ifdef __cplusplus -} -#endif - -#endif // __KERNEL_DEFS_H_ diff --git a/source/kernel/kernel_utils.c b/source/kernel/kernel_utils.c deleted file mode 100644 index 50ed499..0000000 --- a/source/kernel/kernel_utils.c +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include - -static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len){ - /* - * Setup a DBAT access with cache inhibited to write through and read directly from memory - */ - unsigned int dbatu0, dbatl0, dbatu1, dbatl1; - // save the original DBAT value - asm volatile("mfdbatu %0, 0" : "=r" (dbatu0)); - asm volatile("mfdbatl %0, 0" : "=r" (dbatl0)); - asm volatile("mfdbatu %0, 1" : "=r" (dbatu1)); - asm volatile("mfdbatl %0, 1" : "=r" (dbatl1)); - - unsigned int target_dbatu0 = 0; - unsigned int target_dbatl0 = 0; - unsigned int target_dbatu1 = 0; - unsigned int target_dbatl1 = 0; - - unsigned char *dst_p = (unsigned char*)addr; - unsigned char *src_p = (unsigned char*)src; - - // we only need DBAT modification for addresses out of our own DBAT range - // as our own DBAT is available everywhere for user and supervisor - // since our own DBAT is on DBAT5 position we don't collide here - if(addr < 0x00800000 || addr >= 0x01000000) - { - target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F; - target_dbatl0 = (addr & 0xFFF00000) | 0x32; - asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); - asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); - dst_p = (unsigned char*)((addr & 0xFFFFFF) | 0xC0000000); - } - if(src < 0x00800000 || src >= 0x01000000) - { - target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F; - target_dbatl1 = (src & 0xFFF00000) | 0x32; - - asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); - asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); - src_p = (unsigned char*)((src & 0xFFFFFF) | 0xB0000000); - } - - asm volatile("eieio; isync"); - - unsigned int i; - for(i = 0; i < len; i++) - { - // if we are on the edge to next chunk - if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000))) - { - target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F; - target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32; - dst_p = (unsigned char*)(((addr + i) & 0xFFFFFF) | 0xC0000000); - - asm volatile("eieio; isync"); - asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); - asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); - asm volatile("eieio; isync"); - } - if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000))) - { - target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F; - target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32; - src_p = (unsigned char*)(((src + i) & 0xFFFFFF) | 0xB0000000); - - asm volatile("eieio; isync"); - asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); - asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); - asm volatile("eieio; isync"); - } - - *dst_p = *src_p; - - ++dst_p; - ++src_p; - } - - /* - * Restore original DBAT value - */ - asm volatile("eieio; isync"); - asm volatile("mtdbatu 0, %0" : : "r" (dbatu0)); - asm volatile("mtdbatl 0, %0" : : "r" (dbatl0)); - asm volatile("mtdbatu 1, %0" : : "r" (dbatu1)); - asm volatile("mtdbatl 1, %0" : : "r" (dbatl1)); - asm volatile("eieio; isync"); -} - -/* Read a 32-bit word with kernel permissions */ -uint32_t __attribute__ ((noinline)) kern_read(const void *addr) -{ - uint32_t result; - asm volatile ( - "li 3,1\n" - "li 4,0\n" - "li 5,0\n" - "li 6,0\n" - "li 7,0\n" - "lis 8,1\n" - "mr 9,%1\n" - "li 0,0x3400\n" - "mr %0,1\n" - "sc\n" - "nop\n" - "mr 1,%0\n" - "mr %0,3\n" - : "=r"(result) - : "b"(addr) - : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", - "11", "12" - ); - - return result; -} - -/* 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" - ); -} - -void init_kernel_syscalls(){ - kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x25 * 4)), (unsigned int)KernelCopyData); - kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x25 * 4)), (unsigned int)KernelCopyData); - kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x25 * 4)), (unsigned int)KernelCopyData); - kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x25 * 4)), (unsigned int)KernelCopyData); - kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x25 * 4)), (unsigned int)KernelCopyData); -} \ No newline at end of file diff --git a/source/kernel/kernel_utils.h b/source/kernel/kernel_utils.h deleted file mode 100644 index b7d25a7..0000000 --- a/source/kernel/kernel_utils.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __KERNEL_UTILS_H_ -#define __KERNEL_UTILS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void init_kernel_syscalls(); - -#ifdef __cplusplus -} -#endif - -#endif // __KERNEL_UTILS_H_ diff --git a/source/kernel/syscalls.h b/source/kernel/syscalls.h deleted file mode 100644 index 2af3d56..0000000 --- a/source/kernel/syscalls.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __SYSCALLS_H_ -#define __SYSCALLS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "kernel_defs.h" - -void SC0x25_KernelCopyData(u32 addr, u32 src, u32 len); - -#ifdef __cplusplus -} -#endif - -#endif // __KERNEL_FUNCTIONS_H_ diff --git a/source/kernel/syscalls_asm.s b/source/kernel/syscalls_asm.s deleted file mode 100644 index 29afb19..0000000 --- a/source/kernel/syscalls_asm.s +++ /dev/null @@ -1,8 +0,0 @@ -# Created by dimok -# Syscalls for kernel that we use - - .globl SC0x25_KernelCopyData -SC0x25_KernelCopyData: - li r0, 0x2500 - sc - blr diff --git a/source/network/FileDownloader.cpp b/source/network/FileDownloader.cpp deleted file mode 100644 index c179628..0000000 --- a/source/network/FileDownloader.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016 Dimok - * Modified by Maschell, 2018 - * - * 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 . - ****************************************************************************/ -#include -#include -#include "FileDownloader.h" -#include -#include "utils/logger.h" -#include "utils/utils.h" - - -bool FileDownloader::getFile(const std::string & downloadUrl, std::string & fileBuffer, ProgressCallback callback, void *arg) { - curl_private_data_t private_data; - private_data.progressCallback = callback; - private_data.progressArg = arg; - private_data.buffer = 0; - private_data.filesize = 0; - private_data.file = 0; - - bool result = internalGetFile(downloadUrl, &private_data); - - if(private_data.filesize > 0 && private_data.buffer) { - fileBuffer.resize(private_data.filesize); - memcpy(&fileBuffer[0], private_data.buffer, private_data.filesize); - } - - if(private_data.buffer) { - free(private_data.buffer); - } - - return result; -} - -bool FileDownloader::getFile(const std::string & downloadUrl, const std::string & outputPath, ProgressCallback callback, void *arg) { - curl_private_data_t private_data; - private_data.progressCallback = callback; - private_data.progressArg = arg; - private_data.buffer = 0; - private_data.filesize = 0; - - s32 res = open(outputPath.c_str(), O_CREAT | O_TRUNC | O_WRONLY); - close(res); - - private_data.file = new CFile(outputPath.c_str(), CFile::WriteOnly); - - if(!private_data.file->isOpen()) { - delete private_data.file; - DEBUG_FUNCTION_LINE("Can not write to file %s\n", outputPath.c_str()); - return false; - } - - bool result = internalGetFile(downloadUrl, &private_data); - - private_data.file->close(); - delete private_data.file; - return result; -} - -bool FileDownloader::internalGetFile(const std::string & downloadUrl, curl_private_data_t * private_data) { - bool result = false; - int resp = 404; - int ret = -1; - CURL * curl = n_curl_easy_init(); - if(!curl) { - return false; - } - - int ssl_context = -1; - - std::string prefix = "https"; - if(strncmp(downloadUrl.c_str(), prefix.c_str(), prefix.size()) == 0) { - DEBUG_FUNCTION_LINE("Needs a SSL context\n"); - ssl_context = NSSLCreateContext(0); - if(ssl_context < 0) { - DEBUG_FUNCTION_LINE("Failed to create SSL Context\n"); - goto exit_error; - } - - // Add all existing certs - for(int i = 100; i<106; i++) { - NSSLAddServerPKI(ssl_context,i); - } - - for(int i = 1001; i<1034; i++) { - NSSLAddServerPKI(ssl_context,i); - } - n_curl_easy_setopt(curl, CURLOPT_GSSAPI_DELEGATION, ssl_context); // Is CURLOPT_NSSL_CONTEXT on the Wii U - } - - n_curl_easy_setopt(curl, CURLOPT_URL, downloadUrl.c_str()); - n_curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, FileDownloader::curlCallback); - n_curl_easy_setopt(curl, CURLOPT_WRITEDATA, private_data); - n_curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - - //n_curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); - - if(private_data->progressCallback) { - n_curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, FileDownloader::curlProgressCallback); - n_curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, private_data); - n_curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); - } - - ret = n_curl_easy_perform(curl); - if(ret) { - DEBUG_FUNCTION_LINE("n_curl_easy_perform ret %i\n", ret); - goto exit_error; - } - - if(!private_data->filesize) { - DEBUG_FUNCTION_LINE("file length is 0\n"); - goto exit_error; - } - - n_curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp); - - if(resp != 200) { - DEBUG_FUNCTION_LINE("response != 200\n"); - goto exit_error; - } - - result = true; - -exit_error: - if(ssl_context >= 0) { - NSSLDestroyContext(ssl_context); - } - - n_curl_easy_cleanup(curl); - return result; -} - -int FileDownloader::curlCallback(void *buffer, int size, int nmemb, void *userp) { - curl_private_data_t *private_data = (curl_private_data_t *)userp; - int read_len = size*nmemb; - - if(private_data->file) { - int res = private_data->file->write((u8*)buffer, read_len); - private_data->filesize += res; - return res; - } else { - if(!private_data->buffer) { - private_data->buffer = (u8*) malloc(read_len); - } else { - u8 *tmp = (u8*) realloc(private_data->buffer, private_data->filesize + read_len); - if(!tmp) { - free(private_data->buffer); - private_data->buffer = NULL; - } else { - private_data->buffer = tmp; - } - } - - if(!private_data->buffer) { - private_data->filesize = 0; - return -1; - } - - memcpy(private_data->buffer + private_data->filesize, buffer, read_len); - private_data->filesize += read_len; - return read_len; - } -} - -int FileDownloader::curlProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { - curl_private_data_t *private_data = (curl_private_data_t *)clientp; - if(private_data->progressCallback) { - private_data->progressCallback(private_data->progressArg, (u32)dlnow, (u32)dltotal); - } - return 0; -} - diff --git a/source/network/FileDownloader.h b/source/network/FileDownloader.h deleted file mode 100644 index ab897f9..0000000 --- a/source/network/FileDownloader.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016 Dimok - * Modified by Maschell, 2018 - * - * 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 . - ****************************************************************************/ -#ifndef _FILE_DOWNLOADER_H -#define _FILE_DOWNLOADER_H - -#include -#include "fs/CFile.hpp" - -class FileDownloader -{ -public: - typedef void (*ProgressCallback)(void *arg, u32 done, u32 total); - - static bool getFile(const std::string & downloadUrl, std::string & fileBuffer, ProgressCallback callback = 0, void *arg = 0); - static bool getFile(const std::string & downloadUrl, const std::string & outputPath, ProgressCallback callback = 0, void *arg = 0); -private: - typedef struct - { - ProgressCallback progressCallback; - void *progressArg; - CFile * file; - u8 *buffer; - u32 filesize; - } curl_private_data_t; - - static bool internalGetFile(const std::string & downloadUrl, curl_private_data_t * private_data); - static int curlCallback(void *buffer, int size, int nmemb, void *userp); - static int curlProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); -}; - -#endif // _FILE_DOWNLOADER_H diff --git a/source/system/exception_handler.c b/source/system/exception_handler.c deleted file mode 100644 index 7a53b00..0000000 --- a/source/system/exception_handler.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include "utils/logger.h" -#include "exception_handler.h" - -#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4 - -#define OS_EXCEPTION_DSI 2 -#define OS_EXCEPTION_ISI 3 -#define OS_EXCEPTION_PROGRAM 6 - - -#define CPU_STACK_TRACE_DEPTH 10 -#define __stringify(rn) #rn - -#define mfspr(_rn) \ -({ register uint32_t _rval = 0; \ - asm volatile("mfspr %0," __stringify(_rn) \ - : "=r" (_rval));\ - _rval; \ -}) - -typedef struct _framerec { - struct _framerec *up; - void *lr; -} frame_rec, *frame_rec_t; - -static const char *exception_names[] = { - "DSI", - "ISI", - "PROGRAM" -}; - -static const char exception_print_formats[18][45] = { - "Exception type %s occurred!\n", // 0 - "GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1 - "GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2 - "GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3 - "GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4 - "GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5 - "GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6 - "GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7 - "GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8 - "LR %08X SRR0 %08x SRR1 %08x\n", // 9 - "DAR %08X DSISR %08X\n", // 10 - "\nSTACK DUMP:", // 11 - " --> ", // 12 - " -->\n", // 13 - "\n", // 14 - "%p", // 15 - "\nCODE DUMP:\n", // 16 - "%p: %08X %08X %08X %08X\n", // 17 -}; - -static unsigned char exception_cb(void * c, unsigned char exception_type) { - char buf[850]; - int pos = 0; - - OSContext *context = (OSContext *) c; - /* - * This part is mostly from libogc. Thanks to the devs over there. - */ - pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]); - pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16], context->gpr[24]); - pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17], context->gpr[25]); - pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18], context->gpr[26]); - pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19], context->gpr[27]); - pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20], context->gpr[28]); - pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21], context->gpr[29]); - pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22], context->gpr[30]); - pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23], context->gpr[31]); - pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1); - - //if(exception_type == OS_EXCEPTION_DSI) { - pos += sprintf(buf + pos, exception_print_formats[10], context->ex1, context->ex0); // this freezes - //} - - void *pc = (void*)context->srr0; - void *lr = (void*)context->lr; - void *r1 = (void*)context->gpr[1]; - register uint32_t i = 0; - register frame_rec_t l,p = (frame_rec_t)lr; - - l = p; - p = r1; - if(!p) - asm volatile("mr %0,%%r1" : "=r"(p)); - - pos += sprintf(buf + pos, exception_print_formats[11]); - - for(i = 0; i < CPU_STACK_TRACE_DEPTH-1 && p->up; p = p->up, i++) { - if(i % 4) - pos += sprintf(buf + pos, exception_print_formats[12]); - else { - if(i > 0) - pos += sprintf(buf + pos, exception_print_formats[13]); - else - pos += sprintf(buf + pos, exception_print_formats[14]); - } - - switch(i) { - case 0: - if(pc) - pos += sprintf(buf + pos, exception_print_formats[15],pc); - break; - case 1: - if(!l) - l = (frame_rec_t)mfspr(8); - pos += sprintf(buf + pos, exception_print_formats[15],(void*)l); - break; - default: - pos += sprintf(buf + pos, exception_print_formats[15],(void*)(p->up->lr)); - break; - } - } - - //if(exception_type == OS_EXCEPTION_DSI) { - uint32_t *pAdd = (uint32_t*)context->srr0; - pos += sprintf(buf + pos, exception_print_formats[16]); - // TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen - for (i = 0; i < 8; i += 4) - pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]); - //} - log_print(buf); - OSFatal(buf); - return 1; -} - -static unsigned char dsi_exception_cb(OSContext * context) { - return exception_cb(context, 0); -} -static unsigned char isi_exception_cb(OSContext * context) { - return exception_cb(context, 1); -} -static unsigned char program_exception_cb(OSContext * context) { - return exception_cb(context, 2); -} - -void setup_os_exceptions(void) { - OSSetExceptionCallback(OS_EXCEPTION_DSI, &dsi_exception_cb); - OSSetExceptionCallback(OS_EXCEPTION_ISI, &isi_exception_cb); - OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb); -} diff --git a/source/system/exception_handler.h b/source/system/exception_handler.h deleted file mode 100644 index 7626f92..0000000 --- a/source/system/exception_handler.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __EXCEPTION_HANDLER_H_ -#define __EXCEPTION_HANDLER_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void setup_os_exceptions(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/system/memory.c b/source/system/memory.c deleted file mode 100644 index 3925f70..0000000 --- a/source/system/memory.c +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#include -#include -#include -#include "memory.h" - -#define MEMORY_ARENA_1 0 -#define MEMORY_ARENA_2 1 -#define MEMORY_ARENA_3 2 -#define MEMORY_ARENA_4 3 -#define MEMORY_ARENA_5 4 -#define MEMORY_ARENA_6 5 -#define MEMORY_ARENA_7 6 -#define MEMORY_ARENA_8 7 -#define MEMORY_ARENA_FG_BUCKET 8 - -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -//! Memory functions -//! This is the only place where those are needed so lets keep them more or less private -//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern u32 * pMEMAllocFromDefaultHeapEx; -extern u32 * pMEMAllocFromDefaultHeap; -extern u32 * pMEMFreeToDefaultHeap; - -extern s32 (* MEMGetBaseHeapHandle)(s32 mem_arena); -extern u32 (* MEMGetAllocatableSizeForFrmHeapEx)(s32 heap, s32 align); -extern void *(* MEMAllocFromFrmHeapEx)(s32 heap, u32 size, s32 align); -extern void (* MEMFreeToFrmHeap)(s32 heap, s32 mode); -extern void *(* MEMAllocFromExpHeapEx)(s32 heap, u32 size, s32 align); -extern s32 (* MEMCreateExpHeapEx)(void* address, u32 size, unsigned short flags); -extern void *(* MEMDestroyExpHeap)(s32 heap); -extern void (* MEMFreeToExpHeap)(s32 heap, void* ptr); - -static s32 mem1_heap = -1; -static s32 bucket_heap = -1; - -void memoryInitialize(void) { - s32 mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); - u32 mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); - void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); - if(mem1_memory) - mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); - - s32 bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); - u32 bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); - void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); - if(bucket_memory) - bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); -} - -void memoryRelease(void) { - MEMDestroyExpHeap(mem1_heap); - MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3); - mem1_heap = -1; - - MEMDestroyExpHeap(bucket_heap); - MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3); - bucket_heap = -1; -} - -//!------------------------------------------------------------------------------------------- -//! wraps -//!------------------------------------------------------------------------------------------- -void *__wrap_malloc(size_t size) { - // pointer to a function resolve - return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); -} - -void *__wrap_memalign(size_t align, size_t size) { - if (align < 4) - align = 4; - - // pointer to a function resolve - return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); -} - -void __wrap_free(void *p) { - // pointer to a function resolve - if(p != 0) - ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); -} - -void *__wrap_calloc(size_t n, size_t size) { - void *p = __wrap_malloc(n * size); - if (p != 0) { - memset(p, 0, n * size); - } - return p; -} - -size_t __wrap_malloc_usable_size(void *p) { - //! TODO: this is totally wrong and needs to be addressed - return 0x7FFFFFFF; -} - -void *__wrap_realloc(void *ptr, size_t size) { - void *newPtr; - - if (!ptr) { - newPtr = __wrap_malloc(size); - if (!newPtr) { - goto error; - } - } else { - newPtr = __wrap_malloc(size); - if (!newPtr) { - goto error; - } - - memcpy(newPtr, ptr, size); - - __wrap_free(ptr); - } - - return newPtr; -error: - return NULL; -} -/* -void *new_ptr = __wrap_malloc(size); -if (new_ptr != 0) -{ - memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size); - __wrap_free(p); -} -return new_ptr; -}*/ - -//!------------------------------------------------------------------------------------------- -//! reent versions -//!------------------------------------------------------------------------------------------- -void *__wrap__malloc_r(struct _reent *r, size_t size) { - return __wrap_malloc(size); -} - -void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size) { - return __wrap_calloc(n, size); -} - -void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size) { - return __wrap_memalign(align, size); -} - -void __wrap__free_r(struct _reent *r, void *p) { - __wrap_free(p); -} - -size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p) { - return __wrap_malloc_usable_size(p); -} - -void *__wrap__realloc_r(struct _reent *r, void *p, size_t size) { - return __wrap_realloc(p, size); -} - -//!------------------------------------------------------------------------------------------- -//! some wrappers -//!------------------------------------------------------------------------------------------- -void * MEM2_alloc(u32 size, u32 align) { - return __wrap_memalign(align, size); -} - -void MEM2_free(void *ptr) { - __wrap_free(ptr); -} - -void * MEM1_alloc(u32 size, u32 align) { - if (align < 4) - align = 4; - return MEMAllocFromExpHeapEx(mem1_heap, size, align); -} - -void MEM1_free(void *ptr) { - MEMFreeToExpHeap(mem1_heap, ptr); -} - -void * MEMBucket_alloc(u32 size, u32 align) { - if (align < 4) - align = 4; - return MEMAllocFromExpHeapEx(bucket_heap, size, align); -} - -void MEMBucket_free(void *ptr) { - MEMFreeToExpHeap(bucket_heap, ptr); -} diff --git a/source/system/memory.h b/source/system/memory.h deleted file mode 100644 index db67a05..0000000 --- a/source/system/memory.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#ifndef __MEMORY_H_ -#define __MEMORY_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -void memoryInitialize(void); -void memoryRelease(void); - -void * MEM2_alloc(u32 size, u32 align); -void MEM2_free(void *ptr); - -void * MEM1_alloc(u32 size, u32 align); -void MEM1_free(void *ptr); - -void * MEMBucket_alloc(u32 size, u32 align); -void MEMBucket_free(void *ptr); - -#ifdef __cplusplus -} -#endif - -#endif // __MEMORY_H_ diff --git a/source/utils/function_patcher.cpp b/source/utils/function_patcher.cpp deleted file mode 100644 index e58d191..0000000 --- a/source/utils/function_patcher.cpp +++ /dev/null @@ -1,549 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016 Maschell - * With code from chadderz and dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ - -#include -#include -#include -#include -#include - -#include "function_patcher.h" -#include "logger.h" -#include "kernel/kernel_defs.h" -#include "kernel/syscalls.h" - -#define LIB_CODE_RW_BASE_OFFSET 0xC1000000 -#define CODE_RW_BASE_OFFSET 0x00000000 -#define DEBUG_LOG_DYN 0 - -u32 acp_handle_internal = 0; -u32 aoc_handle_internal = 0; -u32 sound_handle_internal = 0; -u32 sound_handle_internal_old = 0; -u32 libcurl_handle_internal = 0; -u32 gx2_handle_internal = 0; -u32 nfp_handle_internal = 0; -u32 nn_act_handle_internal = 0; -u32 nn_nim_handle_internal = 0; -u32 nn_save_handle_internal = 0; -u32 ntag_handle_internal = 0; -u32 coreinit_handle_internal = 0; -u32 padscore_handle_internal = 0; -u32 proc_ui_handle_internal = 0; -u32 nsysnet_handle_internal = 0; -u32 sysapp_handle_internal = 0; -u32 syshid_handle_internal = 0; -u32 vpad_handle_internal = 0; -u32 vpadbase_handle_internal = 0; - -/* -* Patches a function that is loaded at the start of each application. Its not required to restore, at least when they are really dynamic. -* "normal" functions should be patch with the normal patcher. Current Code by Maschell with the help of dimok. Orignal code by Chadderz. -*/ -void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],s32 hook_information_size, volatile u32 dynamic_method_calls[]) { - InitAcquireOS(); - resetLibs(); - - DEBUG_FUNCTION_LINE("Patching %d given functions\n",hook_information_size); - /* Patch branches to it. */ - volatile u32 *space = &dynamic_method_calls[0]; - - s32 method_hooks_count = hook_information_size; - - u32 skip_instr = 1; - u32 my_instr_len = 6; - u32 instr_len = my_instr_len + skip_instr; - u32 flush_len = 4*instr_len; - for(s32 i = 0; i < method_hooks_count; i++) { - DEBUG_FUNCTION_LINE("Patching %s ...",method_hooks[i].functionName); - if(method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) { - if(isDynamicFunction((u32)OSEffectiveToPhysical((void*)method_hooks[i].realAddr))) { - log_printf("The function %s is a dynamic function. Please fix that <3\n", method_hooks[i].functionName); - method_hooks[i].functionType = DYNAMIC_FUNCTION; - } else { - log_printf("Skipping %s, its already patched\n", method_hooks[i].functionName); - space += instr_len; - continue; - } - } - - u32 physical = 0; - u32 repl_addr = (u32)method_hooks[i].replaceAddr; - u32 call_addr = (u32)method_hooks[i].replaceCall; - - u32 real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library); - - if(!real_addr) { - log_printf("\n"); - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName); - space += instr_len; - continue; - } - - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s is located at %08X!\n", method_hooks[i].functionName,real_addr); - } - - physical = (u32)OSEffectiveToPhysical((void*)real_addr); - if(!physical) { - log_printf("Error. Something is wrong with the physical address\n"); - space += instr_len; - continue; - } - - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", method_hooks[i].functionName,physical); - } - - *(volatile u32 *)(call_addr) = (u32)(space) - CODE_RW_BASE_OFFSET; - - - SC0x25_KernelCopyData((u32)space, physical, 4); - space++; - - //Only works if skip_instr == 1 - if(skip_instr == 1) { - // fill the restore instruction section - method_hooks[i].realAddr = real_addr; - method_hooks[i].restoreInstruction = *(space-1); - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!\n", method_hooks[i].realAddr); - } - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!\n",method_hooks[i].restoreInstruction) ; - } - } else { - log_printf("Error. Can't save %s for restoring!\n", method_hooks[i].functionName); - } - - //adding jump to real function thx @ dimok for the assembler code - /* - 90 61 ff e0 stw r3,-32(r1) - 3c 60 12 34 lis r3,4660 - 60 63 56 78 ori r3,r3,22136 - 7c 69 03 a6 mtctr r3 - 80 61 ff e0 lwz r3,-32(r1) - 4e 80 04 20 bctr*/ - *space = 0x9061FFE0; - space++; - *space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h - space++; - *space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l - space++; - *space = 0x7C6903A6; // mtctr r3 - space++; - *space = 0x8061FFE0; // lwz r3,-32(r1) - space++; - *space = 0x4E800420; // bctr - space++; - DCFlushRange((void*)(space - instr_len), flush_len); - ICInvalidateRange((unsigned char*)(space - instr_len), flush_len); - - //setting jump back - u32 replace_instr = 0x48000002 | (repl_addr & 0x03fffffc); - DCFlushRange(&replace_instr, 4); - - SC0x25_KernelCopyData(physical, (u32)OSEffectiveToPhysical(&replace_instr), 4); - ICInvalidateRange((void*)(real_addr), 4); - - method_hooks[i].alreadyPatched = 1; - log_printf("done!\n"); - - } - DEBUG_FUNCTION_LINE("Done with patching given functions!\n"); -} - -/* ****************************************************************** */ -/* RESTORE ORIGINAL INSTRUCTIONS */ -/* ****************************************************************** */ -void RestoreInvidualInstructions(hooks_magic_t method_hooks[],s32 hook_information_size) { - InitAcquireOS(); - resetLibs(); - DEBUG_FUNCTION_LINE("Restoring given functions!\n"); - s32 method_hooks_count = hook_information_size; - for(s32 i = 0; i < method_hooks_count; i++) { - DEBUG_FUNCTION_LINE("Restoring %s... ",method_hooks[i].functionName); - if(method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) { - log_printf("I dont have the information for the restore =( skip\n"); - continue; - } - - u32 real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library); - - if(!real_addr) { - log_printf("OSDynLoad_FindExport failed for %s\n", method_hooks[i].functionName); - continue; - } - - u32 physical = (u32)OSEffectiveToPhysical((void*)real_addr); - if(!physical) { - log_printf("Something is wrong with the physical address\n"); - continue; - } - - if(isDynamicFunction(physical)) { - log_printf("Its a dynamic function. We don't need to restore it!\n",method_hooks[i].functionName); - } else { - physical = (u32)OSEffectiveToPhysical((void*)method_hooks[i].realAddr); //When its an static function, we need to use the old location - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(u32)method_hooks[i].restoreInstruction,physical); - } - SC0x25_KernelCopyData(physical,(u32)&method_hooks[i].restoreInstruction , 4); - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)method_hooks[i].realAddr); - } - ICInvalidateRange((void*)method_hooks[i].realAddr, 4); - log_printf("done\n"); - } - method_hooks[i].alreadyPatched = 0; // In case a - } - - DEBUG_FUNCTION_LINE("Done with restoring given functions!\n"); -} - -s32 isDynamicFunction(u32 physicalAddress) { - if((physicalAddress & 0x80000000) == 0x80000000) { - return 1; - } - return 0; -} - -u32 GetAddressOfFunction(const char * functionName,u32 library) { - u32 real_addr = 0; - - if(strcmp(functionName, "OSDynLoad_Acquire") == 0) { - memcpy(&real_addr, &OSDynLoad_Acquire, 4); - return real_addr; - } else if(strcmp(functionName, "LiWaitOneChunk") == 0) { - real_addr = (u32)addr_LiWaitOneChunk; - return real_addr; - } else if(strcmp(functionName, "LiBounceOneChunk") == 0) { - //! not required on firmwares above 3.1.0 - if(OS_FIRMWARE >= 400) - return 0; - - u32 addr_LiBounceOneChunk = 0x010003A0; - real_addr = (u32)addr_LiBounceOneChunk; - return real_addr; - } - - u32 rpl_handle = 0; - if(library == LIB_CORE_INIT) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_CORE_INIT\n", functionName); - } - if(coreinit_handle_internal == 0) { - OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); - } - if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_CORE_INIT failed to acquire\n"); - return 0; - } - rpl_handle = coreinit_handle_internal; - } else if(library == LIB_NSYSNET) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NSYSNET\n", functionName); - } - if(nsysnet_handle_internal == 0) { - OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal); - } - if(nsysnet_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_NSYSNET failed to acquire\n"); - return 0; - } - rpl_handle = nsysnet_handle_internal; - } else if(library == LIB_GX2) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_GX2\n", functionName); - } - if(gx2_handle_internal == 0) { - OSDynLoad_Acquire("gx2.rpl", &gx2_handle_internal); - } - if(gx2_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_GX2 failed to acquire\n"); - return 0; - } - rpl_handle = gx2_handle_internal; - } else if(library == LIB_AOC) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AOC\n", functionName); - } - if(aoc_handle_internal == 0) { - OSDynLoad_Acquire("nn_aoc.rpl", &aoc_handle_internal); - } - if(aoc_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_AOC failed to acquire\n"); - return 0; - } - rpl_handle = aoc_handle_internal; - } else if(library == LIB_AX) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX\n", functionName); - } - if(sound_handle_internal == 0) { - OSDynLoad_Acquire("sndcore2.rpl", &sound_handle_internal); - } - if(sound_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_AX failed to acquire\n"); - return 0; - } - rpl_handle = sound_handle_internal; - } else if(library == LIB_AX_OLD) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX_OLD\n", functionName); - } - if(sound_handle_internal_old == 0) { - OSDynLoad_Acquire("snd_core.rpl", &sound_handle_internal_old); - } - if(sound_handle_internal_old == 0) { - DEBUG_FUNCTION_LINE("LIB_AX_OLD failed to acquire\n"); - return 0; - } - rpl_handle = sound_handle_internal_old; - } else if(library == LIB_FS) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_FS\n", functionName); - } - if(coreinit_handle_internal == 0) { - OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); - } - if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_FS failed to acquire\n"); - return 0; - } - rpl_handle = coreinit_handle_internal; - } else if(library == LIB_OS) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_OS\n", functionName); - } - if(coreinit_handle_internal == 0) { - OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal); - } - if(coreinit_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_OS failed to acquire\n"); - return 0; - } - rpl_handle = coreinit_handle_internal; - } else if(library == LIB_PADSCORE) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PADSCORE\n", functionName); - } - if(padscore_handle_internal == 0) { - OSDynLoad_Acquire("padscore.rpl", &padscore_handle_internal); - } - if(padscore_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_PADSCORE failed to acquire\n"); - return 0; - } - rpl_handle = padscore_handle_internal; - } else if(library == LIB_SOCKET) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SOCKET\n", functionName); - } - if(nsysnet_handle_internal == 0) { - OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal); - } - if(nsysnet_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SOCKET failed to acquire\n"); - return 0; - } - rpl_handle = nsysnet_handle_internal; - } else if(library == LIB_SYS) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYS\n", functionName); - } - if(sysapp_handle_internal == 0) { - OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle_internal); - } - if(sysapp_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SYS failed to acquire\n"); - return 0; - } - rpl_handle = sysapp_handle_internal; - } else if(library == LIB_VPAD) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPAD\n", functionName); - } - if(vpad_handle_internal == 0) { - OSDynLoad_Acquire("vpad.rpl", &vpad_handle_internal); - } - if(vpad_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_VPAD failed to acquire\n"); - return 0; - } - rpl_handle = vpad_handle_internal; - } else if(library == LIB_NN_ACP) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NN_ACP\n", functionName); - } - if(acp_handle_internal == 0) { - OSDynLoad_Acquire("nn_acp.rpl", &acp_handle_internal); - } - if(acp_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_NN_ACP failed to acquire\n"); - return 0; - } - rpl_handle = acp_handle_internal; - } else if(library == LIB_SYSHID) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYSHID\n", functionName); - } - if(syshid_handle_internal == 0) { - OSDynLoad_Acquire("nsyshid.rpl", &syshid_handle_internal); - } - if(syshid_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_SYSHID failed to acquire\n"); - return 0; - } - rpl_handle = syshid_handle_internal; - } else if(library == LIB_VPADBASE) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPADBASE\n", functionName); - } - if(vpadbase_handle_internal == 0) { - OSDynLoad_Acquire("vpadbase.rpl", &vpadbase_handle_internal); - } - if(vpadbase_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_VPADBASE failed to acquire\n"); - return 0; - } - rpl_handle = vpadbase_handle_internal; - } else if(library == LIB_PROC_UI) { - if(DEBUG_LOG_DYN) { - DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PROC_UI\n", functionName); - } - if(proc_ui_handle_internal == 0) { - OSDynLoad_Acquire("proc_ui.rpl", &proc_ui_handle_internal); - } - if(proc_ui_handle_internal == 0) { - DEBUG_FUNCTION_LINE("LIB_PROC_UI failed to acquire\n"); - return 0; - } - rpl_handle = proc_ui_handle_internal; - } else if(library == LIB_NTAG) { - if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NTAG\n", functionName); - } - if(ntag_handle_internal == 0) { - OSDynLoad_Acquire("ntag.rpl", &ntag_handle_internal); - } - if(ntag_handle_internal == 0) { - log_print("LIB_NTAG failed to acquire\n"); - return 0; - } - rpl_handle = ntag_handle_internal; - } else if(library == LIB_NFP) { - if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NFP\n", functionName); - } - if(nfp_handle_internal == 0) { - OSDynLoad_Acquire("nn_nfp.rpl", &nfp_handle_internal); - } - if(nfp_handle_internal == 0) { - log_print("LIB_NFP failed to acquire\n"); - return 0; - } - rpl_handle = nfp_handle_internal; - } else if(library == LIB_SAVE) { - if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_SAVE\n", functionName); - } - if(nn_save_handle_internal == 0) { - OSDynLoad_Acquire("nn_save.rpl", &nn_save_handle_internal); - } - if(nn_save_handle_internal == 0) { - log_print("LIB_SAVE failed to acquire\n"); - return 0; - } - rpl_handle = nn_save_handle_internal; - } else if(library == LIB_ACT) { - if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_ACT\n", functionName); - } - if(nn_act_handle_internal == 0) { - OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle_internal); - } - if(nn_act_handle_internal == 0) { - log_print("LIB_ACT failed to acquire\n"); - return 0; - } - rpl_handle = nn_act_handle_internal; - } else if(library == LIB_NIM) { - if(DEBUG_LOG_DYN) { - log_printf("FindExport of %s! From LIB_NIM\n", functionName); - } - if(nn_nim_handle_internal == 0) { - OSDynLoad_Acquire("nn_nim.rpl", &nn_nim_handle_internal); - } - if(nn_nim_handle_internal == 0) { - log_print("LIB_NIM failed to acquire\n"); - return 0; - } - rpl_handle = nn_nim_handle_internal; - } - - if(!rpl_handle) { - DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName); - return 0; - } - - OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr); - - if(!real_addr) { - OSDynLoad_FindExport(rpl_handle, 1, functionName, &real_addr); - if(!real_addr) { - DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName); - return 0; - } - } - - if((library == LIB_NN_ACP) && (u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000) { - u32 address_diff = (u32)(*(volatile u32*)(real_addr) & 0x03FFFFFC); - if((address_diff & 0x03000000) == 0x03000000) { - address_diff |= 0xFC000000; - } - real_addr += (s32)address_diff; - if((u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000) { - return 0; - } - } - - return real_addr; -} - -void resetLibs() { - acp_handle_internal = 0; - aoc_handle_internal = 0; - sound_handle_internal = 0; - sound_handle_internal_old = 0; - libcurl_handle_internal = 0; - gx2_handle_internal = 0; - nfp_handle_internal = 0; - nn_act_handle_internal = 0; - nn_nim_handle_internal = 0; - nn_save_handle_internal = 0; - ntag_handle_internal = 0; - coreinit_handle_internal = 0; - padscore_handle_internal = 0; - proc_ui_handle_internal = 0; - nsysnet_handle_internal = 0; - sysapp_handle_internal = 0; - syshid_handle_internal = 0; - vpad_handle_internal = 0; - vpadbase_handle_internal = 0; -} diff --git a/source/utils/function_patcher.h b/source/utils/function_patcher.h deleted file mode 100644 index fcb84a3..0000000 --- a/source/utils/function_patcher.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016 Maschell - * With code from chadderz and dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ - -#ifndef _FUNCTION_HOOKS_H_ -#define _FUNCTION_HOOKS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Macros for libs */ -#define LIB_CORE_INIT 0 -#define LIB_NSYSNET 1 -#define LIB_GX2 2 -#define LIB_AOC 3 -#define LIB_AX 4 -#define LIB_FS 5 -#define LIB_OS 6 -#define LIB_PADSCORE 7 -#define LIB_SOCKET 8 -#define LIB_SYS 9 -#define LIB_VPAD 10 -#define LIB_NN_ACP 11 -#define LIB_SYSHID 12 -#define LIB_VPADBASE 13 -#define LIB_AX_OLD 14 -#define LIB_PROC_UI 15 -#define LIB_NTAG 16 -#define LIB_NFP 17 -#define LIB_SAVE 18 -#define LIB_ACT 19 -#define LIB_NIM 20 - -// functions types -#define STATIC_FUNCTION 0 -#define DYNAMIC_FUNCTION 1 - -//Orignal code by Chadderz. -#define DECL(res, name, ...) \ - res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \ - res my_ ## name(__VA_ARGS__) - -#define FUNCTION_PATCHER_METHOD_STORE_SIZE 7 - -typedef struct { - const u32 replaceAddr; - const u32 replaceCall; - const u32 library; - const char functionName[50]; - u32 realAddr; - u32 restoreInstruction; - u8 functionType; - u8 alreadyPatched; -} hooks_magic_t; - -void PatchInvidualMethodHooks(hooks_magic_t hook_information[],s32 hook_information_size, volatile u32 dynamic_method_calls[]); -void RestoreInvidualInstructions(hooks_magic_t hook_information[],s32 hook_information_size); -u32 GetAddressOfFunction(const char * functionName,u32 library); -s32 isDynamicFunction(u32 physicalAddress); -void resetLibs(); - -//Orignal code by Chadderz. -#define MAKE_MAGIC(x, lib,functionType) { (u32) my_ ## x, (u32) &real_ ## x, lib, # x,0,0,functionType,0} -#define MAKE_MAGIC_NAME(x,y, lib,functionType) { (u32) my_ ## x, (u32) &real_ ## x, lib, # y,0,0,functionType,0} - -#ifdef __cplusplus -} -#endif - -#endif /* _FS_H */ diff --git a/source/utils/utils.h b/source/utils/utils.h deleted file mode 100644 index 39324ed..0000000 --- a/source/utils/utils.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __UTILS_H_ -#define __UTILS_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \ - "icbi %0, %1\n" \ - "sync\n" \ - "eieio\n" \ - "isync\n" \ - : \ - :"r"(0), "r"(((addr) & ~31)) \ - :"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \ - ); - -#define LIMIT(x, min, max) \ - ({ \ - typeof( x ) _x = x; \ - typeof( min ) _min = min; \ - typeof( max ) _max = max; \ - ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ - }) - -#define DegToRad(a) ( (a) * 0.01745329252f ) -#define RadToDeg(a) ( (a) * 57.29577951f ) - -#define ALIGN4(x) (((x) + 3) & ~3) -#define ALIGN32(x) (((x) + 31) & ~31) - -// those work only in powers of 2 -#define ROUNDDOWN(val, align) ((val) & ~(align-1)) -#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) - -#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8))) -#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16))) -#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) - -unsigned int getApplicationEndAddr(void); - -//Need to have log_init() called beforehand. -void dumpHex(const void* data, size_t size); - -#ifdef __cplusplus -} -#endif - -#endif // __UTILS_H_ diff --git a/source/utils/utils_asm.s b/source/utils/utils_asm.s deleted file mode 100644 index b210f76..0000000 --- a/source/utils/utils_asm.s +++ /dev/null @@ -1,5 +0,0 @@ - .globl getApplicationEndAddr -getApplicationEndAddr: - lis r3, __CODE_END@h - ori r3, r3, __CODE_END@l - blr diff --git a/source/fs/CFile.cpp b/src/fs/CFile.cpp similarity index 95% rename from source/fs/CFile.cpp rename to src/fs/CFile.cpp index 8282faf..ce92d94 100644 --- a/source/fs/CFile.cpp +++ b/src/fs/CFile.cpp @@ -1,7 +1,8 @@ #include #include #include -#include "CFile.hpp" +#include +#include CFile::CFile() { iFd = -1; @@ -153,20 +154,17 @@ s32 CFile::seek(long int offset, s32 origin) { } s32 CFile::fwrite(const char *format, ...) { + char tmp[512]; + tmp[0] = 0; s32 result = -1; - char * tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { result = this->write((u8 *)tmp, strlen(tmp)); } va_end(va); - if(tmp) { - free(tmp); - tmp = NULL; - } return result; } diff --git a/source/fs/DirList.cpp b/src/fs/DirList.cpp similarity index 98% rename from source/fs/DirList.cpp rename to src/fs/DirList.cpp index 19cb9ba..51e6702 100644 --- a/source/fs/DirList.cpp +++ b/src/fs/DirList.cpp @@ -28,12 +28,13 @@ #include #include #include +#include #include #include #include -#include "DirList.h" -#include "utils/StringTools.h" +#include +#include DirList::DirList() { Flags = 0; diff --git a/source/fs/FSUtils.cpp b/src/fs/FSUtils.cpp similarity index 97% rename from source/fs/FSUtils.cpp rename to src/fs/FSUtils.cpp index 6de727f..0cb69ef 100644 --- a/source/fs/FSUtils.cpp +++ b/src/fs/FSUtils.cpp @@ -3,9 +3,9 @@ #include #include #include -#include "FSUtils.h" -#include "CFile.hpp" -#include "utils/logger.h" +#include +#include +#include s32 FSUtils::LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size) { //! always initialze input diff --git a/source/language/gettext.cpp b/src/language/gettext.cpp similarity index 95% rename from source/language/gettext.cpp rename to src/language/gettext.cpp index b78429e..e744d31 100644 --- a/source/language/gettext.cpp +++ b/src/language/gettext.cpp @@ -20,9 +20,23 @@ #include #include -#include "gettext.h" -#include "fs/CFile.hpp" -#include "utils/StringTools.h" +#include +#include +#include + + +char* strdup (const char* s) +{ + size_t slen = strlen(s); + char* result = (char *) malloc(slen + 1); + if(result == NULL) + { + return NULL; + } + + memcpy(result, s, slen+1); + return result; +} typedef struct _MSG { u32 id; diff --git a/source/utils/net.c b/src/network/net.c similarity index 80% rename from source/utils/net.c rename to src/network/net.c index 30532de..b097039 100644 --- a/source/utils/net.c +++ b/src/network/net.c @@ -1,12 +1,19 @@ -#include "net.h" -#include -#include +#include +#include +#include +#include +#include +static u32 hostIpAddress __attribute__((section(".data"))) = 0; static volatile int socket_lock __attribute__((section(".data"))) = 0; +void initNetwork(){ + +} + s32 recvwait(s32 sock, void *buffer, s32 len) { while(socket_lock) { - os_usleep(1000); + OSSleepTicks(OSMillisecondsToTicks(1000)); } s32 ret; while (len > 0) { @@ -42,7 +49,7 @@ u32 recvword(s32 sock) { s32 checkbyte(s32 sock) { while(socket_lock) { - os_usleep(1000); + OSSleepTicks(OSMillisecondsToTicks(1000)); } unsigned char buffer[1]; s32 ret; @@ -56,7 +63,7 @@ s32 checkbyte(s32 sock) { s32 sendwait(s32 sock, const void *buffer, s32 len) { while(socket_lock) { - os_usleep(1000); + OSSleepTicks(OSMillisecondsToTicks(1000)); } s32 ret; while (len > 0) { diff --git a/source/system/AsyncDeleter.cpp b/src/system/AsyncDeleter.cpp similarity index 98% rename from source/system/AsyncDeleter.cpp rename to src/system/AsyncDeleter.cpp index f9e5baf..196a1e0 100644 --- a/source/system/AsyncDeleter.cpp +++ b/src/system/AsyncDeleter.cpp @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ -#include "AsyncDeleter.h" +#include AsyncDeleter * AsyncDeleter::deleterInstance = NULL; diff --git a/source/utils/StringTools.cpp b/src/utils/StringTools.cpp similarity index 89% rename from source/utils/StringTools.cpp rename to src/utils/StringTools.cpp index c2a1995..fbd9ad2 100644 --- a/source/utils/StringTools.cpp +++ b/src/utils/StringTools.cpp @@ -30,8 +30,11 @@ #include #include #include -#include -#include "StringTools.h" +#include +#include +#include +#include + bool StringTools::EndsWith(const std::string& a, const std::string& b) { if (b.size() > a.size()) return false; @@ -65,27 +68,23 @@ std::string StringTools::removeCharFromString(std::string& input,char toBeRemove const char * StringTools::fmt(const char * format, ...) { static char strChar[512]; strChar[0] = 0; - char * tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { - snprintf(strChar, sizeof(strChar), tmp); - free(tmp); + if((vsprintf(strChar, format, va) >= 0)) { va_end(va); return (const char *) strChar; } va_end(va); - if(tmp) - free(tmp); - 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; @@ -93,16 +92,12 @@ const wchar_t * StringTools::wfmt(const char * format, ...) { if(strcmp(format, "") == 0) return (const wchar_t *) strWChar; - char * tmp = NULL; - va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { int bt; s32 strlength = strlen(tmp); bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 ); - free(tmp); - tmp = 0; if(bt > 0) { strWChar[bt] = 0; @@ -111,44 +106,37 @@ const wchar_t * StringTools::wfmt(const char * format, ...) { } va_end(va); - if(tmp) - free(tmp); - return NULL; } s32 StringTools::strprintf(std::string &str, const char * format, ...) { + static char tmp[512]; + tmp[0] = 0; s32 result = 0; - char * tmp = NULL; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { str = tmp; result = str.size(); } va_end(va); - if(tmp) - free(tmp); - return result; } std::string StringTools::strfmt(const char * format, ...) { std::string str; - char * tmp = NULL; + static char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { str = tmp; } va_end(va); - if(tmp) - free(tmp); - return str; } diff --git a/source/utils/TCPServer.cpp b/src/utils/TCPServer.cpp similarity index 95% rename from source/utils/TCPServer.cpp rename to src/utils/TCPServer.cpp index 5ea5639..48416ba 100644 --- a/source/utils/TCPServer.cpp +++ b/src/utils/TCPServer.cpp @@ -1,11 +1,10 @@ -#include "TCPServer.hpp" +#include #include #include #include -#include -#include "logger.h" -#include "net.h" +#include +#include #define wiiu_errno (*__gh_errno_ptr()) @@ -48,12 +47,12 @@ void TCPServer::CloseSockets() { void TCPServer::ErrorHandling() { CloseSockets(); - os_usleep(1000*1000*2); + OSSleepTicks(OSMillisecondsToTicks(1000*1000*2)); } void TCPServer::DoTCPThreadInternal() { s32 ret; - s32 len; + socklen_t len; connected = false; while (1) { if(exitThread) { diff --git a/src/utils/elf_utils.cpp b/src/utils/elf_utils.cpp new file mode 100644 index 0000000..f451073 --- /dev/null +++ b/src/utils/elf_utils.cpp @@ -0,0 +1,87 @@ +#include +#include + +#include +#include + + +u32 elf_get_section(u8 *data, const char *name, u32 * size, u32 * 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 *) (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; +} + +bool elf_copy_section(u8 * elf_data, const char * section_name) { + u32 section_addr = 0; + u32 section_len = 0; + u32 section_offset = elf_get_section(elf_data, section_name, §ion_len, §ion_addr, false); + if(section_offset > 0) { + u8 *main_section = elf_data + section_offset; + memcpy((void*) section_addr,(void*) main_section, section_len); + + DCFlushRange((void*)section_addr, section_len); + ICInvalidateRange((void*)section_addr, section_len); + return true; + } + return false; +} + +u32 elf_copy_common_sections(u8 * elf_data) { + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data; + if ( !elf_data + || !IS_ELF (*ehdr) + || (ehdr->e_type != ET_EXEC) + || (ehdr->e_machine != EM_PPC)) { + return 0; + } + + bool error = false; + + if(!elf_copy_section(elf_data, ".text")) { + return 0; + } + + elf_copy_section(elf_data, ".rodata"); + elf_copy_section(elf_data, ".data"); + elf_copy_section(elf_data, ".bss"); + + return elf_get_entry_addr(elf_data); +} + +u32 elf_get_entry_addr(u8 * elf_data) { + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data; + if ( !elf_data + || !IS_ELF (*ehdr) + || (ehdr->e_type != ET_EXEC) + || (ehdr->e_machine != EM_PPC)) { + return 0; + } + u8 * source_addr = (u8 *) elf_data; + return ehdr->e_entry; +} diff --git a/source/utils/logger.c b/src/utils/logger.c similarity index 81% rename from source/utils/logger.c rename to src/utils/logger.c index a3b4688..db8203f 100644 --- a/source/utils/logger.c +++ b/src/utils/logger.c @@ -3,18 +3,18 @@ #include #include #include -#include "logger.h" -#include -#include +#include +#include +#include + +#include +#include static int log_socket __attribute__((section(".data")))= -1; static struct sockaddr_in connect_addr __attribute__((section(".data"))); static volatile int log_lock __attribute__((section(".data"))) = 0; void log_init_() { - InitOSFunctionPointers(); - InitSocketFunctionPointers(); - int broadcastEnable = 1; log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (log_socket < 0) @@ -35,7 +35,7 @@ void log_print_(const char *str) { } while(log_lock) - os_usleep(1000); + OSSleepTicks(OSMillisecondsToTicks(1000)); log_lock = 1; int len = strlen(str); @@ -54,10 +54,11 @@ void log_print_(const char *str) { } void OSFatal_printf(const char *format, ...) { - char * tmp = NULL; + char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { OSFatal(tmp); } va_end(va); @@ -68,17 +69,14 @@ void log_printf_(const char *format, ...) { return; } - - char * tmp = NULL; + char tmp[512]; + tmp[0] = 0; va_list va; va_start(va, format); - if((vasprintf(&tmp, format, va) >= 0) && tmp) { + if((vsprintf(tmp, format, va) >= 0)) { log_print_(tmp); } va_end(va); - - if(tmp) - free(tmp); } diff --git a/source/utils/utils.c b/src/utils/utils.c similarity index 96% rename from source/utils/utils.c rename to src/utils/utils.c index ca64f72..0042415 100644 --- a/source/utils/utils.c +++ b/src/utils/utils.c @@ -4,8 +4,7 @@ #include #include #include -#include "utils.h" -#include "logger.h" +#include // https://gist.github.com/ccbrown/9722406 void dumpHex(const void* data, size_t size) {