├── Dockerfile ├── sd_loader ├── .gitignore ├── src │ ├── link.ld │ ├── loader_defs.h │ ├── os_defs.h │ ├── common.h │ ├── fs_defs.h │ ├── kernel_hooks.S │ ├── kernel_defs.h │ ├── os_types.h │ ├── elf_abi.h │ └── entry.c └── Makefile ├── .gitignore ├── src ├── dynamic.h ├── import_stub.S ├── link.ld ├── dynamic.c ├── kernel_patches.S ├── imports.h ├── entry.c └── elf_abi.h ├── .github └── workflows │ ├── pr.yml │ └── ci.yml ├── README.md ├── Makefile └── LICENSE /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wiiuenv/devkitppc:20200810 2 | 3 | WORKDIR project -------------------------------------------------------------------------------- /sd_loader/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.elf 3 | sd_loader.c 4 | sd_loader.h 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.elf 3 | *.cbp 4 | payload.bin 5 | .idea/ 6 | cmake-build-debug/ 7 | CMakeLists.txt 8 | payload.elf.bin 9 | -------------------------------------------------------------------------------- /src/dynamic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void InitFunctionPointers(void); 8 | 9 | #ifdef __cplusplus 10 | } 11 | #endif -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: CI-PR 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build-binary: 7 | runs-on: ubuntu-18.04 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: build binary 11 | run: | 12 | docker build . -t builder 13 | docker run --rm -v ${PWD}:/project builder make 14 | - uses: actions/upload-artifact@master 15 | with: 16 | name: binary 17 | path: "*.elf" -------------------------------------------------------------------------------- /sd_loader/src/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT(sd_loader.elf); 2 | 3 | ENTRY(_start); 4 | 5 | SECTIONS { 6 | . = 0x00800000; 7 | .text : { 8 | *(.kernel_code*); 9 | *(.text*); 10 | /* Tell linker to not garbage collect this section as it is not referenced anywhere */ 11 | KEEP(*(.kernel_code*)); 12 | } 13 | .data : { 14 | *(.rodata*); 15 | *(.data*); 16 | *(.bss*); 17 | } 18 | /DISCARD/ : { 19 | *(*); 20 | } 21 | } 22 | 23 | ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x1300, "Memory overlapping with main elf."); 24 | -------------------------------------------------------------------------------- /src/import_stub.S: -------------------------------------------------------------------------------- 1 | /*#define IMPORT(name) \ 2 | .global name; \ 3 | name: \ 4 | lis %r11, addr_##name@h; \ 5 | lwz %r11, addr_##name@l(%r11); \ 6 | mtctr %r11; \ 7 | bctr*/ 8 | 9 | #define IMPORT(name) \ 10 | .global name; \ 11 | name: \ 12 | lis %r11, addr_##name@h; \ 13 | ori %r11, %r11, addr_##name@l; \ 14 | lwz %r11, 0(%r11); \ 15 | mtctr %r11; \ 16 | bctr 17 | 18 | #define IMPORT_BEGIN(lib) 19 | #define IMPORT_END() 20 | 21 | .align 2; 22 | .section ".text"; 23 | 24 | #include "imports.h" -------------------------------------------------------------------------------- /src/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT(payload.elf); 2 | 3 | ENTRY(_start); 4 | 5 | SECTIONS { 6 | . = 0x00840000; 7 | .text : { 8 | *(.kernel_code*); 9 | *(.text*); 10 | /* Tell linker to not garbage collect this section as it is not referenced anywhere */ 11 | KEEP(*(.kernel_code*)); 12 | } 13 | .data : { 14 | *(.rodata*); 15 | *(.data*); 16 | *(.sdata*); 17 | *(.bss*); 18 | *(.sbss*); 19 | } 20 | __CODE_END = .; 21 | /DISCARD/ : { 22 | *(*); 23 | } 24 | } 25 | 26 | ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x400000, "elf is too big"); 27 | -------------------------------------------------------------------------------- /sd_loader/src/loader_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_DEFS_H_ 2 | #define __LOADER_DEFS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | // struct holding the globals of the loader (there are actually more but we don't need others) 9 | typedef struct _loader_globals_t { 10 | int sgIsLoadingBuffer; 11 | int sgFileType; 12 | int sgProcId; 13 | int sgGotBytes; 14 | int sgFileOffset; 15 | int sgBufferNumber; 16 | int sgBounceError; 17 | char sgLoadName[0x1000]; 18 | } __attribute__((packed)) loader_globals_t; 19 | 20 | typedef struct _loader_globals_550_t { 21 | int sgFinishedLoadingBuffer; 22 | int sgFileType; 23 | int sgProcId; 24 | int sgGotBytes; 25 | int sgTotalBytes; 26 | int sgFileOffset; 27 | int sgBufferNumber; 28 | int sgBounceError; 29 | char sgLoadName[0x1000]; 30 | } __attribute__((packed)) loader_globals_550_t; 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif // __LOADER_DEFS_H_ 37 | -------------------------------------------------------------------------------- /sd_loader/src/os_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_DEFS_H_ 2 | #define __OS_DEFS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef struct _OsSpecifics { 9 | unsigned int addr_OSDynLoad_Acquire; 10 | unsigned int addr_OSDynLoad_FindExport; 11 | unsigned int addr_OSTitle_main_entry; 12 | 13 | unsigned int addr_KernSyscallTbl1; 14 | unsigned int addr_KernSyscallTbl2; 15 | unsigned int addr_KernSyscallTbl3; 16 | unsigned int addr_KernSyscallTbl4; 17 | unsigned int addr_KernSyscallTbl5; 18 | 19 | int (*LiWaitIopComplete)(int, int *); 20 | int (*LiWaitIopCompleteWithInterrupts)(int, int *); 21 | unsigned int addr_LiWaitOneChunk; 22 | unsigned int addr_PrepareTitle_hook; 23 | unsigned int addr_sgIsLoadingBuffer; 24 | unsigned int addr_gDynloadInitialized; 25 | unsigned int orig_LiWaitOneChunkInstr; 26 | } OsSpecifics; 27 | 28 | typedef struct _s_mem_area { 29 | unsigned int address; 30 | unsigned int size; 31 | struct _s_mem_area* next; 32 | } s_mem_area; 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif // __OS_DEFS_H_ 39 | -------------------------------------------------------------------------------- /sd_loader/src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "os_defs.h" 9 | 10 | #define HBL_VERSION "v1.4" 11 | 12 | #define CAFE_OS_SD_PATH "/vol/external01" 13 | #define SD_PATH "sd:" 14 | #define WIIU_PATH "/wiiu" 15 | 16 | #ifndef MEM_BASE 17 | #define MEM_BASE (0x00800000) 18 | #endif 19 | 20 | #define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00)) 21 | #define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04)) 22 | #define HBL_CHANNEL (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x08)) 23 | #define RPX_MAX_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x0C)) 24 | #define RPX_MAX_CODE_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x10)) 25 | #define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00)) 26 | #define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04)) 27 | 28 | #define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500)) 29 | 30 | #define MEM_AREA_TABLE ((s_mem_area*)(MEM_BASE + 0x1600)) 31 | 32 | #ifndef EXIT_SUCCESS 33 | #define EXIT_SUCCESS 0 34 | #endif 35 | #define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* COMMON_H */ 42 | 43 | -------------------------------------------------------------------------------- /src/dynamic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IMPORT(name) void* addr_##name 5 | #define IMPORT_BEGIN(lib) 6 | #define IMPORT_END() 7 | 8 | #include "imports.h" 9 | 10 | #undef IMPORT 11 | #undef IMPORT_BEGIN 12 | #undef IMPORT_END 13 | 14 | #define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0) 15 | #define IMPORT_BEGIN(lib) OSDynLoad_Acquire(#lib ".rpl", &handle) 16 | /* #define IMPORT_END() OSDynLoad_Release(handle) */ 17 | #define IMPORT_END() 18 | 19 | #define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); 20 | 21 | EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap); 22 | EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx); 23 | EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap); 24 | 25 | void InitFunctionPointers(void) { 26 | OSDynLoad_Module handle; 27 | addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; 28 | addr_OSDynLoad_FindExport = (void *) 0x0102B828; 29 | 30 | OSDynLoad_Acquire("coreinit.rpl", &handle); 31 | 32 | uint32_t **value = 0; 33 | OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &value); 34 | MEMAllocFromDefaultHeap = *value; 35 | OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &value); 36 | MEMAllocFromDefaultHeapEx = *value; 37 | OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &value); 38 | MEMFreeToDefaultHeap = *value; 39 | 40 | #include "imports.h" 41 | 42 | // override failed __rplwrap_exit find export 43 | OSDynLoad_FindExport(handle, 0, "exit", (void **) &addr___rplwrap_exit); 44 | } 45 | -------------------------------------------------------------------------------- /sd_loader/src/fs_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef FS_DEFS_H 2 | #define FS_DEFS_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | 11 | /* FS defines and types */ 12 | #define FS_MAX_LOCALPATH_SIZE 511 13 | #define FS_MAX_MOUNTPATH_SIZE 128 14 | #define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE) 15 | #define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE 16 | 17 | #define FS_STATUS_OK 0 18 | #define FS_RET_UNSUPPORTED_CMD 0x0400 19 | #define FS_RET_NO_ERROR 0x0000 20 | #define FS_RET_ALL_ERROR (unsigned int)(-1) 21 | 22 | #define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 23 | 24 | /* max length of file/dir name */ 25 | #define FS_MAX_ENTNAME_SIZE 256 26 | 27 | #define FS_SOURCETYPE_EXTERNAL 0 28 | #define FS_SOURCETYPE_HFIO 1 29 | #define FS_SOURCETYPE_HFIO 1 30 | 31 | #define FS_MOUNT_SOURCE_SIZE 0x300 32 | #define FS_CLIENT_SIZE 0x1700 33 | #define FS_CMD_BLOCK_SIZE 0xA80 34 | 35 | typedef struct { 36 | uint32_t flag; 37 | uint32_t permission; 38 | uint32_t owner_id; 39 | uint32_t group_id; 40 | uint32_t size; 41 | uint32_t alloc_size; 42 | uint64_t quota_size; 43 | uint32_t ent_id; 44 | uint64_t ctime; 45 | uint64_t mtime; 46 | uint8_t attributes[48]; 47 | } __attribute__((packed)) FSStat; 48 | 49 | typedef struct { 50 | FSStat stat; 51 | char name[FS_MAX_ENTNAME_SIZE]; 52 | } FSDirEntry; 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif /* FS_DEFS_H */ 60 | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Homebrew Launcher installer 2 | Straight port from the offical [homebrew_launcher repo](https://github.com/dimok789/homebrew_launcher) 3 | 4 | # Usage 5 | Meant to be used with the [payload_loader](https://github.com/wiiu-env/payload_loader). 6 | Put the created `payload.elf` on the sd card where the `payload_loader` can find it. 7 | Check out the repository of the loader for further instructions. 8 | 9 | Still requires the [homebrew_launcher.elf](https://github.com/dimok789/homebrew_launcher) 10 | to be placed on the sd card. Checkout the [official hbl repo](https://github.com/dimok789/homebrew_launcher) 11 | for further instructions. 12 | 13 | ## Building 14 | In order to be able to compile this, you need to have installed 15 | [devkitPPC](https://devkitpro.org/wiki/Getting_Started) with the following 16 | pacman packages installed. 17 | 18 | ``` 19 | pacman -Syu devkitPPC 20 | ``` 21 | 22 | Make sure the following environment variables are set: 23 | ``` 24 | DEVKITPRO=/opt/devkitpro 25 | DEVKITPPC=/opt/devkitpro/devkitPPC 26 | ``` 27 | 28 | The command `make` should produce a `payload.elf`, meant to be used with the 29 | [payload_loader](https://github.com/wiiu-env/payload_loader) 30 | 31 | ## Building using the Dockerfile 32 | 33 | It's possible to use a docker image for building. This way you don't need anything installed on your host system. 34 | 35 | ``` 36 | # Build docker image (only needed once) 37 | docker build . -t hbl-installer-builder 38 | 39 | # make 40 | docker run -it --rm -v ${PWD}:/project hbl-installer-builder make 41 | 42 | # make clean 43 | docker run -it --rm -v ${PWD}:/project hbl-installer-builder make clean 44 | ``` 45 | 46 | 47 | # Credits 48 | 49 | - dimok789: [original installer](https://github.com/dimok789/homebrew_launcher)) 50 | - orboditilt: port to be used with the [payload_loader](https://github.com/wiiu-env/payload_loader) 51 | -------------------------------------------------------------------------------- /sd_loader/src/kernel_hooks.S: -------------------------------------------------------------------------------- 1 | # This stuff may need a change in different kernel versions 2 | # This is only needed when launched directly through browser and not SD card. 3 | 4 | .section ".kernel_code" 5 | .globl SaveAndResetDataBATs_And_SRs_hook 6 | SaveAndResetDataBATs_And_SRs_hook: 7 | # setup CTR to the position we need to return to 8 | mflr r5 9 | mtctr r5 10 | # set link register to its original value 11 | mtlr r7 12 | # setup us a nice DBAT for our code data with same region as our code 13 | mfspr r5, 560 14 | mtspr 570, r5 15 | mfspr r5, 561 16 | mtspr 571, r5 17 | # restore the original kernel instructions that we replaced 18 | lwz r5, 0x34(r3) 19 | lwz r6, 0x38(r3) 20 | lwz r7, 0x3C(r3) 21 | lwz r8, 0x40(r3) 22 | lwz r9, 0x44(r3) 23 | lwz r10, 0x48(r3) 24 | lwz r11, 0x4C(r3) 25 | lwz r3, 0x50(r3) 26 | isync 27 | mtsr 7, r5 28 | # jump back to the position in kernel after our patch (from LR) 29 | bctr 30 | 31 | .extern my_PrepareTitle 32 | .globl my_PrepareTitle_hook 33 | my_PrepareTitle_hook: 34 | # store all registers on stack to avoid issues with the call to C functions 35 | stwu r1, -0x90(r1) 36 | # registers for our own usage 37 | # just store everything 38 | stmw r3, 0x10(r1) 39 | 40 | # save the LR from where we came 41 | mflr r31 42 | 43 | # the cos.xml/app.xml structure is at the location 0x68 of r11 44 | # there are actually many places that can be hooked for it 45 | # e.g. 0xFFF16130 and r27 points to this structure 46 | addi r3, r11, 0x68 47 | 48 | bl my_PrepareTitle 49 | 50 | # setup LR to jump back to kernel code 51 | mtlr r31 52 | 53 | # restore all original values of registers from stack 54 | lmw r3, 0x10(r1) 55 | 56 | # restore the stack 57 | addi r1, r1, 0x90 58 | 59 | # restore original instruction that we replaced in the kernel 60 | clrlwi r7, r12, 0 61 | 62 | # jump back 63 | blr 64 | 65 | .globl SC0x25_KernelCopyData 66 | SC0x25_KernelCopyData: 67 | li r0, 0x2500 68 | sc 69 | blr 70 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI-Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build-binary: 10 | runs-on: ubuntu-18.04 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: build binary 14 | run: | 15 | docker build . -t builder 16 | docker run --rm -v ${PWD}:/project builder make 17 | - uses: actions/upload-artifact@master 18 | with: 19 | name: binary 20 | path: "payload.elf" 21 | deploy-binary: 22 | needs: build-binary 23 | runs-on: ubuntu-18.04 24 | steps: 25 | - name: Get environment variables 26 | id: get_repository_name 27 | run: | 28 | echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//") >> $GITHUB_ENV 29 | echo DATETIME=$(echo $(date '+%Y%m%d-%H%M%S')) >> $GITHUB_ENV 30 | - uses: actions/download-artifact@master 31 | with: 32 | name: binary 33 | path: wiiu 34 | - name: zip artifact 35 | run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip wiiu 36 | - name: Create Release 37 | id: create_release 38 | uses: actions/create-release@v1 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | with: 42 | tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }} 43 | release_name: Nightly-${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }} 44 | draft: false 45 | prerelease: true 46 | body: | 47 | Not a stable release: 48 | ${{ github.event.head_commit.message }} 49 | - name: Upload Release Asset 50 | id: upload-release-asset 51 | uses: actions/upload-release-asset@v1 52 | env: 53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | with: 55 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 56 | asset_path: ./${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip 57 | asset_name: ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip 58 | asset_content_type: application/unknown -------------------------------------------------------------------------------- /sd_loader/src/kernel_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_DEFS_H_ 2 | #define __KERNEL_DEFS_H_ 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | // original structure in the kernel that is originally 0x1270 long 11 | typedef struct { 12 | uint32_t version_cos_xml; // version tag from cos.xml 13 | uint64_t os_version; // os_version from app.xml 14 | uint64_t title_id; // title_id tag from app.xml 15 | uint32_t app_type; // app_type tag from app.xml 16 | uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure) 17 | char rpx_name[0x1000]; // rpx name from cos.xml 18 | uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?) 19 | uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2 20 | uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app 21 | uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?) 22 | uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?) 23 | uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?) 24 | uint32_t max_codesize; // max_codesize in cos.xml 25 | uint32_t overlay_arena; // overlay_arena in cos.xml 26 | uint32_t unknown4[59]; // all zeros it seems 27 | uint32_t default_stack0_size; // not sure because always 0 but very likely 28 | uint32_t default_stack1_size; // not sure because always 0 but very likely 29 | uint32_t default_stack2_size; // not sure because always 0 but very likely 30 | uint32_t default_redzone0_size; // not sure because always 0 but very likely 31 | uint32_t default_redzone1_size; // not sure because always 0 but very likely 32 | uint32_t default_redzone2_size; // not sure because always 0 but very likely 33 | uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker 34 | uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker 35 | uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker 36 | uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker 37 | uint32_t title_version; // from app.xml, 0x32 on mii maker 38 | /* 39 | // --------------------------------------------------------------------------------------------------------------------------------------------- 40 | // the next part might be changing from title to title?! I don't think its important but nice to know maybe.... 41 | // --------------------------------------------------------------------------------------------------------------------------------------------- 42 | char mlc[4]; // string "mlc" on mii maker and sysmenu 43 | uint32_t unknown5[7]; // all zeros on mii maker and sysmenu 44 | uint32_t unknown6_one; // 0x01 on mii maker and sysmenu 45 | // --------------------------------------------------------------------------------------------------------------------------------------------- 46 | char ACP[4]; // string "ACP" on mii maker and sysmenu 47 | uint32_t unknown7[15]; // all zeros on mii maker and sysmenu 48 | uint32_t unknown8_5; // 0x05 on mii maker and sysmenu 49 | uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu 50 | uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu 51 | // --------------------------------------------------------------------------------------------------------------------------------------------- 52 | char UVD[4]; // string "UVD" on mii maker and sysmenu 53 | uint32_t unknown11[15]; // all zeros on mii maker and sysmenu 54 | uint32_t unknown12_5; // 0x05 on mii maker and sysmenu 55 | uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu 56 | uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu 57 | // --------------------------------------------------------------------------------------------------------------------------------------------- 58 | char SND[4]; // string "SND" on mii maker and sysmenu 59 | uint32_t unknown15[15]; // all zeros on mii maker and sysmenu 60 | uint32_t unknown16_5; // 0x05 on mii maker and sysmenu 61 | uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu 62 | uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu 63 | // --------------------------------------------------------------------------------------------------------------------------------------------- 64 | uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu 65 | */ 66 | // after that only zeros follow 67 | } __attribute__((packed)) CosAppXmlInfo; 68 | 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif // __KERNEL_DEFS_H_ 75 | -------------------------------------------------------------------------------- /src/kernel_patches.S: -------------------------------------------------------------------------------- 1 | #define BAT_SETUP_HOOK_ADDR 0xFFF1D624 2 | # not all of those NOP address are required for every firmware 3 | # mainly these should stop the kernel from removing our IBAT4 and DBAT5 4 | #define BAT_SET_NOP_ADDR_1 0xFFF06B6C 5 | #define BAT_SET_NOP_ADDR_2 0xFFF06BF8 6 | #define BAT_SET_NOP_ADDR_3 0xFFF003C8 7 | #define BAT_SET_NOP_ADDR_4 0xFFF003CC 8 | #define BAT_SET_NOP_ADDR_5 0xFFF1D70C 9 | #define BAT_SET_NOP_ADDR_6 0xFFF1D728 10 | #define BAT_SET_NOP_ADDR_7 0xFFF1D82C 11 | 12 | #define BAT_SET_NOP_ADDR_8 0xFFEE11C4 13 | #define BAT_SET_NOP_ADDR_9 0xFFEE11C8 14 | 15 | #define BAT_SETUP_HOOK_ENTRY 0x00800000 16 | 17 | 18 | #define BAT4U_VAL 0x008000FF 19 | #define BAT4L_VAL 0x30800012 20 | 21 | 22 | #define SET_R4_TO_ADDR(addr) \ 23 | lis r3, addr@h ; \ 24 | ori r3, r3, addr@l ; \ 25 | stw r4, 0(r3) ; \ 26 | dcbf 0, r3 ; \ 27 | icbi 0, r3 ; 28 | 29 | .globl Syscall_0x36 30 | Syscall_0x36: 31 | li r0, 0x3600 32 | sc 33 | blr 34 | 35 | 36 | .global SCKernelCopyData 37 | SCKernelCopyData: 38 | // Disable data address translation 39 | mfmsr %r6 40 | li %r7, 0x10 41 | andc %r6, %r6, %r7 42 | mtmsr %r6 43 | 44 | // Copy data 45 | addi %r3, %r3, -1 46 | addi %r4, %r4, -1 47 | mtctr %r5 48 | SCKernelCopyData_loop: 49 | lbzu %r5, 1(%r4) 50 | stbu %r5, 1(%r3) 51 | bdnz SCKernelCopyData_loop 52 | 53 | // Enable data address translation 54 | ori %r6, %r6, 0x10 55 | mtmsr %r6 56 | blr 57 | 58 | .global SC_0x25_KernelCopyData 59 | SC_0x25_KernelCopyData: 60 | li %r0, 0x2500 61 | sc 62 | blr 63 | 64 | .globl KernelPatches 65 | KernelPatches: 66 | # store the old DBAT0 67 | mfdbatu r5, 0 68 | mfdbatl r6, 0 69 | 70 | # memory barrier 71 | eieio 72 | isync 73 | 74 | # setup DBAT0 for access to kernel code memory 75 | lis r3, 0xFFF0 76 | ori r3, r3, 0x0002 77 | mtdbatu 0, r3 78 | lis r3, 0xFFF0 79 | ori r3, r3, 0x0032 80 | mtdbatl 0, r3 81 | 82 | # memory barrier 83 | eieio 84 | isync 85 | 86 | # SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though 87 | # just chosen because its simple 88 | lis r3, BAT_SETUP_HOOK_ADDR@h 89 | ori r3, r3, BAT_SETUP_HOOK_ADDR@l 90 | 91 | # make the kernel setup our section in IBAT4 and 92 | # jump to our function to restore the replaced instructions 93 | lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h 94 | ori r4, r4, BAT4L_VAL@h 95 | stw r4, 0x00(r3) 96 | lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l 97 | ori r4, r4, BAT4L_VAL@l 98 | stw r4, 0x04(r3) 99 | lis r4, 0x7cf1 # mtspr 561, r7 100 | ori r4, r4, 0x8ba6 101 | stw r4, 0x08(r3) 102 | lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h 103 | ori r4, r4, BAT4U_VAL@h 104 | stw r4, 0x0C(r3) 105 | lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l 106 | ori r4, r4, BAT4U_VAL@l 107 | stw r4, 0x10(r3) 108 | lis r4, 0x7cf0 # mtspr 560, r7 109 | ori r4, r4, 0x8ba6 110 | stw r4, 0x14(r3) 111 | lis r4, 0x7c00 # eieio 112 | ori r4, r4, 0x06ac 113 | stw r4, 0x18(r3) 114 | lis r4, 0x4c00 # isync 115 | ori r4, r4, 0x012c 116 | stw r4, 0x1C(r3) 117 | lis r4, 0x7ce8 # mflr r7 118 | ori r4, r4, 0x02a6 119 | stw r4, 0x20(r3) 120 | lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY 121 | ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l 122 | stw r4, 0x24(r3) 123 | 124 | # flush and invalidate the replaced instructions 125 | lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h 126 | ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l 127 | dcbf 0, r3 128 | icbi 0, r3 129 | lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h 130 | ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l 131 | dcbf 0, r3 132 | icbi 0, r3 133 | sync 134 | 135 | # setup IBAT4 for core 1 at this position (not really required but wont hurt) 136 | # IBATL 4 137 | lis r3, BAT4L_VAL@h 138 | ori r3, r3, BAT4L_VAL@l 139 | mtspr 561, r3 140 | 141 | # IBATU 4 142 | lis r3, BAT4U_VAL@h 143 | ori r3, r3, BAT4U_VAL@l 144 | mtspr 560, r3 145 | 146 | # memory barrier 147 | eieio 148 | isync 149 | 150 | # write "nop" to some positions 151 | lis r4, 0x6000 152 | # nop on IBATU 4 and DBAT 5 set/reset 153 | #ifdef BAT_SET_NOP_ADDR_1 154 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1) 155 | #endif 156 | #ifdef BAT_SET_NOP_ADDR_2 157 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2) 158 | #endif 159 | #ifdef BAT_SET_NOP_ADDR_3 160 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3) 161 | #endif 162 | #ifdef BAT_SET_NOP_ADDR_4 163 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4) 164 | #endif 165 | #ifdef BAT_SET_NOP_ADDR_5 166 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5) 167 | #endif 168 | #ifdef BAT_SET_NOP_ADDR_6 169 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6) 170 | #endif 171 | #ifdef BAT_SET_NOP_ADDR_7 172 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7) 173 | #endif 174 | 175 | #if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9)) 176 | # memory barrier 177 | eieio 178 | isync 179 | 180 | # setup DBAT0 for access to kernel code memory 181 | lis r3, 0xFFEE 182 | ori r3, r3, 0x0002 183 | mtdbatu 0, r3 184 | lis r3, 0xFFEE 185 | ori r3, r3, 0x0032 186 | mtdbatl 0, r3 187 | 188 | # memory barrier 189 | eieio 190 | isync 191 | 192 | # write "nop" to some positions 193 | lis r4, 0x6000 194 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8) 195 | SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9) 196 | #endif 197 | 198 | # memory barrier 199 | eieio 200 | isync 201 | 202 | # restore DBAT 0 and return from interrupt 203 | mtdbatu 0, r5 204 | mtdbatl 0, r6 205 | 206 | # memory barrier 207 | eieio 208 | isync 209 | 210 | blr 211 | 212 | -------------------------------------------------------------------------------- /sd_loader/src/os_types.h: -------------------------------------------------------------------------------- 1 | #ifndef _OS_TYPES_H_ 2 | #define _OS_TYPES_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /*+----------------------------------------------------------------------------------------------+*/ 14 | typedef uint8_t u8; ///< 8bit unsigned integer 15 | typedef uint16_t u16; ///< 16bit unsigned integer 16 | typedef uint32_t u32; ///< 32bit unsigned integer 17 | typedef uint64_t u64; ///< 64bit unsigned integer 18 | /*+----------------------------------------------------------------------------------------------+*/ 19 | typedef int8_t s8; ///< 8bit signed integer 20 | typedef int16_t s16; ///< 16bit signed integer 21 | typedef int32_t s32; ///< 32bit signed integer 22 | typedef int64_t s64; ///< 64bit signed integer 23 | /*+----------------------------------------------------------------------------------------------+*/ 24 | typedef volatile u8 vu8; ///< 8bit unsigned volatile integer 25 | typedef volatile u16 vu16; ///< 16bit unsigned volatile integer 26 | typedef volatile u32 vu32; ///< 32bit unsigned volatile integer 27 | typedef volatile u64 vu64; ///< 64bit unsigned volatile integer 28 | /*+----------------------------------------------------------------------------------------------+*/ 29 | typedef volatile s8 vs8; ///< 8bit signed volatile integer 30 | typedef volatile s16 vs16; ///< 16bit signed volatile integer 31 | typedef volatile s32 vs32; ///< 32bit signed volatile integer 32 | typedef volatile s64 vs64; ///< 64bit signed volatile integer 33 | /*+----------------------------------------------------------------------------------------------+*/ 34 | // fixed point math typedefs 35 | typedef s16 sfp16; ///< signed 8:8 fixed point 36 | typedef s32 sfp32; ///< signed 20:8 fixed point 37 | typedef u16 ufp16; ///< unsigned 8:8 fixed point 38 | typedef u32 ufp32; ///< unsigned 24:8 fixed point 39 | /*+----------------------------------------------------------------------------------------------+*/ 40 | typedef float f32; 41 | typedef double f64; 42 | /*+----------------------------------------------------------------------------------------------+*/ 43 | typedef volatile float vf32; 44 | typedef volatile double vf64; 45 | /*+----------------------------------------------------------------------------------------------+*/ 46 | 47 | #define OS_MESSAGE_NOBLOCK 0 48 | #define OS_MESSAGE_BLOCK 1 49 | 50 | #define OS_EXCEPTION_DSI 2 51 | #define OS_EXCEPTION_ISI 3 52 | #define OS_EXCEPTION_PROGRAM 6 53 | #define OS_EXCEPTION_MODE_THREAD 1 54 | #define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4 55 | 56 | #define OS_THREAD_ATTR_AFFINITY_NONE 0x0007u // affinity to run on every core 57 | #define OS_THREAD_ATTR_AFFINITY_CORE0 0x0001u // run only on core0 58 | #define OS_THREAD_ATTR_AFFINITY_CORE1 0x0002u // run only on core1 59 | #define OS_THREAD_ATTR_AFFINITY_CORE2 0x0004u // run only on core2 60 | #define OS_THREAD_ATTR_DETACH 0x0008u // detached 61 | #define OS_THREAD_ATTR_PINNED_AFFINITY 0x0010u // pinned (affinitized) to a single core 62 | #define OS_THREAD_ATTR_CHECK_STACK_USE 0x0040u // check for stack usage 63 | #define OS_THREAD_ATTR_NAME_SENT 0x0080u // debugger has seen the name 64 | #define OS_THREAD_ATTR_LAST (OS_THREAD_ATTR_DETACH | OS_THREAD_ATTR_PINNED_AFFINITY | OS_THREAD_ATTR_AFFINITY_NONE) 65 | 66 | typedef struct OSThread_ OSThread; 67 | 68 | typedef struct OSThreadLink_ { 69 | OSThread *next; 70 | OSThread *prev; 71 | } OSThreadLink; 72 | 73 | typedef struct OSThreadQueue_ { 74 | OSThread *head; 75 | OSThread *tail; 76 | void *parentStruct; 77 | u32 reserved; 78 | } OSThreadQueue; 79 | 80 | typedef struct OSMessage_ { 81 | u32 message; 82 | u32 data0; 83 | u32 data1; 84 | u32 data2; 85 | } OSMessage; 86 | 87 | typedef struct OSMessageQueue_ { 88 | u32 tag; 89 | char *name; 90 | u32 reserved; 91 | 92 | OSThreadQueue sendQueue; 93 | OSThreadQueue recvQueue; 94 | OSMessage *messages; 95 | int msgCount; 96 | int firstIndex; 97 | int usedCount; 98 | } OSMessageQueue; 99 | 100 | typedef struct OSContext_ { 101 | char tag[8]; 102 | 103 | u32 gpr[32]; 104 | 105 | u32 cr; 106 | u32 lr; 107 | u32 ctr; 108 | u32 xer; 109 | 110 | u32 srr0; 111 | u32 srr1; 112 | 113 | u32 ex0; 114 | u32 ex1; 115 | 116 | u32 exception_type; 117 | u32 reserved; 118 | 119 | double fpscr; 120 | double fpr[32]; 121 | 122 | u16 spinLockCount; 123 | u16 state; 124 | 125 | u32 gqr[8]; 126 | u32 pir; 127 | double psf[32]; 128 | 129 | u64 coretime[3]; 130 | u64 starttime; 131 | 132 | u32 error; 133 | u32 attributes; 134 | 135 | u32 pmc1; 136 | u32 pmc2; 137 | u32 pmc3; 138 | u32 pmc4; 139 | u32 mmcr0; 140 | u32 mmcr1; 141 | } OSContext; 142 | 143 | typedef enum OSExceptionType { 144 | OS_EXCEPTION_TYPE_SYSTEM_RESET = 0, 145 | OS_EXCEPTION_TYPE_MACHINE_CHECK = 1, 146 | OS_EXCEPTION_TYPE_DSI = 2, 147 | OS_EXCEPTION_TYPE_ISI = 3, 148 | OS_EXCEPTION_TYPE_EXTERNAL_INTERRUPT = 4, 149 | OS_EXCEPTION_TYPE_ALIGNMENT = 5, 150 | OS_EXCEPTION_TYPE_PROGRAM = 6, 151 | OS_EXCEPTION_TYPE_FLOATING_POINT = 7, 152 | OS_EXCEPTION_TYPE_DECREMENTER = 8, 153 | OS_EXCEPTION_TYPE_SYSTEM_CALL = 9, 154 | OS_EXCEPTION_TYPE_TRACE = 10, 155 | OS_EXCEPTION_TYPE_PERFORMANCE_MONITOR = 11, 156 | OS_EXCEPTION_TYPE_BREAKPOINT = 12, 157 | OS_EXCEPTION_TYPE_SYSTEM_INTERRUPT = 13, 158 | OS_EXCEPTION_TYPE_ICI = 14, 159 | } OSExceptionType; 160 | 161 | typedef int (*ThreadFunc)(int argc, void *argv); 162 | 163 | struct OSThread_ { 164 | OSContext context; 165 | 166 | u32 txtTag; 167 | u8 state; 168 | u8 attr; 169 | 170 | short threadId; 171 | int suspend; 172 | int priority; 173 | 174 | char _[0x394 - 0x330 - sizeof(OSThreadLink)]; 175 | OSThreadLink linkActive; 176 | 177 | void *stackBase; 178 | void *stackEnd; 179 | 180 | ThreadFunc entryPoint; 181 | 182 | char _3A0[0x6A0 - 0x3A0]; 183 | }; 184 | 185 | typedef struct _OSCalendarTime { 186 | int sec; 187 | int min; 188 | int hour; 189 | int mday; 190 | int mon; 191 | int year; 192 | int wday; 193 | int yday; 194 | int msec; 195 | int usec; 196 | } OSCalendarTime; 197 | 198 | 199 | typedef struct MCPTitleListType { 200 | u64 titleId; 201 | u8 unknwn[4]; 202 | s8 path[56]; 203 | u32 appType; 204 | u8 unknwn1[0x54 - 0x48]; 205 | u8 device; 206 | u8 unknwn2; 207 | s8 indexedDevice[10]; 208 | u8 unk0x60; 209 | } MCPTitleListType; 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /src/imports.h: -------------------------------------------------------------------------------- 1 | /* coreinit */ 2 | IMPORT_BEGIN(coreinit); 3 | 4 | IMPORT(OSScreenInit); 5 | IMPORT(OSScreenGetBufferSizeEx); 6 | IMPORT(OSScreenSetBufferEx); 7 | IMPORT(OSScreenEnableEx); 8 | IMPORT(OSScreenFlipBuffersEx); 9 | IMPORT(OSScreenClearBufferEx); 10 | IMPORT(OSScreenPutFontEx); 11 | IMPORT(OSFatal); 12 | IMPORT(OSDynLoad_Acquire); 13 | IMPORT(OSDynLoad_FindExport); 14 | IMPORT(OSDynLoad_Release); 15 | IMPORT(OSSetExceptionCallback); 16 | IMPORT(OSSavesDone_ReadyToRelease); 17 | IMPORT(OSInitMutex); 18 | IMPORT(OSLockMutex); 19 | IMPORT(OSUnlockMutex); 20 | IMPORT(OSInitCond); 21 | IMPORT(OSWaitCond); 22 | IMPORT(OSSignalCond); 23 | IMPORT(OSInitSpinLock); 24 | IMPORT(OSUninterruptibleSpinLock_Acquire); 25 | IMPORT(OSUninterruptibleSpinLock_Release); 26 | IMPORT(OSFastMutex_Init); 27 | IMPORT(OSFastMutex_Lock); 28 | IMPORT(OSFastMutex_Unlock); 29 | IMPORT(OSSleepTicks); 30 | IMPORT(OSGetTitleID); 31 | IMPORT(OSIsThreadTerminated); 32 | IMPORT(OSSetThreadPriority); 33 | IMPORT(OSCreateThread); 34 | IMPORT(OSSetThreadCleanupCallback); 35 | IMPORT(OSResumeThread); 36 | IMPORT(OSIsThreadSuspended); 37 | IMPORT(OSSuspendThread); 38 | IMPORT(OSGetCurrentThread); 39 | IMPORT(OSExitThread); 40 | IMPORT(OSJoinThread); 41 | IMPORT(OSYieldThread); 42 | IMPORT(OSGetCoreId); 43 | IMPORT(OSIsMainCore); 44 | IMPORT(OSGetSystemTime); 45 | IMPORT(OSGetSystemTick); 46 | IMPORT(OSGetTime); 47 | IMPORT(OSGetSymbolName); 48 | IMPORT(OSGetSharedData); 49 | IMPORT(OSEffectiveToPhysical); 50 | IMPORT(OSInitSemaphore); 51 | IMPORT(OSInitSemaphoreEx); 52 | IMPORT(OSGetSemaphoreCount); 53 | IMPORT(OSSignalSemaphore); 54 | IMPORT(OSWaitSemaphore); 55 | IMPORT(OSTryWaitSemaphore); 56 | IMPORT(OSCompareAndSwapAtomicEx); 57 | IMPORT(OSCompareAndSwapAtomic); 58 | IMPORT(OSGetThreadSpecific); 59 | IMPORT(OSSetThreadSpecific); 60 | 61 | IMPORT(exit); 62 | IMPORT(_Exit); 63 | IMPORT(__os_snprintf); 64 | IMPORT(DisassemblePPCRange); 65 | 66 | IMPORT(ICInvalidateRange); 67 | IMPORT(DCInvalidateRange); 68 | IMPORT(DCFlushRange); 69 | IMPORT(DCStoreRange); 70 | IMPORT(DCStoreRangeNoSync); 71 | 72 | IMPORT(__gh_errno_ptr); 73 | 74 | IMPORT(MEMGetBaseHeapHandle); 75 | IMPORT(MEMCreateExpHeapEx); 76 | IMPORT(MEMDestroyExpHeap); 77 | IMPORT(MEMAllocFromExpHeapEx); 78 | IMPORT(MEMFreeToExpHeap); 79 | IMPORT(MEMGetSizeForMBlockExpHeap); 80 | IMPORT(MEMAllocFromFrmHeapEx); 81 | IMPORT(MEMFreeToFrmHeap); 82 | IMPORT(MEMGetAllocatableSizeForFrmHeapEx); 83 | 84 | IMPORT(FSInit); 85 | IMPORT(FSShutdown); 86 | IMPORT(FSAddClient); 87 | IMPORT(FSAddClientEx); 88 | IMPORT(FSDelClient); 89 | IMPORT(FSInitCmdBlock); 90 | IMPORT(FSChangeDir); 91 | IMPORT(FSGetFreeSpaceSize); 92 | IMPORT(FSGetStat); 93 | IMPORT(FSRemove); 94 | IMPORT(FSOpenFile); 95 | IMPORT(FSCloseFile); 96 | IMPORT(FSOpenDir); 97 | IMPORT(FSMakeDir); 98 | IMPORT(FSReadDir); 99 | IMPORT(FSRewindDir); 100 | IMPORT(FSCloseDir); 101 | IMPORT(FSGetStatFile); 102 | IMPORT(FSReadFile); 103 | IMPORT(FSWriteFile); 104 | IMPORT(FSSetPosFile); 105 | IMPORT(FSFlushFile); 106 | IMPORT(FSTruncateFile); 107 | IMPORT(FSRename); 108 | IMPORT(FSGetMountSource); 109 | IMPORT(FSMount); 110 | IMPORT(FSUnmount); 111 | IMPORT(FSChangeMode); 112 | IMPORT(FSGetPosFile); 113 | IMPORT(OSTicksToCalendarTime); 114 | IMPORT(__rplwrap_exit); 115 | 116 | IMPORT(IOS_Open); 117 | IMPORT(IOS_Close); 118 | IMPORT(IOS_Ioctl); 119 | IMPORT(IOS_IoctlAsync); 120 | 121 | IMPORT(IMIsAPDEnabled); 122 | IMPORT(IMIsDimEnabled); 123 | IMPORT(IMEnableAPD); 124 | IMPORT(IMEnableDim); 125 | IMPORT(IMDisableAPD); 126 | IMPORT(IMDisableDim); 127 | 128 | IMPORT(OSGetSystemInfo); 129 | 130 | IMPORT_END(); 131 | 132 | /* nsysnet */ 133 | IMPORT_BEGIN(nsysnet); 134 | 135 | IMPORT(socket_lib_init); 136 | IMPORT(getaddrinfo); 137 | IMPORT(freeaddrinfo); 138 | IMPORT(getnameinfo); 139 | IMPORT(inet_ntoa); 140 | IMPORT(inet_ntop); 141 | IMPORT(inet_aton); 142 | IMPORT(inet_pton); 143 | IMPORT(ntohl); 144 | IMPORT(ntohs); 145 | IMPORT(htonl); 146 | IMPORT(htons); 147 | IMPORT(accept); 148 | IMPORT(bind); 149 | IMPORT(socketclose); 150 | IMPORT(connect); 151 | IMPORT(getpeername); 152 | IMPORT(getsockname); 153 | IMPORT(getsockopt); 154 | IMPORT(listen); 155 | IMPORT(recv); 156 | IMPORT(recvfrom); 157 | IMPORT(send); 158 | IMPORT(sendto); 159 | IMPORT(setsockopt); 160 | IMPORT(shutdown); 161 | IMPORT(socket); 162 | IMPORT(select); 163 | IMPORT(socketlasterr); 164 | 165 | IMPORT_END(); 166 | 167 | /* gx2 */ 168 | IMPORT_BEGIN(gx2); 169 | 170 | IMPORT(GX2Invalidate); 171 | IMPORT(GX2Init); 172 | IMPORT(GX2GetSystemTVScanMode); 173 | IMPORT(GX2CalcTVSize); 174 | IMPORT(GX2SetTVBuffer); 175 | IMPORT(GX2CalcDRCSize); 176 | IMPORT(GX2SetDRCBuffer); 177 | IMPORT(GX2CalcSurfaceSizeAndAlignment); 178 | IMPORT(GX2InitColorBufferRegs); 179 | IMPORT(GX2SetupContextStateEx); 180 | IMPORT(GX2SetContextState); 181 | IMPORT(GX2SetColorBuffer); 182 | IMPORT(GX2SetViewport); 183 | IMPORT(GX2SetScissor); 184 | IMPORT(GX2SetDepthOnlyControl); 185 | IMPORT(GX2SetColorControl); 186 | IMPORT(GX2SetBlendControl); 187 | IMPORT(GX2SetBlendConstantColor); 188 | IMPORT(GX2SetCullOnlyControl); 189 | IMPORT(GX2CalcFetchShaderSizeEx); 190 | IMPORT(GX2InitFetchShaderEx); 191 | IMPORT(GX2SetFetchShader); 192 | IMPORT(GX2SetVertexShader); 193 | IMPORT(GX2SetPixelShader); 194 | IMPORT(GX2SetGeometryShader); 195 | IMPORT(GX2SetGeometryUniformBlock); 196 | IMPORT(GX2SetVertexUniformBlock); 197 | IMPORT(GX2SetPixelUniformBlock); 198 | IMPORT(GX2CalcGeometryShaderInputRingBufferSize); 199 | IMPORT(GX2CalcGeometryShaderOutputRingBufferSize); 200 | IMPORT(GX2SetGeometryShaderInputRingBuffer); 201 | IMPORT(GX2SetGeometryShaderOutputRingBuffer); 202 | IMPORT(GX2SetShaderModeEx); 203 | IMPORT(GX2SetAttribBuffer); 204 | IMPORT(GX2InitTextureRegs); 205 | IMPORT(GX2InitSampler); 206 | IMPORT(GX2SetPixelTexture); 207 | IMPORT(GX2SetPixelSampler); 208 | IMPORT(GX2ClearColor); 209 | IMPORT(GX2CopyColorBufferToScanBuffer); 210 | IMPORT(GX2SwapScanBuffers); 211 | IMPORT(GX2Flush); 212 | IMPORT(GX2WaitForVsync); 213 | IMPORT(GX2SetTVEnable); 214 | IMPORT(GX2SetDRCEnable); 215 | IMPORT(GX2SetSwapInterval); 216 | IMPORT(GX2DrawDone); 217 | IMPORT(GX2Shutdown); 218 | IMPORT(GX2DrawEx); 219 | IMPORT(GX2WaitForFlip); 220 | IMPORT(GX2GetSwapStatus); 221 | 222 | IMPORT_END(); 223 | 224 | /* nn_ac */ 225 | IMPORT_BEGIN(nn_ac); 226 | IMPORT(ACInitialize); 227 | IMPORT(ACFinalize); 228 | IMPORT(ACConnect); 229 | IMPORT(ACClose); 230 | IMPORT(ACGetAssignedAddress); 231 | IMPORT(ACGetAssignedSubnet); 232 | IMPORT(Initialize__Q2_2nn3actFv); 233 | IMPORT(GetSlotNo__Q2_2nn3actFv); 234 | IMPORT(GetDefaultAccount__Q2_2nn3actFv); 235 | IMPORT(Finalize__Q2_2nn3actFv); 236 | IMPORT_END(); 237 | 238 | /* proc_ui */ 239 | IMPORT_BEGIN(proc_ui); 240 | 241 | IMPORT(ProcUIInit); 242 | IMPORT(ProcUIShutdown); 243 | IMPORT(ProcUIDrawDoneRelease); 244 | IMPORT(ProcUIProcessMessages); 245 | 246 | IMPORT_END(); 247 | 248 | /* sndcore2 */ 249 | IMPORT_BEGIN(sndcore2); 250 | 251 | IMPORT(AXInitWithParams); 252 | IMPORT(AXQuit); 253 | IMPORT(AXRegisterFrameCallback); 254 | IMPORT(AXAcquireMultiVoice); 255 | IMPORT(AXSetMultiVoiceDeviceMix); 256 | IMPORT(AXSetMultiVoiceOffsets); 257 | IMPORT(AXSetMultiVoiceCurrentOffset); 258 | IMPORT(AXSetMultiVoiceState); 259 | IMPORT(AXSetMultiVoiceVe); 260 | IMPORT(AXSetMultiVoiceSrcType); 261 | IMPORT(AXSetMultiVoiceSrcRatio); 262 | IMPORT(AXIsMultiVoiceRunning); 263 | IMPORT(AXFreeMultiVoice); 264 | 265 | IMPORT_END(); 266 | 267 | /* sysapp */ 268 | IMPORT_BEGIN(sysapp); 269 | 270 | IMPORT(SYSRelaunchTitle); 271 | IMPORT(_SYSGetSystemApplicationTitleId); 272 | IMPORT(SYSLaunchMenu); 273 | IMPORT(_SYSLaunchMenuWithCheckingAccount); 274 | 275 | IMPORT_END(); 276 | 277 | /* vpad */ 278 | IMPORT_BEGIN(vpad); 279 | 280 | IMPORT(VPADRead); 281 | IMPORT(VPADInit); 282 | IMPORT(VPADGetTPCalibratedPoint); 283 | 284 | IMPORT_END(); 285 | 286 | 287 | /* nsyskbd */ 288 | IMPORT_BEGIN(zlib125); 289 | 290 | IMPORT(inflateInit_); 291 | IMPORT(inflate); 292 | IMPORT(inflateEnd); 293 | 294 | IMPORT_END(); 295 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | ifeq ($(strip $(DEVKITPPC)),) 7 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 8 | endif 9 | export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) 10 | export PORTLIBS := $(DEVKITPRO)/portlibs/ppc 11 | 12 | PREFIX := powerpc-eabi- 13 | 14 | export AS := $(PREFIX)as 15 | export CC := $(PREFIX)gcc 16 | export CXX := $(PREFIX)g++ 17 | export AR := $(PREFIX)ar 18 | export OBJCOPY := $(PREFIX)objcopy 19 | 20 | GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion) 21 | 22 | #--------------------------------------------------------------------------------- 23 | # TARGET is the name of the output 24 | # BUILD is the directory where object files & intermediate files will be placed 25 | # SOURCES is a list of directories containing source code 26 | # INCLUDES is a list of directories containing extra header files 27 | #--------------------------------------------------------------------------------- 28 | TARGET := payload 29 | BUILD := build 30 | BUILD_DBG := $(TARGET)_dbg 31 | SOURCES := src \ 32 | sd_loader 33 | DATA := 34 | INCLUDES := 35 | 36 | #--------------------------------------------------------------------------------- 37 | # options for code generation 38 | #--------------------------------------------------------------------------------- 39 | CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-builtin \ 40 | -O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 41 | CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ 42 | -O0 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 43 | ASFLAGS := -mregnames 44 | LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition 45 | 46 | Q := @ 47 | MAKEFLAGS += --no-print-directory 48 | #--------------------------------------------------------------------------------- 49 | # any extra libraries we wish to link with the project 50 | #--------------------------------------------------------------------------------- 51 | LIBS := -lwut 52 | 53 | #--------------------------------------------------------------------------------- 54 | # list of directories containing libraries, this must be the top level containing 55 | # include and lib 56 | #--------------------------------------------------------------------------------- 57 | LIBDIRS := $(CURDIR) \ 58 | $(DEVKITPPC)/lib \ 59 | $(DEVKITPRO)/wut \ 60 | $(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER) 61 | 62 | 63 | #--------------------------------------------------------------------------------- 64 | # no real need to edit anything past this point unless you need to add additional 65 | # rules for different file extensions 66 | #--------------------------------------------------------------------------------- 67 | ifneq ($(BUILD),$(notdir $(CURDIR))) 68 | #--------------------------------------------------------------------------------- 69 | export PROJECTDIR := $(CURDIR) 70 | export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) 71 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 72 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 73 | export DEPSDIR := $(CURDIR)/$(BUILD) 74 | 75 | #--------------------------------------------------------------------------------- 76 | # automatically build a list of object files for our project 77 | #--------------------------------------------------------------------------------- 78 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) sd_loader.c 79 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 80 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 81 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 82 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 83 | TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) 84 | PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) 85 | 86 | #--------------------------------------------------------------------------------- 87 | # use CXX for linking C++ projects, CC for standard C 88 | #--------------------------------------------------------------------------------- 89 | ifeq ($(strip $(CPPFILES)),) 90 | export LD := $(CC) 91 | else 92 | export LD := $(CXX) 93 | endif 94 | 95 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ 96 | $(sFILES:.s=.o) $(SFILES:.S=.o) \ 97 | $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) 98 | 99 | #--------------------------------------------------------------------------------- 100 | # build a list of include paths 101 | #--------------------------------------------------------------------------------- 102 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 103 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 104 | -I$(CURDIR)/$(BUILD) \ 105 | -I$(PORTLIBS)/include 106 | 107 | #--------------------------------------------------------------------------------- 108 | # build a list of library paths 109 | #--------------------------------------------------------------------------------- 110 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ 111 | -L$(PORTLIBS)/lib 112 | 113 | export OUTPUT := $(CURDIR)/$(TARGET) 114 | .PHONY: $(BUILD) clean install 115 | 116 | #--------------------------------------------------------------------------------- 117 | $(BUILD): sd_loader/sd_loader.h 118 | @[ -d $@ ] || mkdir -p $@ 119 | @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/sd_loader -f $(CURDIR)/sd_loader/Makefile 120 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 121 | 122 | sd_loader_elf := sd_loader/sd_loader.h 123 | 124 | $(sd_loader_elf): 125 | make -C sd_loader 126 | 127 | #--------------------------------------------------------------------------------- 128 | clean: 129 | @echo clean ... 130 | @$(MAKE) --no-print-directory -C $(CURDIR)/sd_loader -f $(CURDIR)/sd_loader/Makefile clean 131 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf 132 | 133 | #--------------------------------------------------------------------------------- 134 | else 135 | 136 | DEPENDS := $(OFILES:.o=.d) 137 | 138 | #--------------------------------------------------------------------------------- 139 | # main targets 140 | #--------------------------------------------------------------------------------- 141 | $(OUTPUT).elf: $(OFILES) 142 | 143 | #--------------------------------------------------------------------------------- 144 | # This rule links in binary data with the .jpg extension 145 | #--------------------------------------------------------------------------------- 146 | %.elf: link.ld $(OFILES) 147 | @echo "linking ... $(TARGET).elf" 148 | $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) 149 | $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ 150 | $(Q)$(OBJCOPY) -O binary -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf ../payload.bin 151 | 152 | #--------------------------------------------------------------------------------- 153 | %.a: 154 | #--------------------------------------------------------------------------------- 155 | @echo $(notdir $@) 156 | @rm -f $@ 157 | @$(AR) -rc $@ $^ 158 | 159 | #--------------------------------------------------------------------------------- 160 | %.o: %.cpp 161 | @echo $(notdir $<) 162 | @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) 163 | 164 | #--------------------------------------------------------------------------------- 165 | %.o: %.c 166 | @echo $(notdir $<) 167 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) 168 | 169 | #--------------------------------------------------------------------------------- 170 | %.o: %.S 171 | @echo $(notdir $<) 172 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) 173 | 174 | #--------------------------------------------------------------------------------- 175 | %.png.o : %.png 176 | @echo $(notdir $<) 177 | @bin2s -a 32 $< | $(AS) -o $(@) 178 | 179 | #--------------------------------------------------------------------------------- 180 | %.ttf.o : %.ttf 181 | @echo $(notdir $<) 182 | @bin2s -a 32 $< | $(AS) -o $(@) 183 | 184 | -include $(DEPENDS) 185 | 186 | #--------------------------------------------------------------------------------- 187 | endif 188 | #--------------------------------------------------------------------------------- 189 | -------------------------------------------------------------------------------- /sd_loader/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | ifeq ($(strip $(DEVKITPPC)),) 7 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 8 | endif 9 | export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) 10 | export LIBOGC_INC := $(DEVKITPRO)/libogc/include 11 | export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii 12 | export PORTLIBS := $(DEVKITPRO)/portlibs/ppc 13 | 14 | PREFIX := powerpc-eabi- 15 | 16 | export AS := $(PREFIX)as 17 | export CC := $(PREFIX)gcc 18 | export CXX := $(PREFIX)g++ 19 | export AR := $(PREFIX)ar 20 | export OBJCOPY := $(PREFIX)objcopy 21 | 22 | #--------------------------------------------------------------------------------- 23 | # TARGET is the name of the output 24 | # BUILD is the directory where object files & intermediate files will be placed 25 | # SOURCES is a list of directories containing source code 26 | # INCLUDES is a list of directories containing extra header files 27 | #--------------------------------------------------------------------------------- 28 | TARGET := sd_loader 29 | BUILD := build 30 | BUILD_DBG := $(TARGET)_dbg 31 | SOURCES := src 32 | DATA := 33 | INCLUDES := 34 | 35 | #--------------------------------------------------------------------------------- 36 | # options for code generation 37 | #--------------------------------------------------------------------------------- 38 | CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-builtin \ 39 | -Os -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 40 | CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ 41 | -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 42 | ASFLAGS := -mregnames 43 | LDFLAGS := -nostartfiles -Wl,--gc-sections 44 | 45 | Q := @ 46 | MAKEFLAGS += --no-print-directory 47 | #--------------------------------------------------------------------------------- 48 | # any extra libraries we wish to link with the project 49 | #--------------------------------------------------------------------------------- 50 | LIBS := 51 | 52 | #--------------------------------------------------------------------------------- 53 | # list of directories containing libraries, this must be the top level containing 54 | # include and lib 55 | #--------------------------------------------------------------------------------- 56 | LIBDIRS := $(CURDIR) \ 57 | $(DEVKITPPC)/lib \ 58 | $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 59 | 60 | 61 | #--------------------------------------------------------------------------------- 62 | # no real need to edit anything past this point unless you need to add additional 63 | # rules for different file extensions 64 | #--------------------------------------------------------------------------------- 65 | ifneq ($(BUILD),$(notdir $(CURDIR))) 66 | #--------------------------------------------------------------------------------- 67 | export PROJECTDIR := $(CURDIR) 68 | export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) 69 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 70 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 71 | export DEPSDIR := $(CURDIR)/$(BUILD) 72 | 73 | #--------------------------------------------------------------------------------- 74 | # automatically build a list of object files for our project 75 | #--------------------------------------------------------------------------------- 76 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 77 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 78 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 79 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 80 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 81 | TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) 82 | PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) 83 | 84 | #--------------------------------------------------------------------------------- 85 | # use CXX for linking C++ projects, CC for standard C 86 | #--------------------------------------------------------------------------------- 87 | ifeq ($(strip $(CPPFILES)),) 88 | export LD := $(CC) 89 | else 90 | export LD := $(CXX) 91 | endif 92 | 93 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ 94 | $(sFILES:.s=.o) $(SFILES:.S=.o) \ 95 | $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) 96 | 97 | #--------------------------------------------------------------------------------- 98 | # build a list of include paths 99 | #--------------------------------------------------------------------------------- 100 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 101 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 102 | -I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \ 103 | -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 104 | 105 | #--------------------------------------------------------------------------------- 106 | # path to tools 107 | #--------------------------------------------------------------------------------- 108 | DEVKITPATH=$(shell echo "$(DEVKITPRO)" | sed -e 's/^\([a-zA-Z]\):/\/\1/') 109 | export PATH := $(DEVKITPATH)/tools/bin:$(DEVKITPATH)/devkitPPC/bin:$(PATH) 110 | 111 | #--------------------------------------------------------------------------------- 112 | # build a list of library paths 113 | #--------------------------------------------------------------------------------- 114 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ 115 | -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib 116 | 117 | export OUTPUT := $(CURDIR)/$(TARGET) 118 | .PHONY: $(BUILD) clean install 119 | 120 | #--------------------------------------------------------------------------------- 121 | $(BUILD): 122 | @[ -d $@ ] || mkdir -p $@ 123 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 124 | 125 | #--------------------------------------------------------------------------------- 126 | clean: 127 | @echo clean ... 128 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(BUILD_DBG).c $(BUILD_DBG).h 129 | 130 | #--------------------------------------------------------------------------------- 131 | else 132 | 133 | DEPENDS := $(OFILES:.o=.d) 134 | 135 | #--------------------------------------------------------------------------------- 136 | # main targets 137 | #--------------------------------------------------------------------------------- 138 | $(OUTPUT).h: $(OFILES) 139 | 140 | $(OUTPUT).c: $(OUTPUT).elf 141 | @raw2c $< 142 | @cp $(TARGET).c $@ 143 | 144 | $(OUTPUT).h: $(OUTPUT).c 145 | @cp $(TARGET).h $@ 146 | 147 | #--------------------------------------------------------------------------------- 148 | # This rule links in binary data with the .jpg extension 149 | #--------------------------------------------------------------------------------- 150 | %.elf: link.ld $(OFILES) 151 | @echo "linking ... $(TARGET).elf" 152 | $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) 153 | $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ 154 | 155 | #--------------------------------------------------------------------------------- 156 | %.a: 157 | #--------------------------------------------------------------------------------- 158 | @echo $(notdir $@) 159 | @rm -f $@ 160 | @$(AR) -rc $@ $^ 161 | 162 | #--------------------------------------------------------------------------------- 163 | %.o: %.cpp 164 | @echo $(notdir $<) 165 | @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) 166 | 167 | #--------------------------------------------------------------------------------- 168 | %.o: %.c 169 | @echo $(notdir $<) 170 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) 171 | 172 | #--------------------------------------------------------------------------------- 173 | %.o: %.S 174 | @echo $(notdir $<) 175 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) 176 | 177 | #--------------------------------------------------------------------------------- 178 | %.png.o : %.png 179 | @echo $(notdir $<) 180 | @bin2s -a 32 $< | $(AS) -o $(@) 181 | 182 | #--------------------------------------------------------------------------------- 183 | %.ttf.o : %.ttf 184 | @echo $(notdir $<) 185 | @bin2s -a 32 $< | $(AS) -o $(@) 186 | 187 | -include $(DEPENDS) 188 | 189 | #--------------------------------------------------------------------------------- 190 | endif 191 | #--------------------------------------------------------------------------------- 192 | -------------------------------------------------------------------------------- /src/entry.c: -------------------------------------------------------------------------------- 1 | #include "elf_abi.h" 2 | #include "../sd_loader/src/common.h" 3 | #include "../sd_loader/sd_loader.h" 4 | #include 5 | #include "dynamic.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4) 17 | #define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828) 18 | #define OSFatal ((void (*)(char* msg))0x01031618) 19 | 20 | #define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__); 21 | #define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) 22 | 23 | #define ADDRESS_OSTitle_main_entry_ptr 0x1005E040 24 | #define ADDRESS_main_entry_hook 0x0101c56c 25 | 26 | #define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown 27 | #define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games 28 | #define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader 29 | #define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu 30 | #define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) 31 | 32 | #define address_LiWaitIopComplete 0x01010180 33 | #define address_LiWaitIopCompleteWithInterrupts 0x0101006C 34 | #define address_LiWaitOneChunk 0x0100080C 35 | #define address_PrepareTitle_hook 0xFFF184E4 36 | #define address_sgIsLoadingBuffer 0xEFE19E80 37 | #define address_gDynloadInitialized 0xEFE13DBC 38 | 39 | /* assembly functions */ 40 | extern void Syscall_0x36(void); 41 | extern void KernelPatches(void); 42 | extern void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len); 43 | 44 | extern void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len); 45 | 46 | 47 | void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); 48 | 49 | typedef struct _private_data_t { 50 | EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align); 51 | EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr); 52 | 53 | EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s); 54 | EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s); 55 | 56 | EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*); 57 | EXPORT_DECL(void, exit, int); 58 | EXPORT_DECL(void, DCInvalidateRange, const void *addr, unsigned int length); 59 | EXPORT_DECL(void, DCFlushRange, const void *addr, unsigned int length); 60 | EXPORT_DECL(void, ICInvalidateRange, const void *addr, unsigned int length); 61 | 62 | EXPORT_DECL(int, FSInit, void); 63 | EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); 64 | EXPORT_DECL(int, FSDelClient, void *pClient); 65 | 66 | EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); 67 | 68 | EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); 69 | 70 | EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); 71 | 72 | EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); 73 | 74 | EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); 75 | 76 | EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); 77 | 78 | EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); 79 | 80 | EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); 81 | 82 | EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv); 83 | 84 | EXPORT_DECL(int, _SYSLaunchMiiStudio); 85 | 86 | EXPORT_DECL(int, SYSLaunchMenu); 87 | 88 | EXPORT_DECL(uint64_t, OSGetTitleID); 89 | } private_data_t; 90 | 91 | static void InstallPatches(private_data_t *private_data); 92 | 93 | 94 | static void loadFunctionPointers(private_data_t * private_data) { 95 | unsigned int coreinit_handle; 96 | 97 | OSDynLoad_Acquire("coreinit", &coreinit_handle); 98 | 99 | unsigned int *functionPtr = 0; 100 | 101 | OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); 102 | private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr; 103 | OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); 104 | private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr; 105 | 106 | OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID); 107 | OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); 108 | OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); 109 | OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange); 110 | OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", private_data->DCInvalidateRange); 111 | OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", private_data->ICInvalidateRange); 112 | OS_FIND_EXPORT(coreinit_handle, "OSEffectiveToPhysical", private_data->OSEffectiveToPhysical); 113 | OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit); 114 | 115 | OS_FIND_EXPORT(coreinit_handle, "FSInit", private_data->FSInit); 116 | OS_FIND_EXPORT(coreinit_handle, "FSAddClientEx", private_data->FSAddClientEx); 117 | OS_FIND_EXPORT(coreinit_handle, "FSDelClient", private_data->FSDelClient); 118 | OS_FIND_EXPORT(coreinit_handle, "FSInitCmdBlock", private_data->FSInitCmdBlock); 119 | OS_FIND_EXPORT(coreinit_handle, "FSGetMountSource", private_data->FSGetMountSource); 120 | OS_FIND_EXPORT(coreinit_handle, "FSMount", private_data->FSMount); 121 | OS_FIND_EXPORT(coreinit_handle, "FSUnmount", private_data->FSUnmount); 122 | OS_FIND_EXPORT(coreinit_handle, "FSOpenFile", private_data->FSOpenFile); 123 | OS_FIND_EXPORT(coreinit_handle, "FSGetStatFile", private_data->FSGetStatFile); 124 | OS_FIND_EXPORT(coreinit_handle, "FSReadFile", private_data->FSReadFile); 125 | OS_FIND_EXPORT(coreinit_handle, "FSCloseFile", private_data->FSCloseFile); 126 | 127 | unsigned int sysapp_handle; 128 | OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); 129 | OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle); 130 | OS_FIND_EXPORT(sysapp_handle, "_SYSLaunchMiiStudio", private_data->_SYSLaunchMiiStudio); 131 | OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu); 132 | } 133 | 134 | static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart) { 135 | Elf32_Ehdr *ehdr; 136 | Elf32_Phdr *phdrs; 137 | unsigned char *image; 138 | int i; 139 | 140 | ehdr = (Elf32_Ehdr *) elfstart; 141 | 142 | if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0) 143 | return 0; 144 | 145 | if(ehdr->e_phentsize != sizeof(Elf32_Phdr)) 146 | return 0; 147 | 148 | phdrs = (Elf32_Phdr*)(elfstart + ehdr->e_phoff); 149 | 150 | for(i = 0; i < ehdr->e_phnum; i++) { 151 | if(phdrs[i].p_type != PT_LOAD) 152 | continue; 153 | 154 | if(phdrs[i].p_filesz > phdrs[i].p_memsz) 155 | continue; 156 | 157 | if(!phdrs[i].p_filesz) 158 | continue; 159 | 160 | unsigned int p_paddr = phdrs[i].p_paddr; 161 | image = (unsigned char *) (elfstart + phdrs[i].p_offset); 162 | 163 | private_data->memcpy ((void *) p_paddr, image, phdrs[i].p_filesz); 164 | private_data->DCFlushRange((void*)p_paddr, phdrs[i].p_filesz); 165 | 166 | if(phdrs[i].p_flags & PF_X) 167 | private_data->ICInvalidateRange ((void *) p_paddr, phdrs[i].p_memsz); 168 | } 169 | 170 | //! clear BSS 171 | Elf32_Shdr *shdr = (Elf32_Shdr *) (elfstart + ehdr->e_shoff); 172 | for(i = 0; i < ehdr->e_shnum; i++) { 173 | const char *section_name = ((const char*)elfstart) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; 174 | if(section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') { 175 | private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size); 176 | private_data->DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size); 177 | } else if(section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') { 178 | private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size); 179 | private_data->DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size); 180 | } 181 | } 182 | 183 | return ehdr->e_entry; 184 | } 185 | 186 | void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) { 187 | pdata->ICInvalidateRange(&value, 4); 188 | pdata->DCFlushRange(&value, 4); 189 | 190 | uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *) addr); 191 | uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *) &value); 192 | 193 | SC_0x25_KernelCopyData(dst, src, 4); 194 | 195 | pdata->DCFlushRange((void *) addr, 4); 196 | pdata->ICInvalidateRange((void *) addr, 4); 197 | } 198 | 199 | bool CheckRunning() { 200 | switch (ProcUIProcessMessages(true)) { 201 | case PROCUI_STATUS_EXITING: { 202 | return false; 203 | } 204 | case PROCUI_STATUS_RELEASE_FOREGROUND: { 205 | ProcUIDrawDoneRelease(); 206 | break; 207 | } 208 | case PROCUI_STATUS_IN_FOREGROUND: { 209 | break; 210 | } 211 | case PROCUI_STATUS_IN_BACKGROUND: 212 | default: 213 | break; 214 | } 215 | return true; 216 | } 217 | 218 | int _start(int argc, char **argv) { 219 | kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int) SCKernelCopyData); 220 | kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int) SCKernelCopyData); 221 | kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int) SCKernelCopyData); 222 | kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int) SCKernelCopyData); 223 | kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int) SCKernelCopyData); 224 | 225 | kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches); 226 | kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches); 227 | kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches); 228 | kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches); 229 | kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches); 230 | 231 | Syscall_0x36(); 232 | 233 | private_data_t private_data; 234 | loadFunctionPointers(&private_data); 235 | 236 | InstallPatches(&private_data); 237 | 238 | unsigned char *pElfBuffer = (unsigned char *) sd_loader; // use this address as temporary to load the elf 239 | 240 | unsigned int mainEntryPoint = load_elf_image(&private_data, pElfBuffer); 241 | 242 | if (mainEntryPoint == 0) { 243 | OSFatal("failed to load elf"); 244 | } 245 | 246 | //! Install our entry point hook 247 | unsigned int repl_addr = ADDRESS_main_entry_hook; 248 | unsigned int jump_addr = mainEntryPoint & 0x03fffffc; 249 | 250 | unsigned int bufferU32 = 0x48000003 | jump_addr; 251 | KernelWriteU32(repl_addr, bufferU32, &private_data); 252 | 253 | InitFunctionPointers(); 254 | 255 | if ( 256 | OSGetTitleID() == 0x000500101004A200L || // mii maker eur 257 | OSGetTitleID() == 0x000500101004A100L || // mii maker usa 258 | OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn 259 | 260 | // restart mii maker. 261 | private_data.SYSRelaunchTitle(0, 0); 262 | private_data.exit(0); 263 | } else { 264 | ProcUIInit(OSSavesDone_ReadyToRelease); 265 | for (int i = 0; i < argc; i++) { 266 | if(strcmp(argv[i], "void forceDefaultTitleIDToWiiUMenu(void)") == 0){ 267 | if((i + 1) < argc){ 268 | i++; 269 | void (*forceDefaultTitleIDToWiiUMenu)(void) = (void (*)(void)) argv[i]; 270 | forceDefaultTitleIDToWiiUMenu(); 271 | } 272 | } 273 | } 274 | SYSLaunchMenu(); 275 | 276 | while (CheckRunning()) { 277 | // wait. 278 | OSSleepTicks(OSMillisecondsToTicks(100)); 279 | } 280 | ProcUIShutdown(); 281 | 282 | return 0; 283 | } 284 | 285 | return 0; 286 | } 287 | 288 | /* Write a 32-bit word with kernel permissions */ 289 | void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { 290 | asm volatile ( 291 | "li 3,1\n" 292 | "li 4,0\n" 293 | "mr 5,%1\n" 294 | "li 6,0\n" 295 | "li 7,0\n" 296 | "lis 8,1\n" 297 | "mr 9,%0\n" 298 | "mr %1,1\n" 299 | "li 0,0x3500\n" 300 | "sc\n" 301 | "nop\n" 302 | "mr 1,%1\n" 303 | : 304 | : "r"(addr), "r"(value) 305 | : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", 306 | "11", "12" 307 | ); 308 | } 309 | 310 | /* 311 | unsigned int _start(int argc, char **argv) { 312 | if (OSGetTitleID() == 0x000500101004A200 || // mii maker eur 313 | OSGetTitleID() == 0x000500101004A100 || // mii maker usa 314 | OSGetTitleID() == 0x000500101004A000) { // mii maker jpn 315 | // load hbl 316 | return EXIT_SUCCESS; 317 | } 318 | // load real application 319 | return EXIT_RELAUNCH_ON_LOAD; 320 | } 321 | */ 322 | const unsigned char homebrew_stub[] = 323 | {0x94, 0x21, 0xff, 0xf8, 0x7c, 0x08, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x0c, 0x48, 0x81, 0xd5, 0xc1, 0x6c, 0x69, 0x00, 0x05, 0x2c, 0x09, 0x00, 0x10, 0x40, 0x82, 0x00, 0x10, 0x6c, 0x89, 0xef, 0xfb, 324 | 0x2c, 0x09, 0xa2, 0x00, 0x41, 0x82, 0x00, 0x3c, 0x48, 0x81, 0xd5, 0xa5, 0x6c, 0x69, 0x00, 0x05, 0x2c, 0x09, 0x00, 0x10, 0x40, 0x82, 0x00, 0x10, 0x6c, 0x89, 0xef, 0xfb, 0x2c, 0x09, 0xa1, 0x00, 325 | 0x41, 0x82, 0x00, 0x20, 0x48, 0x81, 0xd5, 0x89, 0x6c, 0x69, 0x00, 0x05, 0x2c, 0x09, 0x00, 0x10, 0x40, 0x82, 0x00, 0x24, 0x6c, 0x89, 0xef, 0xfb, 0x2c, 0x09, 0xa0, 0x00, 0x40, 0x82, 0x00, 0x18, 326 | 0x38, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0c, 0x38, 0x21, 0x00, 0x08, 0x7c, 0x08, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x38, 0x60, 0xff, 0xfd, 0x4b, 0xff, 0xff, 0xec}; 327 | 328 | /* ****************************************************************** */ 329 | /* INSTALL PATCHES */ 330 | /* All OS specific stuff is done here */ 331 | /* ****************************************************************** */ 332 | static void InstallPatches(private_data_t *private_data) { 333 | OsSpecifics osSpecificFunctions; 334 | private_data->memset(&osSpecificFunctions, 0, sizeof(OsSpecifics)); 335 | 336 | unsigned int bufferU32; 337 | /* Pre-setup a few options to defined values */ 338 | bufferU32 = 550; 339 | private_data->memcpy((void*)&OS_FIRMWARE, &bufferU32, sizeof(bufferU32)); 340 | bufferU32 = 0xDEADC0DE; 341 | private_data->memcpy((void*)&MAIN_ENTRY_ADDR, &bufferU32, sizeof(bufferU32)); 342 | private_data->memcpy((void*)&ELF_DATA_ADDR, &bufferU32, sizeof(bufferU32)); 343 | bufferU32 = 0; 344 | private_data->memcpy((void*)&ELF_DATA_SIZE, &bufferU32, sizeof(bufferU32)); 345 | private_data->memcpy((void*)&HBL_CHANNEL, &bufferU32, sizeof(bufferU32)); 346 | 347 | // If we install the sd_loader but don't have any homebrew loaded some applications won't start. 348 | // We load a stub that just opens the real app and opens the hbl when opening the mii maker. 349 | private_data->memcpy((void *) 0x00802000, homebrew_stub, sizeof(homebrew_stub)); 350 | MAIN_ENTRY_ADDR = 0x00802000; 351 | 352 | osSpecificFunctions.addr_OSDynLoad_Acquire = (unsigned int)OSDynLoad_Acquire; 353 | osSpecificFunctions.addr_OSDynLoad_FindExport = (unsigned int)OSDynLoad_FindExport; 354 | 355 | osSpecificFunctions.addr_KernSyscallTbl1 = KERN_SYSCALL_TBL_1; 356 | osSpecificFunctions.addr_KernSyscallTbl2 = KERN_SYSCALL_TBL_2; 357 | osSpecificFunctions.addr_KernSyscallTbl3 = KERN_SYSCALL_TBL_3; 358 | osSpecificFunctions.addr_KernSyscallTbl4 = KERN_SYSCALL_TBL_4; 359 | osSpecificFunctions.addr_KernSyscallTbl5 = KERN_SYSCALL_TBL_5; 360 | 361 | osSpecificFunctions.LiWaitIopComplete = (int (*)(int, int *)) address_LiWaitIopComplete; 362 | osSpecificFunctions.LiWaitIopCompleteWithInterrupts = (int (*)(int, int *)) address_LiWaitIopCompleteWithInterrupts; 363 | osSpecificFunctions.addr_LiWaitOneChunk = address_LiWaitOneChunk; 364 | osSpecificFunctions.addr_PrepareTitle_hook = address_PrepareTitle_hook; 365 | osSpecificFunctions.addr_sgIsLoadingBuffer = address_sgIsLoadingBuffer; 366 | osSpecificFunctions.addr_gDynloadInitialized = address_gDynloadInitialized; 367 | osSpecificFunctions.orig_LiWaitOneChunkInstr = *(unsigned int*)address_LiWaitOneChunk; 368 | 369 | //! pointer to main entry point of a title 370 | osSpecificFunctions.addr_OSTitle_main_entry = ADDRESS_OSTitle_main_entry_ptr; 371 | 372 | private_data->memcpy((void*)OS_SPECIFICS, &osSpecificFunctions, sizeof(OsSpecifics)); 373 | } 374 | -------------------------------------------------------------------------------- /src/elf_abi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1996, 2001, 2002 3 | * Erik Theisen. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /* 29 | * This is the ELF ABI header file 30 | * formerly known as "elf_abi.h". 31 | */ 32 | 33 | #ifndef _ELF_ABI_H 34 | #define _ELF_ABI_H 35 | 36 | /* 37 | * This version doesn't work for 64-bit ABIs - Erik. 38 | */ 39 | 40 | /* 41 | * These typedefs need to be handled better. 42 | */ 43 | typedef unsigned int Elf32_Addr; /* Unsigned program address */ 44 | typedef unsigned int Elf32_Off; /* Unsigned file offset */ 45 | typedef signed int Elf32_Sword; /* Signed large integer */ 46 | typedef unsigned int Elf32_Word; /* Unsigned large integer */ 47 | typedef unsigned short Elf32_Half; /* Unsigned medium integer */ 48 | 49 | /* e_ident[] identification indexes */ 50 | #define EI_MAG0 0 /* file ID */ 51 | #define EI_MAG1 1 /* file ID */ 52 | #define EI_MAG2 2 /* file ID */ 53 | #define EI_MAG3 3 /* file ID */ 54 | #define EI_CLASS 4 /* file class */ 55 | #define EI_DATA 5 /* data encoding */ 56 | #define EI_VERSION 6 /* ELF header version */ 57 | #define EI_OSABI 7 /* OS/ABI specific ELF extensions */ 58 | #define EI_ABIVERSION 8 /* ABI target version */ 59 | #define EI_PAD 9 /* start of pad bytes */ 60 | #define EI_NIDENT 16 /* Size of e_ident[] */ 61 | 62 | /* e_ident[] magic number */ 63 | #define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ 64 | #define ELFMAG1 'E' /* e_ident[EI_MAG1] */ 65 | #define ELFMAG2 'L' /* e_ident[EI_MAG2] */ 66 | #define ELFMAG3 'F' /* e_ident[EI_MAG3] */ 67 | #define ELFMAG "\177ELF" /* magic */ 68 | #define SELFMAG 4 /* size of magic */ 69 | 70 | /* e_ident[] file class */ 71 | #define ELFCLASSNONE 0 /* invalid */ 72 | #define ELFCLASsigned int 1 /* 32-bit objs */ 73 | #define ELFCLASS64 2 /* 64-bit objs */ 74 | #define ELFCLASSNUM 3 /* number of classes */ 75 | 76 | /* e_ident[] data encoding */ 77 | #define ELFDATANONE 0 /* invalid */ 78 | #define ELFDATA2LSB 1 /* Little-Endian */ 79 | #define ELFDATA2MSB 2 /* Big-Endian */ 80 | #define ELFDATANUM 3 /* number of data encode defines */ 81 | 82 | /* e_ident[] OS/ABI specific ELF extensions */ 83 | #define ELFOSABI_NONE 0 /* No extension specified */ 84 | #define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ 85 | #define ELFOSABI_NETBSD 2 /* NetBSD */ 86 | #define ELFOSABI_LINUX 3 /* Linux */ 87 | #define ELFOSABI_SOLARIS 6 /* Sun Solaris */ 88 | #define ELFOSABI_AIX 7 /* AIX */ 89 | #define ELFOSABI_IRIX 8 /* IRIX */ 90 | #define ELFOSABI_FREEBSD 9 /* FreeBSD */ 91 | #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ 92 | #define ELFOSABI_MODESTO 11 /* Novell Modesto */ 93 | #define ELFOSABI_OPENBSD 12 /* OpenBSD */ 94 | /* 64-255 Architecture-specific value range */ 95 | 96 | /* e_ident[] ABI Version */ 97 | #define ELFABIVERSION 0 98 | 99 | /* e_ident */ 100 | #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ 101 | (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ 102 | (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ 103 | (ehdr).e_ident[EI_MAG3] == ELFMAG3) 104 | 105 | /* ELF Header */ 106 | typedef struct elfhdr{ 107 | unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ 108 | Elf32_Half e_type; /* object file type */ 109 | Elf32_Half e_machine; /* machine */ 110 | Elf32_Word e_version; /* object file version */ 111 | Elf32_Addr e_entry; /* virtual entry point */ 112 | Elf32_Off e_phoff; /* program header table offset */ 113 | Elf32_Off e_shoff; /* section header table offset */ 114 | Elf32_Word e_flags; /* processor-specific flags */ 115 | Elf32_Half e_ehsize; /* ELF header size */ 116 | Elf32_Half e_phentsize; /* program header entry size */ 117 | Elf32_Half e_phnum; /* number of program header entries */ 118 | Elf32_Half e_shentsize; /* section header entry size */ 119 | Elf32_Half e_shnum; /* number of section header entries */ 120 | Elf32_Half e_shstrndx; /* section header table's "section 121 | header string table" entry offset */ 122 | } Elf32_Ehdr; 123 | 124 | /* e_type */ 125 | #define ET_NONE 0 /* No file type */ 126 | #define ET_REL 1 /* relocatable file */ 127 | #define ET_EXEC 2 /* executable file */ 128 | #define ET_DYN 3 /* shared object file */ 129 | #define ET_CORE 4 /* core file */ 130 | #define ET_NUM 5 /* number of types */ 131 | #define ET_LOOS 0xfe00 /* reserved range for operating */ 132 | #define ET_HIOS 0xfeff /* system specific e_type */ 133 | #define ET_LOPROC 0xff00 /* reserved range for processor */ 134 | #define ET_HIPROC 0xffff /* specific e_type */ 135 | 136 | /* e_machine */ 137 | #define EM_NONE 0 /* No Machine */ 138 | #define EM_M32 1 /* AT&T WE 32100 */ 139 | #define EM_SPARC 2 /* SPARC */ 140 | #define EM_386 3 /* Intel 80386 */ 141 | #define EM_68K 4 /* Motorola 68000 */ 142 | #define EM_88K 5 /* Motorola 88000 */ 143 | #if 0 144 | #define EM_486 6 /* RESERVED - was Intel 80486 */ 145 | #endif 146 | #define EM_860 7 /* Intel 80860 */ 147 | #define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ 148 | #define EM_S370 9 /* IBM System/370 Processor */ 149 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ 150 | #if 0 151 | #define EM_SPARC64 11 /* RESERVED - was SPARC v9 152 | 64-bit unoffical */ 153 | #endif 154 | /* RESERVED 11-14 for future use */ 155 | #define EM_PARISC 15 /* HPPA */ 156 | /* RESERVED 16 for future use */ 157 | #define EM_VPP500 17 /* Fujitsu VPP500 */ 158 | #define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ 159 | #define EM_960 19 /* Intel 80960 */ 160 | #define EM_PPC 20 /* PowerPC */ 161 | #define EM_PPC64 21 /* 64-bit PowerPC */ 162 | #define EM_S390 22 /* IBM System/390 Processor */ 163 | /* RESERVED 23-35 for future use */ 164 | #define EM_V800 36 /* NEC V800 */ 165 | #define EM_FR20 37 /* Fujitsu FR20 */ 166 | #define EM_RH32 38 /* TRW RH-32 */ 167 | #define EM_RCE 39 /* Motorola RCE */ 168 | #define EM_ARM 40 /* Advanced Risc Machines ARM */ 169 | #define EM_ALPHA 41 /* Digital Alpha */ 170 | #define EM_SH 42 /* Hitachi SH */ 171 | #define EM_SPARCV9 43 /* SPARC Version 9 */ 172 | #define EM_TRICORE 44 /* Siemens TriCore embedded processor */ 173 | #define EM_ARC 45 /* Argonaut RISC Core */ 174 | #define EM_H8_300 46 /* Hitachi H8/300 */ 175 | #define EM_H8_300H 47 /* Hitachi H8/300H */ 176 | #define EM_H8S 48 /* Hitachi H8S */ 177 | #define EM_H8_500 49 /* Hitachi H8/500 */ 178 | #define EM_IA_64 50 /* Intel Merced */ 179 | #define EM_MIPS_X 51 /* Stanford MIPS-X */ 180 | #define EM_COLDFIRE 52 /* Motorola Coldfire */ 181 | #define EM_68HC12 53 /* Motorola M68HC12 */ 182 | #define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ 183 | #define EM_PCP 55 /* Siemens PCP */ 184 | #define EM_NCPU 56 /* Sony nCPU embeeded RISC */ 185 | #define EM_NDR1 57 /* Denso NDR1 microprocessor */ 186 | #define EM_STARCORE 58 /* Motorola Start*Core processor */ 187 | #define EM_ME16 59 /* Toyota ME16 processor */ 188 | #define EM_ST100 60 /* STMicroelectronic ST100 processor */ 189 | #define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ 190 | #define EM_X86_64 62 /* AMD x86-64 */ 191 | #define EM_PDSP 63 /* Sony DSP Processor */ 192 | /* RESERVED 64,65 for future use */ 193 | #define EM_FX66 66 /* Siemens FX66 microcontroller */ 194 | #define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ 195 | #define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ 196 | #define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ 197 | #define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ 198 | #define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ 199 | #define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ 200 | #define EM_SVX 73 /* Silicon Graphics SVx */ 201 | #define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ 202 | #define EM_VAX 75 /* Digital VAX */ 203 | #define EM_CHRIS 76 /* Axis Communications embedded proc. */ 204 | #define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */ 205 | #define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ 206 | #define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ 207 | #define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */ 208 | #define EM_HUANY 81 /* Harvard University mach-indep objs */ 209 | #define EM_PRISM 82 /* SiTera Prism */ 210 | #define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ 211 | #define EM_FR30 84 /* Fujitsu FR30 */ 212 | #define EM_D10V 85 /* Mitsubishi DV10V */ 213 | #define EM_D30V 86 /* Mitsubishi DV30V */ 214 | #define EM_V850 87 /* NEC v850 */ 215 | #define EM_M32R 88 /* Mitsubishi M32R */ 216 | #define EM_MN10300 89 /* Matsushita MN10200 */ 217 | #define EM_MN10200 90 /* Matsushita MN10200 */ 218 | #define EM_PJ 91 /* picoJava */ 219 | #define EM_NUM 92 /* number of machine types */ 220 | 221 | /* Version */ 222 | #define EV_NONE 0 /* Invalid */ 223 | #define EV_CURRENT 1 /* Current */ 224 | #define EV_NUM 2 /* number of versions */ 225 | 226 | /* Section Header */ 227 | typedef struct { 228 | Elf32_Word sh_name; /* name - index into section header 229 | string table section */ 230 | Elf32_Word sh_type; /* type */ 231 | Elf32_Word sh_flags; /* flags */ 232 | Elf32_Addr sh_addr; /* address */ 233 | Elf32_Off sh_offset; /* file offset */ 234 | Elf32_Word sh_size; /* section size */ 235 | Elf32_Word sh_link; /* section header table index link */ 236 | Elf32_Word sh_info; /* extra information */ 237 | Elf32_Word sh_addralign; /* address alignment */ 238 | Elf32_Word sh_entsize; /* section entry size */ 239 | } Elf32_Shdr; 240 | 241 | /* Special Section Indexes */ 242 | #define SHN_UNDEF 0 /* undefined */ 243 | #define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ 244 | #define SHN_LOPROC 0xff00 /* reserved range for processor */ 245 | #define SHN_HIPROC 0xff1f /* specific section indexes */ 246 | #define SHN_LOOS 0xff20 /* reserved range for operating */ 247 | #define SHN_HIOS 0xff3f /* specific semantics */ 248 | #define SHN_ABS 0xfff1 /* absolute value */ 249 | #define SHN_COMMON 0xfff2 /* common symbol */ 250 | #define SHN_XINDEX 0xffff /* Index is an extra table */ 251 | #define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ 252 | 253 | /* sh_type */ 254 | #define SHT_NULL 0 /* inactive */ 255 | #define SHT_PROGBITS 1 /* program defined information */ 256 | #define SHT_SYMTAB 2 /* symbol table section */ 257 | #define SHT_STRTAB 3 /* string table section */ 258 | #define SHT_RELA 4 /* relocation section with addends*/ 259 | #define SHT_HASH 5 /* symbol hash table section */ 260 | #define SHT_DYNAMIC 6 /* dynamic section */ 261 | #define SHT_NOTE 7 /* note section */ 262 | #define SHT_NOBITS 8 /* no space section */ 263 | #define SHT_REL 9 /* relation section without addends */ 264 | #define SHT_SHLIB 10 /* reserved - purpose unknown */ 265 | #define SHT_DYNSYM 11 /* dynamic symbol table section */ 266 | #define SHT_INIT_ARRAY 14 /* Array of constructors */ 267 | #define SHT_FINI_ARRAY 15 /* Array of destructors */ 268 | #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ 269 | #define SHT_GROUP 17 /* Section group */ 270 | #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ 271 | #define SHT_NUM 19 /* number of section types */ 272 | #define SHT_LOOS 0x60000000 /* Start OS-specific */ 273 | #define SHT_HIOS 0x6fffffff /* End OS-specific */ 274 | #define SHT_LOPROC 0x70000000 /* reserved range for processor */ 275 | #define SHT_HIPROC 0x7fffffff /* specific section header types */ 276 | #define SHT_LOUSER 0x80000000 /* reserved range for application */ 277 | #define SHT_HIUSER 0xffffffff /* specific indexes */ 278 | 279 | /* Section names */ 280 | #define ELF_BSS ".bss" /* uninitialized data */ 281 | #define ELF_COMMENT ".comment" /* version control information */ 282 | #define ELF_DATA ".data" /* initialized data */ 283 | #define ELF_DATA1 ".data1" /* initialized data */ 284 | #define ELF_DEBUG ".debug" /* debug */ 285 | #define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ 286 | #define ELF_DYNSTR ".dynstr" /* dynamic string table */ 287 | #define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ 288 | #define ELF_FINI ".fini" /* termination code */ 289 | #define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */ 290 | #define ELF_GOT ".got" /* global offset table */ 291 | #define ELF_HASH ".hash" /* symbol hash table */ 292 | #define ELF_INIT ".init" /* initialization code */ 293 | #define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */ 294 | #define ELF_INTERP ".interp" /* Pathname of program interpreter */ 295 | #define ELF_LINE ".line" /* Symbolic line numnber information */ 296 | #define ELF_NOTE ".note" /* Contains note section */ 297 | #define ELF_PLT ".plt" /* Procedure linkage table */ 298 | #define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */ 299 | #define ELF_REL_DATA ".rel.data" /* relocation data */ 300 | #define ELF_REL_FINI ".rel.fini" /* relocation termination code */ 301 | #define ELF_REL_INIT ".rel.init" /* relocation initialization code */ 302 | #define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ 303 | #define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ 304 | #define ELF_REL_TEXT ".rel.text" /* relocation code */ 305 | #define ELF_RODATA ".rodata" /* read-only data */ 306 | #define ELF_RODATA1 ".rodata1" /* read-only data */ 307 | #define ELF_SHSTRTAB ".shstrtab" /* section header string table */ 308 | #define ELF_STRTAB ".strtab" /* string table */ 309 | #define ELF_SYMTAB ".symtab" /* symbol table */ 310 | #define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */ 311 | #define ELF_TBSS ".tbss" /* thread local uninit data */ 312 | #define ELF_TDATA ".tdata" /* thread local init data */ 313 | #define ELF_TDATA1 ".tdata1" /* thread local init data */ 314 | #define ELF_TEXT ".text" /* code */ 315 | 316 | /* Section Attribute Flags - sh_flags */ 317 | #define SHF_WRITE 0x1 /* Writable */ 318 | #define SHF_ALLOC 0x2 /* occupies memory */ 319 | #define SHF_EXECINSTR 0x4 /* executable */ 320 | #define SHF_MERGE 0x10 /* Might be merged */ 321 | #define SHF_STRINGS 0x20 /* Contains NULL terminated strings */ 322 | #define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */ 323 | #define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/ 324 | #define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */ 325 | #define SHF_GROUP 0x200 /* Member of section group */ 326 | #define SHF_TLS 0x400 /* Thread local storage */ 327 | #define SHF_MASKOS 0x0ff00000 /* OS specific */ 328 | #define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ 329 | /* specific section attributes */ 330 | 331 | /* Section Group Flags */ 332 | #define GRP_COMDAT 0x1 /* COMDAT group */ 333 | #define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */ 334 | #define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */ 335 | 336 | /* Symbol Table Entry */ 337 | typedef struct elf32_sym { 338 | Elf32_Word st_name; /* name - index into string table */ 339 | Elf32_Addr st_value; /* symbol value */ 340 | Elf32_Word st_size; /* symbol size */ 341 | unsigned char st_info; /* type and binding */ 342 | unsigned char st_other; /* 0 - no defined meaning */ 343 | Elf32_Half st_shndx; /* section header index */ 344 | } Elf32_Sym; 345 | 346 | /* Symbol table index */ 347 | #define STN_UNDEF 0 /* undefined */ 348 | 349 | /* Extract symbol info - st_info */ 350 | #define ELF32_ST_BIND(x) ((x) >> 4) 351 | #define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) 352 | #define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) 353 | #define ELF32_ST_VISIBILITY(x) ((x) & 0x3) 354 | 355 | /* Symbol Binding - ELF32_ST_BIND - st_info */ 356 | #define STB_LOCAL 0 /* Local symbol */ 357 | #define STB_GLOBAL 1 /* Global symbol */ 358 | #define STB_WEAK 2 /* like global - lower precedence */ 359 | #define STB_NUM 3 /* number of symbol bindings */ 360 | #define STB_LOOS 10 /* reserved range for operating */ 361 | #define STB_HIOS 12 /* system specific symbol bindings */ 362 | #define STB_LOPROC 13 /* reserved range for processor */ 363 | #define STB_HIPROC 15 /* specific symbol bindings */ 364 | 365 | /* Symbol type - ELF32_ST_TYPE - st_info */ 366 | #define STT_NOTYPE 0 /* not specified */ 367 | #define STT_OBJECT 1 /* data object */ 368 | #define STT_FUNC 2 /* function */ 369 | #define STT_SECTION 3 /* section */ 370 | #define STT_FILE 4 /* file */ 371 | #define STT_NUM 5 /* number of symbol types */ 372 | #define STT_TLS 6 /* Thread local storage symbol */ 373 | #define STT_LOOS 10 /* reserved range for operating */ 374 | #define STT_HIOS 12 /* system specific symbol types */ 375 | #define STT_LOPROC 13 /* reserved range for processor */ 376 | #define STT_HIPROC 15 /* specific symbol types */ 377 | 378 | /* Symbol visibility - ELF32_ST_VISIBILITY - st_other */ 379 | #define STV_DEFAULT 0 /* Normal visibility rules */ 380 | #define STV_INTERNAL 1 /* Processor specific hidden class */ 381 | #define STV_HIDDEN 2 /* Symbol unavailable in other mods */ 382 | #define STV_PROTECTED 3 /* Not preemptible, not exported */ 383 | 384 | 385 | /* Relocation entry with implicit addend */ 386 | typedef struct 387 | { 388 | Elf32_Addr r_offset; /* offset of relocation */ 389 | Elf32_Word r_info; /* symbol table index and type */ 390 | } Elf32_Rel; 391 | 392 | /* Relocation entry with explicit addend */ 393 | typedef struct 394 | { 395 | Elf32_Addr r_offset; /* offset of relocation */ 396 | Elf32_Word r_info; /* symbol table index and type */ 397 | Elf32_Sword r_addend; 398 | } Elf32_Rela; 399 | 400 | /* Extract relocation info - r_info */ 401 | #define ELF32_R_SYM(i) ((i) >> 8) 402 | #define ELF32_R_TYPE(i) ((unsigned char) (i)) 403 | #define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) 404 | 405 | /* Program Header */ 406 | typedef struct { 407 | Elf32_Word p_type; /* segment type */ 408 | Elf32_Off p_offset; /* segment offset */ 409 | Elf32_Addr p_vaddr; /* virtual address of segment */ 410 | Elf32_Addr p_paddr; /* physical address - ignored? */ 411 | Elf32_Word p_filesz; /* number of bytes in file for seg. */ 412 | Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ 413 | Elf32_Word p_flags; /* flags */ 414 | Elf32_Word p_align; /* memory alignment */ 415 | } Elf32_Phdr; 416 | 417 | /* Segment types - p_type */ 418 | #define PT_NULL 0 /* unused */ 419 | #define PT_LOAD 1 /* loadable segment */ 420 | #define PT_DYNAMIC 2 /* dynamic linking section */ 421 | #define PT_INTERP 3 /* the RTLD */ 422 | #define PT_NOTE 4 /* auxiliary information */ 423 | #define PT_SHLIB 5 /* reserved - purpose undefined */ 424 | #define PT_PHDR 6 /* program header */ 425 | #define PT_TLS 7 /* Thread local storage template */ 426 | #define PT_NUM 8 /* Number of segment types */ 427 | #define PT_LOOS 0x60000000 /* reserved range for operating */ 428 | #define PT_HIOS 0x6fffffff /* system specific segment types */ 429 | #define PT_LOPROC 0x70000000 /* reserved range for processor */ 430 | #define PT_HIPROC 0x7fffffff /* specific segment types */ 431 | 432 | /* Segment flags - p_flags */ 433 | #define PF_X 0x1 /* Executable */ 434 | #define PF_W 0x2 /* Writable */ 435 | #define PF_R 0x4 /* Readable */ 436 | #define PF_MASKOS 0x0ff00000 /* OS specific segment flags */ 437 | #define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ 438 | /* specific segment flags */ 439 | /* Dynamic structure */ 440 | typedef struct 441 | { 442 | Elf32_Sword d_tag; /* controls meaning of d_val */ 443 | union 444 | { 445 | Elf32_Word d_val; /* Multiple meanings - see d_tag */ 446 | Elf32_Addr d_ptr; /* program virtual address */ 447 | } d_un; 448 | } Elf32_Dyn; 449 | 450 | extern Elf32_Dyn _DYNAMIC[]; 451 | 452 | /* Dynamic Array Tags - d_tag */ 453 | #define DT_NULL 0 /* marks end of _DYNAMIC array */ 454 | #define DT_NEEDED 1 /* string table offset of needed lib */ 455 | #define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ 456 | #define DT_PLTGOT 3 /* address PLT/GOT */ 457 | #define DT_HASH 4 /* address of symbol hash table */ 458 | #define DT_STRTAB 5 /* address of string table */ 459 | #define DT_SYMTAB 6 /* address of symbol table */ 460 | #define DT_RELA 7 /* address of relocation table */ 461 | #define DT_RELASZ 8 /* size of relocation table */ 462 | #define DT_RELAENT 9 /* size of relocation entry */ 463 | #define DT_STRSZ 10 /* size of string table */ 464 | #define DT_SYMENT 11 /* size of symbol table entry */ 465 | #define DT_INIT 12 /* address of initialization func. */ 466 | #define DT_FINI 13 /* address of termination function */ 467 | #define DT_SONAME 14 /* string table offset of shared obj */ 468 | #define DT_RPATH 15 /* string table offset of library 469 | search path */ 470 | #define DT_SYMBOLIC 16 /* start sym search in shared obj. */ 471 | #define DT_REL 17 /* address of rel. tbl. w addends */ 472 | #define DT_RELSZ 18 /* size of DT_REL relocation table */ 473 | #define DT_RELENT 19 /* size of DT_REL relocation entry */ 474 | #define DT_PLTREL 20 /* PLT referenced relocation entry */ 475 | #define DT_DEBUG 21 /* bugger */ 476 | #define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ 477 | #define DT_JMPREL 23 /* add. of PLT's relocation entries */ 478 | #define DT_BIND_NOW 24 /* Process relocations of object */ 479 | #define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ 480 | #define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ 481 | #define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ 482 | #define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ 483 | #define DT_RUNPATH 29 /* Library search path */ 484 | #define DT_FLAGS 30 /* Flags for the object being loaded */ 485 | #define DT_ENCODING 32 /* Start of encoded range */ 486 | #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ 487 | #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ 488 | #define DT_NUM 34 /* Number used. */ 489 | #define DT_LOOS 0x60000000 /* reserved range for OS */ 490 | #define DT_HIOS 0x6fffffff /* specific dynamic array tags */ 491 | #define DT_LOPROC 0x70000000 /* reserved range for processor */ 492 | #define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ 493 | 494 | /* Dynamic Tag Flags - d_un.d_val */ 495 | #define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */ 496 | #define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */ 497 | #define DF_TEXTREL 0x04 /* Object contains text relocations */ 498 | #define DF_BIND_NOW 0x08 /* No lazy binding for this object */ 499 | #define DF_STATIC_TLS 0x10 /* Static thread local storage */ 500 | 501 | /* Standard ELF hashing function */ 502 | unsigned long elf_hash(const unsigned char *name); 503 | 504 | #define ELF_TARG_VER 1 /* The ver for which this code is intended */ 505 | 506 | /* 507 | * XXX - PowerPC defines really don't belong in here, 508 | * but we'll put them in for simplicity. 509 | */ 510 | 511 | /* Values for Elf32/64_Ehdr.e_flags. */ 512 | #define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ 513 | 514 | /* Cygnus local bits below */ 515 | #define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ 516 | #define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib 517 | flag */ 518 | 519 | /* PowerPC relocations defined by the ABIs */ 520 | #define R_PPC_NONE 0 521 | #define R_PPC_ADDR32 1 /* 32bit absolute address */ 522 | #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ 523 | #define R_PPC_ADDR16 3 /* 16bit absolute address */ 524 | #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ 525 | #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ 526 | #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ 527 | #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ 528 | #define R_PPC_ADDR14_BRTAKEN 8 529 | #define R_PPC_ADDR14_BRNTAKEN 9 530 | #define R_PPC_REL24 10 /* PC relative 26 bit */ 531 | #define R_PPC_REL14 11 /* PC relative 16 bit */ 532 | #define R_PPC_REL14_BRTAKEN 12 533 | #define R_PPC_REL14_BRNTAKEN 13 534 | #define R_PPC_GOT16 14 535 | #define R_PPC_GOT16_LO 15 536 | #define R_PPC_GOT16_HI 16 537 | #define R_PPC_GOT16_HA 17 538 | #define R_PPC_PLTREL24 18 539 | #define R_PPC_COPY 19 540 | #define R_PPC_GLOB_DAT 20 541 | #define R_PPC_JMP_SLOT 21 542 | #define R_PPC_RELATIVE 22 543 | #define R_PPC_LOCAL24PC 23 544 | #define R_PPC_UADDR32 24 545 | #define R_PPC_UADDR16 25 546 | #define R_PPC_REL32 26 547 | #define R_PPC_PLT32 27 548 | #define R_PPC_PLTREL32 28 549 | #define R_PPC_PLT16_LO 29 550 | #define R_PPC_PLT16_HI 30 551 | #define R_PPC_PLT16_HA 31 552 | #define R_PPC_SDAREL16 32 553 | #define R_PPC_SECTOFF 33 554 | #define R_PPC_SECTOFF_LO 34 555 | #define R_PPC_SECTOFF_HI 35 556 | #define R_PPC_SECTOFF_HA 36 557 | /* Keep this the last entry. */ 558 | #define R_PPC_NUM 37 559 | 560 | /* The remaining relocs are from the Embedded ELF ABI, and are not 561 | in the SVR4 ELF ABI. */ 562 | #define R_PPC_EMB_NADDR32 101 563 | #define R_PPC_EMB_NADDR16 102 564 | #define R_PPC_EMB_NADDR16_LO 103 565 | #define R_PPC_EMB_NADDR16_HI 104 566 | #define R_PPC_EMB_NADDR16_HA 105 567 | #define R_PPC_EMB_SDAI16 106 568 | #define R_PPC_EMB_SDA2I16 107 569 | #define R_PPC_EMB_SDA2REL 108 570 | #define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ 571 | #define R_PPC_EMB_MRKREF 110 572 | #define R_PPC_EMB_RELSEC16 111 573 | #define R_PPC_EMB_RELST_LO 112 574 | #define R_PPC_EMB_RELST_HI 113 575 | #define R_PPC_EMB_RELST_HA 114 576 | #define R_PPC_EMB_BIT_FLD 115 577 | #define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ 578 | 579 | /* Diab tool relocations. */ 580 | #define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ 581 | #define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ 582 | #define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ 583 | #define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ 584 | #define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ 585 | #define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ 586 | 587 | /* This is a phony reloc to handle any old fashioned TOC16 references 588 | that may still be in object files. */ 589 | #define R_PPC_TOC16 255 590 | 591 | #endif /* _ELF_H */ 592 | -------------------------------------------------------------------------------- /sd_loader/src/elf_abi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995, 1996, 2001, 2002 3 | * Erik Theisen. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /* 29 | * This is the ELF ABI header file 30 | * formerly known as "elf_abi.h". 31 | */ 32 | 33 | #ifndef _ELF_ABI_H 34 | #define _ELF_ABI_H 35 | 36 | /* 37 | * This version doesn't work for 64-bit ABIs - Erik. 38 | */ 39 | 40 | /* 41 | * These typedefs need to be handled better. 42 | */ 43 | typedef unsigned int Elf32_Addr; /* Unsigned program address */ 44 | typedef unsigned int Elf32_Off; /* Unsigned file offset */ 45 | typedef signed int Elf32_Sword; /* Signed large integer */ 46 | typedef unsigned int Elf32_Word; /* Unsigned large integer */ 47 | typedef unsigned short Elf32_Half; /* Unsigned medium integer */ 48 | 49 | /* e_ident[] identification indexes */ 50 | #define EI_MAG0 0 /* file ID */ 51 | #define EI_MAG1 1 /* file ID */ 52 | #define EI_MAG2 2 /* file ID */ 53 | #define EI_MAG3 3 /* file ID */ 54 | #define EI_CLASS 4 /* file class */ 55 | #define EI_DATA 5 /* data encoding */ 56 | #define EI_VERSION 6 /* ELF header version */ 57 | #define EI_OSABI 7 /* OS/ABI specific ELF extensions */ 58 | #define EI_ABIVERSION 8 /* ABI target version */ 59 | #define EI_PAD 9 /* start of pad bytes */ 60 | #define EI_NIDENT 16 /* Size of e_ident[] */ 61 | 62 | /* e_ident[] magic number */ 63 | #define ELFMAG0 0x7f /* e_ident[EI_MAG0] */ 64 | #define ELFMAG1 'E' /* e_ident[EI_MAG1] */ 65 | #define ELFMAG2 'L' /* e_ident[EI_MAG2] */ 66 | #define ELFMAG3 'F' /* e_ident[EI_MAG3] */ 67 | #define ELFMAG "\177ELF" /* magic */ 68 | #define SELFMAG 4 /* size of magic */ 69 | 70 | /* e_ident[] file class */ 71 | #define ELFCLASSNONE 0 /* invalid */ 72 | #define ELFCLASsigned int 1 /* 32-bit objs */ 73 | #define ELFCLASS64 2 /* 64-bit objs */ 74 | #define ELFCLASSNUM 3 /* number of classes */ 75 | 76 | /* e_ident[] data encoding */ 77 | #define ELFDATANONE 0 /* invalid */ 78 | #define ELFDATA2LSB 1 /* Little-Endian */ 79 | #define ELFDATA2MSB 2 /* Big-Endian */ 80 | #define ELFDATANUM 3 /* number of data encode defines */ 81 | 82 | /* e_ident[] OS/ABI specific ELF extensions */ 83 | #define ELFOSABI_NONE 0 /* No extension specified */ 84 | #define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */ 85 | #define ELFOSABI_NETBSD 2 /* NetBSD */ 86 | #define ELFOSABI_LINUX 3 /* Linux */ 87 | #define ELFOSABI_SOLARIS 6 /* Sun Solaris */ 88 | #define ELFOSABI_AIX 7 /* AIX */ 89 | #define ELFOSABI_IRIX 8 /* IRIX */ 90 | #define ELFOSABI_FREEBSD 9 /* FreeBSD */ 91 | #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */ 92 | #define ELFOSABI_MODESTO 11 /* Novell Modesto */ 93 | #define ELFOSABI_OPENBSD 12 /* OpenBSD */ 94 | /* 64-255 Architecture-specific value range */ 95 | 96 | /* e_ident[] ABI Version */ 97 | #define ELFABIVERSION 0 98 | 99 | /* e_ident */ 100 | #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ 101 | (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ 102 | (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ 103 | (ehdr).e_ident[EI_MAG3] == ELFMAG3) 104 | 105 | /* ELF Header */ 106 | typedef struct elfhdr{ 107 | unsigned char e_ident[EI_NIDENT]; /* ELF Identification */ 108 | Elf32_Half e_type; /* object file type */ 109 | Elf32_Half e_machine; /* machine */ 110 | Elf32_Word e_version; /* object file version */ 111 | Elf32_Addr e_entry; /* virtual entry point */ 112 | Elf32_Off e_phoff; /* program header table offset */ 113 | Elf32_Off e_shoff; /* section header table offset */ 114 | Elf32_Word e_flags; /* processor-specific flags */ 115 | Elf32_Half e_ehsize; /* ELF header size */ 116 | Elf32_Half e_phentsize; /* program header entry size */ 117 | Elf32_Half e_phnum; /* number of program header entries */ 118 | Elf32_Half e_shentsize; /* section header entry size */ 119 | Elf32_Half e_shnum; /* number of section header entries */ 120 | Elf32_Half e_shstrndx; /* section header table's "section 121 | header string table" entry offset */ 122 | } Elf32_Ehdr; 123 | 124 | /* e_type */ 125 | #define ET_NONE 0 /* No file type */ 126 | #define ET_REL 1 /* relocatable file */ 127 | #define ET_EXEC 2 /* executable file */ 128 | #define ET_DYN 3 /* shared object file */ 129 | #define ET_CORE 4 /* core file */ 130 | #define ET_NUM 5 /* number of types */ 131 | #define ET_LOOS 0xfe00 /* reserved range for operating */ 132 | #define ET_HIOS 0xfeff /* system specific e_type */ 133 | #define ET_LOPROC 0xff00 /* reserved range for processor */ 134 | #define ET_HIPROC 0xffff /* specific e_type */ 135 | 136 | /* e_machine */ 137 | #define EM_NONE 0 /* No Machine */ 138 | #define EM_M32 1 /* AT&T WE 32100 */ 139 | #define EM_SPARC 2 /* SPARC */ 140 | #define EM_386 3 /* Intel 80386 */ 141 | #define EM_68K 4 /* Motorola 68000 */ 142 | #define EM_88K 5 /* Motorola 88000 */ 143 | #if 0 144 | #define EM_486 6 /* RESERVED - was Intel 80486 */ 145 | #endif 146 | #define EM_860 7 /* Intel 80860 */ 147 | #define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ 148 | #define EM_S370 9 /* IBM System/370 Processor */ 149 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ 150 | #if 0 151 | #define EM_SPARC64 11 /* RESERVED - was SPARC v9 152 | 64-bit unoffical */ 153 | #endif 154 | /* RESERVED 11-14 for future use */ 155 | #define EM_PARISC 15 /* HPPA */ 156 | /* RESERVED 16 for future use */ 157 | #define EM_VPP500 17 /* Fujitsu VPP500 */ 158 | #define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */ 159 | #define EM_960 19 /* Intel 80960 */ 160 | #define EM_PPC 20 /* PowerPC */ 161 | #define EM_PPC64 21 /* 64-bit PowerPC */ 162 | #define EM_S390 22 /* IBM System/390 Processor */ 163 | /* RESERVED 23-35 for future use */ 164 | #define EM_V800 36 /* NEC V800 */ 165 | #define EM_FR20 37 /* Fujitsu FR20 */ 166 | #define EM_RH32 38 /* TRW RH-32 */ 167 | #define EM_RCE 39 /* Motorola RCE */ 168 | #define EM_ARM 40 /* Advanced Risc Machines ARM */ 169 | #define EM_ALPHA 41 /* Digital Alpha */ 170 | #define EM_SH 42 /* Hitachi SH */ 171 | #define EM_SPARCV9 43 /* SPARC Version 9 */ 172 | #define EM_TRICORE 44 /* Siemens TriCore embedded processor */ 173 | #define EM_ARC 45 /* Argonaut RISC Core */ 174 | #define EM_H8_300 46 /* Hitachi H8/300 */ 175 | #define EM_H8_300H 47 /* Hitachi H8/300H */ 176 | #define EM_H8S 48 /* Hitachi H8S */ 177 | #define EM_H8_500 49 /* Hitachi H8/500 */ 178 | #define EM_IA_64 50 /* Intel Merced */ 179 | #define EM_MIPS_X 51 /* Stanford MIPS-X */ 180 | #define EM_COLDFIRE 52 /* Motorola Coldfire */ 181 | #define EM_68HC12 53 /* Motorola M68HC12 */ 182 | #define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ 183 | #define EM_PCP 55 /* Siemens PCP */ 184 | #define EM_NCPU 56 /* Sony nCPU embeeded RISC */ 185 | #define EM_NDR1 57 /* Denso NDR1 microprocessor */ 186 | #define EM_STARCORE 58 /* Motorola Start*Core processor */ 187 | #define EM_ME16 59 /* Toyota ME16 processor */ 188 | #define EM_ST100 60 /* STMicroelectronic ST100 processor */ 189 | #define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ 190 | #define EM_X86_64 62 /* AMD x86-64 */ 191 | #define EM_PDSP 63 /* Sony DSP Processor */ 192 | /* RESERVED 64,65 for future use */ 193 | #define EM_FX66 66 /* Siemens FX66 microcontroller */ 194 | #define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ 195 | #define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ 196 | #define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ 197 | #define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ 198 | #define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ 199 | #define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ 200 | #define EM_SVX 73 /* Silicon Graphics SVx */ 201 | #define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ 202 | #define EM_VAX 75 /* Digital VAX */ 203 | #define EM_CHRIS 76 /* Axis Communications embedded proc. */ 204 | #define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */ 205 | #define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ 206 | #define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ 207 | #define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */ 208 | #define EM_HUANY 81 /* Harvard University mach-indep objs */ 209 | #define EM_PRISM 82 /* SiTera Prism */ 210 | #define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ 211 | #define EM_FR30 84 /* Fujitsu FR30 */ 212 | #define EM_D10V 85 /* Mitsubishi DV10V */ 213 | #define EM_D30V 86 /* Mitsubishi DV30V */ 214 | #define EM_V850 87 /* NEC v850 */ 215 | #define EM_M32R 88 /* Mitsubishi M32R */ 216 | #define EM_MN10300 89 /* Matsushita MN10200 */ 217 | #define EM_MN10200 90 /* Matsushita MN10200 */ 218 | #define EM_PJ 91 /* picoJava */ 219 | #define EM_NUM 92 /* number of machine types */ 220 | 221 | /* Version */ 222 | #define EV_NONE 0 /* Invalid */ 223 | #define EV_CURRENT 1 /* Current */ 224 | #define EV_NUM 2 /* number of versions */ 225 | 226 | /* Section Header */ 227 | typedef struct { 228 | Elf32_Word sh_name; /* name - index into section header 229 | string table section */ 230 | Elf32_Word sh_type; /* type */ 231 | Elf32_Word sh_flags; /* flags */ 232 | Elf32_Addr sh_addr; /* address */ 233 | Elf32_Off sh_offset; /* file offset */ 234 | Elf32_Word sh_size; /* section size */ 235 | Elf32_Word sh_link; /* section header table index link */ 236 | Elf32_Word sh_info; /* extra information */ 237 | Elf32_Word sh_addralign; /* address alignment */ 238 | Elf32_Word sh_entsize; /* section entry size */ 239 | } Elf32_Shdr; 240 | 241 | /* Special Section Indexes */ 242 | #define SHN_UNDEF 0 /* undefined */ 243 | #define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */ 244 | #define SHN_LOPROC 0xff00 /* reserved range for processor */ 245 | #define SHN_HIPROC 0xff1f /* specific section indexes */ 246 | #define SHN_LOOS 0xff20 /* reserved range for operating */ 247 | #define SHN_HIOS 0xff3f /* specific semantics */ 248 | #define SHN_ABS 0xfff1 /* absolute value */ 249 | #define SHN_COMMON 0xfff2 /* common symbol */ 250 | #define SHN_XINDEX 0xffff /* Index is an extra table */ 251 | #define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */ 252 | 253 | /* sh_type */ 254 | #define SHT_NULL 0 /* inactive */ 255 | #define SHT_PROGBITS 1 /* program defined information */ 256 | #define SHT_SYMTAB 2 /* symbol table section */ 257 | #define SHT_STRTAB 3 /* string table section */ 258 | #define SHT_RELA 4 /* relocation section with addends*/ 259 | #define SHT_HASH 5 /* symbol hash table section */ 260 | #define SHT_DYNAMIC 6 /* dynamic section */ 261 | #define SHT_NOTE 7 /* note section */ 262 | #define SHT_NOBITS 8 /* no space section */ 263 | #define SHT_REL 9 /* relation section without addends */ 264 | #define SHT_SHLIB 10 /* reserved - purpose unknown */ 265 | #define SHT_DYNSYM 11 /* dynamic symbol table section */ 266 | #define SHT_INIT_ARRAY 14 /* Array of constructors */ 267 | #define SHT_FINI_ARRAY 15 /* Array of destructors */ 268 | #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ 269 | #define SHT_GROUP 17 /* Section group */ 270 | #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ 271 | #define SHT_NUM 19 /* number of section types */ 272 | #define SHT_LOOS 0x60000000 /* Start OS-specific */ 273 | #define SHT_HIOS 0x6fffffff /* End OS-specific */ 274 | #define SHT_LOPROC 0x70000000 /* reserved range for processor */ 275 | #define SHT_HIPROC 0x7fffffff /* specific section header types */ 276 | #define SHT_LOUSER 0x80000000 /* reserved range for application */ 277 | #define SHT_HIUSER 0xffffffff /* specific indexes */ 278 | 279 | /* Section names */ 280 | #define ELF_BSS ".bss" /* uninitialized data */ 281 | #define ELF_COMMENT ".comment" /* version control information */ 282 | #define ELF_DATA ".data" /* initialized data */ 283 | #define ELF_DATA1 ".data1" /* initialized data */ 284 | #define ELF_DEBUG ".debug" /* debug */ 285 | #define ELF_DYNAMIC ".dynamic" /* dynamic linking information */ 286 | #define ELF_DYNSTR ".dynstr" /* dynamic string table */ 287 | #define ELF_DYNSYM ".dynsym" /* dynamic symbol table */ 288 | #define ELF_FINI ".fini" /* termination code */ 289 | #define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */ 290 | #define ELF_GOT ".got" /* global offset table */ 291 | #define ELF_HASH ".hash" /* symbol hash table */ 292 | #define ELF_INIT ".init" /* initialization code */ 293 | #define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */ 294 | #define ELF_INTERP ".interp" /* Pathname of program interpreter */ 295 | #define ELF_LINE ".line" /* Symbolic line numnber information */ 296 | #define ELF_NOTE ".note" /* Contains note section */ 297 | #define ELF_PLT ".plt" /* Procedure linkage table */ 298 | #define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */ 299 | #define ELF_REL_DATA ".rel.data" /* relocation data */ 300 | #define ELF_REL_FINI ".rel.fini" /* relocation termination code */ 301 | #define ELF_REL_INIT ".rel.init" /* relocation initialization code */ 302 | #define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */ 303 | #define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */ 304 | #define ELF_REL_TEXT ".rel.text" /* relocation code */ 305 | #define ELF_RODATA ".rodata" /* read-only data */ 306 | #define ELF_RODATA1 ".rodata1" /* read-only data */ 307 | #define ELF_SHSTRTAB ".shstrtab" /* section header string table */ 308 | #define ELF_STRTAB ".strtab" /* string table */ 309 | #define ELF_SYMTAB ".symtab" /* symbol table */ 310 | #define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */ 311 | #define ELF_TBSS ".tbss" /* thread local uninit data */ 312 | #define ELF_TDATA ".tdata" /* thread local init data */ 313 | #define ELF_TDATA1 ".tdata1" /* thread local init data */ 314 | #define ELF_TEXT ".text" /* code */ 315 | 316 | /* Section Attribute Flags - sh_flags */ 317 | #define SHF_WRITE 0x1 /* Writable */ 318 | #define SHF_ALLOC 0x2 /* occupies memory */ 319 | #define SHF_EXECINSTR 0x4 /* executable */ 320 | #define SHF_MERGE 0x10 /* Might be merged */ 321 | #define SHF_STRINGS 0x20 /* Contains NULL terminated strings */ 322 | #define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */ 323 | #define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/ 324 | #define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */ 325 | #define SHF_GROUP 0x200 /* Member of section group */ 326 | #define SHF_TLS 0x400 /* Thread local storage */ 327 | #define SHF_MASKOS 0x0ff00000 /* OS specific */ 328 | #define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */ 329 | /* specific section attributes */ 330 | 331 | /* Section Group Flags */ 332 | #define GRP_COMDAT 0x1 /* COMDAT group */ 333 | #define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */ 334 | #define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */ 335 | 336 | /* Symbol Table Entry */ 337 | typedef struct elf32_sym { 338 | Elf32_Word st_name; /* name - index into string table */ 339 | Elf32_Addr st_value; /* symbol value */ 340 | Elf32_Word st_size; /* symbol size */ 341 | unsigned char st_info; /* type and binding */ 342 | unsigned char st_other; /* 0 - no defined meaning */ 343 | Elf32_Half st_shndx; /* section header index */ 344 | } Elf32_Sym; 345 | 346 | /* Symbol table index */ 347 | #define STN_UNDEF 0 /* undefined */ 348 | 349 | /* Extract symbol info - st_info */ 350 | #define ELF32_ST_BIND(x) ((x) >> 4) 351 | #define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) 352 | #define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf)) 353 | #define ELF32_ST_VISIBILITY(x) ((x) & 0x3) 354 | 355 | /* Symbol Binding - ELF32_ST_BIND - st_info */ 356 | #define STB_LOCAL 0 /* Local symbol */ 357 | #define STB_GLOBAL 1 /* Global symbol */ 358 | #define STB_WEAK 2 /* like global - lower precedence */ 359 | #define STB_NUM 3 /* number of symbol bindings */ 360 | #define STB_LOOS 10 /* reserved range for operating */ 361 | #define STB_HIOS 12 /* system specific symbol bindings */ 362 | #define STB_LOPROC 13 /* reserved range for processor */ 363 | #define STB_HIPROC 15 /* specific symbol bindings */ 364 | 365 | /* Symbol type - ELF32_ST_TYPE - st_info */ 366 | #define STT_NOTYPE 0 /* not specified */ 367 | #define STT_OBJECT 1 /* data object */ 368 | #define STT_FUNC 2 /* function */ 369 | #define STT_SECTION 3 /* section */ 370 | #define STT_FILE 4 /* file */ 371 | #define STT_NUM 5 /* number of symbol types */ 372 | #define STT_TLS 6 /* Thread local storage symbol */ 373 | #define STT_LOOS 10 /* reserved range for operating */ 374 | #define STT_HIOS 12 /* system specific symbol types */ 375 | #define STT_LOPROC 13 /* reserved range for processor */ 376 | #define STT_HIPROC 15 /* specific symbol types */ 377 | 378 | /* Symbol visibility - ELF32_ST_VISIBILITY - st_other */ 379 | #define STV_DEFAULT 0 /* Normal visibility rules */ 380 | #define STV_INTERNAL 1 /* Processor specific hidden class */ 381 | #define STV_HIDDEN 2 /* Symbol unavailable in other mods */ 382 | #define STV_PROTECTED 3 /* Not preemptible, not exported */ 383 | 384 | 385 | /* Relocation entry with implicit addend */ 386 | typedef struct 387 | { 388 | Elf32_Addr r_offset; /* offset of relocation */ 389 | Elf32_Word r_info; /* symbol table index and type */ 390 | } Elf32_Rel; 391 | 392 | /* Relocation entry with explicit addend */ 393 | typedef struct 394 | { 395 | Elf32_Addr r_offset; /* offset of relocation */ 396 | Elf32_Word r_info; /* symbol table index and type */ 397 | Elf32_Sword r_addend; 398 | } Elf32_Rela; 399 | 400 | /* Extract relocation info - r_info */ 401 | #define ELF32_R_SYM(i) ((i) >> 8) 402 | #define ELF32_R_TYPE(i) ((unsigned char) (i)) 403 | #define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t)) 404 | 405 | /* Program Header */ 406 | typedef struct { 407 | Elf32_Word p_type; /* segment type */ 408 | Elf32_Off p_offset; /* segment offset */ 409 | Elf32_Addr p_vaddr; /* virtual address of segment */ 410 | Elf32_Addr p_paddr; /* physical address - ignored? */ 411 | Elf32_Word p_filesz; /* number of bytes in file for seg. */ 412 | Elf32_Word p_memsz; /* number of bytes in mem. for seg. */ 413 | Elf32_Word p_flags; /* flags */ 414 | Elf32_Word p_align; /* memory alignment */ 415 | } Elf32_Phdr; 416 | 417 | /* Segment types - p_type */ 418 | #define PT_NULL 0 /* unused */ 419 | #define PT_LOAD 1 /* loadable segment */ 420 | #define PT_DYNAMIC 2 /* dynamic linking section */ 421 | #define PT_INTERP 3 /* the RTLD */ 422 | #define PT_NOTE 4 /* auxiliary information */ 423 | #define PT_SHLIB 5 /* reserved - purpose undefined */ 424 | #define PT_PHDR 6 /* program header */ 425 | #define PT_TLS 7 /* Thread local storage template */ 426 | #define PT_NUM 8 /* Number of segment types */ 427 | #define PT_LOOS 0x60000000 /* reserved range for operating */ 428 | #define PT_HIOS 0x6fffffff /* system specific segment types */ 429 | #define PT_LOPROC 0x70000000 /* reserved range for processor */ 430 | #define PT_HIPROC 0x7fffffff /* specific segment types */ 431 | 432 | /* Segment flags - p_flags */ 433 | #define PF_X 0x1 /* Executable */ 434 | #define PF_W 0x2 /* Writable */ 435 | #define PF_R 0x4 /* Readable */ 436 | #define PF_MASKOS 0x0ff00000 /* OS specific segment flags */ 437 | #define PF_MASKPROC 0xf0000000 /* reserved bits for processor */ 438 | /* specific segment flags */ 439 | /* Dynamic structure */ 440 | typedef struct 441 | { 442 | Elf32_Sword d_tag; /* controls meaning of d_val */ 443 | union 444 | { 445 | Elf32_Word d_val; /* Multiple meanings - see d_tag */ 446 | Elf32_Addr d_ptr; /* program virtual address */ 447 | } d_un; 448 | } Elf32_Dyn; 449 | 450 | extern Elf32_Dyn _DYNAMIC[]; 451 | 452 | /* Dynamic Array Tags - d_tag */ 453 | #define DT_NULL 0 /* marks end of _DYNAMIC array */ 454 | #define DT_NEEDED 1 /* string table offset of needed lib */ 455 | #define DT_PLTRELSZ 2 /* size of relocation entries in PLT */ 456 | #define DT_PLTGOT 3 /* address PLT/GOT */ 457 | #define DT_HASH 4 /* address of symbol hash table */ 458 | #define DT_STRTAB 5 /* address of string table */ 459 | #define DT_SYMTAB 6 /* address of symbol table */ 460 | #define DT_RELA 7 /* address of relocation table */ 461 | #define DT_RELASZ 8 /* size of relocation table */ 462 | #define DT_RELAENT 9 /* size of relocation entry */ 463 | #define DT_STRSZ 10 /* size of string table */ 464 | #define DT_SYMENT 11 /* size of symbol table entry */ 465 | #define DT_INIT 12 /* address of initialization func. */ 466 | #define DT_FINI 13 /* address of termination function */ 467 | #define DT_SONAME 14 /* string table offset of shared obj */ 468 | #define DT_RPATH 15 /* string table offset of library 469 | search path */ 470 | #define DT_SYMBOLIC 16 /* start sym search in shared obj. */ 471 | #define DT_REL 17 /* address of rel. tbl. w addends */ 472 | #define DT_RELSZ 18 /* size of DT_REL relocation table */ 473 | #define DT_RELENT 19 /* size of DT_REL relocation entry */ 474 | #define DT_PLTREL 20 /* PLT referenced relocation entry */ 475 | #define DT_DEBUG 21 /* bugger */ 476 | #define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */ 477 | #define DT_JMPREL 23 /* add. of PLT's relocation entries */ 478 | #define DT_BIND_NOW 24 /* Process relocations of object */ 479 | #define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ 480 | #define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ 481 | #define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ 482 | #define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ 483 | #define DT_RUNPATH 29 /* Library search path */ 484 | #define DT_FLAGS 30 /* Flags for the object being loaded */ 485 | #define DT_ENCODING 32 /* Start of encoded range */ 486 | #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ 487 | #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ 488 | #define DT_NUM 34 /* Number used. */ 489 | #define DT_LOOS 0x60000000 /* reserved range for OS */ 490 | #define DT_HIOS 0x6fffffff /* specific dynamic array tags */ 491 | #define DT_LOPROC 0x70000000 /* reserved range for processor */ 492 | #define DT_HIPROC 0x7fffffff /* specific dynamic array tags */ 493 | 494 | /* Dynamic Tag Flags - d_un.d_val */ 495 | #define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */ 496 | #define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */ 497 | #define DF_TEXTREL 0x04 /* Object contains text relocations */ 498 | #define DF_BIND_NOW 0x08 /* No lazy binding for this object */ 499 | #define DF_STATIC_TLS 0x10 /* Static thread local storage */ 500 | 501 | /* Standard ELF hashing function */ 502 | unsigned long elf_hash(const unsigned char *name); 503 | 504 | #define ELF_TARG_VER 1 /* The ver for which this code is intended */ 505 | 506 | /* 507 | * XXX - PowerPC defines really don't belong in here, 508 | * but we'll put them in for simplicity. 509 | */ 510 | 511 | /* Values for Elf32/64_Ehdr.e_flags. */ 512 | #define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ 513 | 514 | /* Cygnus local bits below */ 515 | #define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ 516 | #define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib 517 | flag */ 518 | 519 | /* PowerPC relocations defined by the ABIs */ 520 | #define R_PPC_NONE 0 521 | #define R_PPC_ADDR32 1 /* 32bit absolute address */ 522 | #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ 523 | #define R_PPC_ADDR16 3 /* 16bit absolute address */ 524 | #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ 525 | #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ 526 | #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ 527 | #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ 528 | #define R_PPC_ADDR14_BRTAKEN 8 529 | #define R_PPC_ADDR14_BRNTAKEN 9 530 | #define R_PPC_REL24 10 /* PC relative 26 bit */ 531 | #define R_PPC_REL14 11 /* PC relative 16 bit */ 532 | #define R_PPC_REL14_BRTAKEN 12 533 | #define R_PPC_REL14_BRNTAKEN 13 534 | #define R_PPC_GOT16 14 535 | #define R_PPC_GOT16_LO 15 536 | #define R_PPC_GOT16_HI 16 537 | #define R_PPC_GOT16_HA 17 538 | #define R_PPC_PLTREL24 18 539 | #define R_PPC_COPY 19 540 | #define R_PPC_GLOB_DAT 20 541 | #define R_PPC_JMP_SLOT 21 542 | #define R_PPC_RELATIVE 22 543 | #define R_PPC_LOCAL24PC 23 544 | #define R_PPC_UADDR32 24 545 | #define R_PPC_UADDR16 25 546 | #define R_PPC_REL32 26 547 | #define R_PPC_PLT32 27 548 | #define R_PPC_PLTREL32 28 549 | #define R_PPC_PLT16_LO 29 550 | #define R_PPC_PLT16_HI 30 551 | #define R_PPC_PLT16_HA 31 552 | #define R_PPC_SDAREL16 32 553 | #define R_PPC_SECTOFF 33 554 | #define R_PPC_SECTOFF_LO 34 555 | #define R_PPC_SECTOFF_HI 35 556 | #define R_PPC_SECTOFF_HA 36 557 | /* Keep this the last entry. */ 558 | #define R_PPC_NUM 37 559 | 560 | /* The remaining relocs are from the Embedded ELF ABI, and are not 561 | in the SVR4 ELF ABI. */ 562 | #define R_PPC_EMB_NADDR32 101 563 | #define R_PPC_EMB_NADDR16 102 564 | #define R_PPC_EMB_NADDR16_LO 103 565 | #define R_PPC_EMB_NADDR16_HI 104 566 | #define R_PPC_EMB_NADDR16_HA 105 567 | #define R_PPC_EMB_SDAI16 106 568 | #define R_PPC_EMB_SDA2I16 107 569 | #define R_PPC_EMB_SDA2REL 108 570 | #define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ 571 | #define R_PPC_EMB_MRKREF 110 572 | #define R_PPC_EMB_RELSEC16 111 573 | #define R_PPC_EMB_RELST_LO 112 574 | #define R_PPC_EMB_RELST_HI 113 575 | #define R_PPC_EMB_RELST_HA 114 576 | #define R_PPC_EMB_BIT_FLD 115 577 | #define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ 578 | 579 | /* Diab tool relocations. */ 580 | #define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ 581 | #define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ 582 | #define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ 583 | #define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ 584 | #define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ 585 | #define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ 586 | 587 | /* This is a phony reloc to handle any old fashioned TOC16 references 588 | that may still be in object files. */ 589 | #define R_PPC_TOC16 255 590 | 591 | #endif /* _ELF_H */ 592 | -------------------------------------------------------------------------------- /sd_loader/src/entry.c: -------------------------------------------------------------------------------- 1 | #include "os_types.h" 2 | #include "elf_abi.h" 3 | #include "common.h" 4 | #include "os_defs.h" 5 | #include "fs_defs.h" 6 | #include "kernel_defs.h" 7 | #include "loader_defs.h" 8 | 9 | #define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__); 10 | #define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func) 11 | 12 | typedef struct _private_data_t { 13 | EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx, int size, int align); 14 | 15 | EXPORT_DECL(void, MEMFreeToDefaultHeap, void *ptr); 16 | 17 | EXPORT_DECL(uint64_t, OSGetTitleID); 18 | 19 | EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s); 20 | 21 | EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s); 22 | 23 | EXPORT_DECL(void, OSFatal, const char *msg); 24 | 25 | EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*); 26 | 27 | EXPORT_DECL(void, exit, int); 28 | 29 | EXPORT_DECL(int, FSInit, void); 30 | 31 | EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); 32 | 33 | EXPORT_DECL(int, FSDelClient, void *pClient); 34 | 35 | EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); 36 | 37 | EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); 38 | 39 | EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, const char *target, uint32_t bytes, int errHandling); 40 | 41 | EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); 42 | 43 | EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); 44 | 45 | EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); 46 | 47 | EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); 48 | 49 | EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); 50 | 51 | EXPORT_DECL(int, SYSRelaunchTitle, int argc, char **argv); 52 | 53 | } private_data_t; 54 | 55 | static void (*DCFlushRange)(void *addr, unsigned int size); 56 | static void (*DCInvalidateRange)(void *addr, unsigned int size); 57 | static void (*ICInvalidateRange)(void *addr, unsigned int size); 58 | static unsigned int hook_LiWaitOneChunk; 59 | static unsigned int addrphys_LiWaitOneChunk; 60 | 61 | extern void SC0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len); 62 | extern void my_PrepareTitle_hook(void); 63 | 64 | /* Write a 32-bit word with kernel permissions */ 65 | static void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { 66 | asm volatile ( 67 | "li 3,1\n" 68 | "li 4,0\n" 69 | "mr 5,%1\n" 70 | "li 6,0\n" 71 | "li 7,0\n" 72 | "lis 8,1\n" 73 | "mr 9,%0\n" 74 | "mr %1,1\n" 75 | "li 0,0x3500\n" 76 | "sc\n" 77 | "nop\n" 78 | "mr 1,%1\n" 79 | : 80 | : "r"(addr), "r"(value) 81 | : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", 82 | "11", "12" 83 | ); 84 | } 85 | 86 | static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len) { 87 | /* 88 | * Setup a DBAT access with cache inhibited to write through and read directly from memory 89 | */ 90 | unsigned int dbatu0, dbatl0, dbatu1, dbatl1; 91 | // save the original DBAT value 92 | asm volatile("mfdbatu %0, 0" : "=r" (dbatu0)); 93 | asm volatile("mfdbatl %0, 0" : "=r" (dbatl0)); 94 | asm volatile("mfdbatu %0, 1" : "=r" (dbatu1)); 95 | asm volatile("mfdbatl %0, 1" : "=r" (dbatl1)); 96 | 97 | unsigned int target_dbatu0 = 0; 98 | unsigned int target_dbatl0 = 0; 99 | unsigned int target_dbatu1 = 0; 100 | unsigned int target_dbatl1 = 0; 101 | 102 | unsigned int *dst_p = (unsigned int*)addr; 103 | unsigned int *src_p = (unsigned int*)src; 104 | 105 | // we only need DBAT modification for addresses out of our own DBAT range 106 | // as our own DBAT is available everywhere for user and supervisor 107 | // since our own DBAT is on DBAT5 position we don't collide here 108 | if(addr < 0x00800000 || addr >= 0x01000000) { 109 | target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F; 110 | target_dbatl0 = (addr & 0xFFF00000) | 0x32; 111 | asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); 112 | asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); 113 | dst_p = (unsigned int*)((addr & 0xFFFFFF) | 0xC0000000); 114 | } 115 | if(src < 0x00800000 || src >= 0x01000000) { 116 | target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F; 117 | target_dbatl1 = (src & 0xFFF00000) | 0x32; 118 | 119 | asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); 120 | asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); 121 | src_p = (unsigned int*)((src & 0xFFFFFF) | 0xB0000000); 122 | } 123 | 124 | asm volatile("eieio; isync"); 125 | 126 | unsigned int i; 127 | for(i = 0; i < len; i += 4) { 128 | // if we are on the edge to next chunk 129 | if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000))) { 130 | target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F; 131 | target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32; 132 | dst_p = (unsigned int*)(((addr + i) & 0xFFFFFF) | 0xC0000000); 133 | 134 | asm volatile("eieio; isync"); 135 | asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0)); 136 | asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0)); 137 | asm volatile("eieio; isync"); 138 | } 139 | if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000))) { 140 | target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F; 141 | target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32; 142 | src_p = (unsigned int*)(((src + i) & 0xFFFFFF) | 0xB0000000); 143 | 144 | asm volatile("eieio; isync"); 145 | asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1)); 146 | asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1)); 147 | asm volatile("eieio; isync"); 148 | } 149 | 150 | *dst_p = *src_p; 151 | 152 | ++dst_p; 153 | ++src_p; 154 | } 155 | 156 | /* 157 | * Restore original DBAT value 158 | */ 159 | asm volatile("eieio; isync"); 160 | asm volatile("mtdbatu 0, %0" : : "r" (dbatu0)); 161 | asm volatile("mtdbatl 0, %0" : : "r" (dbatl0)); 162 | asm volatile("mtdbatu 1, %0" : : "r" (dbatu1)); 163 | asm volatile("mtdbatl 1, %0" : : "r" (dbatl1)); 164 | asm volatile("eieio; isync"); 165 | } 166 | 167 | // This function is called every time after LiBounceOneChunk. 168 | // It waits for the asynchronous call of LiLoadAsync for the IOSU to fill data to the RPX/RPL address 169 | // and return the still remaining bytes to load. 170 | // We override it and replace the loaded date from LiLoadAsync with our data and our remaining bytes to load. 171 | static int LiWaitOneChunk(unsigned int * iRemainingBytes, const char *filename, int fileType) { 172 | unsigned int result; 173 | register int core_id; 174 | int remaining_bytes = 0; 175 | 176 | int sgFileOffset; 177 | int sgBufferNumber; 178 | int *sgBounceError; 179 | int *sgGotBytes; 180 | int *sgTotalBytes; 181 | int *sgIsLoadingBuffer; 182 | int *sgFinishedLoadingBuffer; 183 | 184 | // get the current core 185 | asm volatile("mfspr %0, 0x3EF" : "=r" (core_id)); 186 | 187 | // get the offset of per core global variable for dynload initialized (just a simple address + (core_id * 4)) 188 | unsigned int gDynloadInitialized = *(volatile unsigned int*)(OS_SPECIFICS->addr_gDynloadInitialized + (core_id << 2)); 189 | 190 | // Comment (Dimok): 191 | // time measurement at this position for logger -> we don't need it right now except maybe for debugging 192 | //unsigned long long systemTime1 = Loader_GetSystemTime(); 193 | 194 | if(OS_FIRMWARE == 550) { 195 | // pointer to global variables of the loader 196 | loader_globals_550_t *loader_globals = (loader_globals_550_t*)(0xEFE19E80); 197 | 198 | sgBufferNumber = loader_globals->sgBufferNumber; 199 | sgFileOffset = loader_globals->sgFileOffset; 200 | sgBounceError = &loader_globals->sgBounceError; 201 | sgGotBytes = &loader_globals->sgGotBytes; 202 | sgTotalBytes = &loader_globals->sgTotalBytes; 203 | sgFinishedLoadingBuffer = &loader_globals->sgFinishedLoadingBuffer; 204 | // not available on 5.5.x 205 | sgIsLoadingBuffer = NULL; 206 | } else { 207 | // pointer to global variables of the loader 208 | loader_globals_t *loader_globals = (loader_globals_t*)(OS_SPECIFICS->addr_sgIsLoadingBuffer); 209 | 210 | sgBufferNumber = loader_globals->sgBufferNumber; 211 | sgFileOffset = loader_globals->sgFileOffset; 212 | sgBounceError = &loader_globals->sgBounceError; 213 | sgGotBytes = &loader_globals->sgGotBytes; 214 | sgIsLoadingBuffer = &loader_globals->sgIsLoadingBuffer; 215 | // not available on < 5.5.x 216 | sgTotalBytes = NULL; 217 | sgFinishedLoadingBuffer = NULL; 218 | } 219 | 220 | // the data loading was started in LiBounceOneChunk() and here it waits for IOSU to finish copy the data 221 | if(gDynloadInitialized != 0) { 222 | result = OS_SPECIFICS->LiWaitIopCompleteWithInterrupts(0x2160EC0, &remaining_bytes); 223 | 224 | } else { 225 | result = OS_SPECIFICS->LiWaitIopComplete(0x2160EC0, &remaining_bytes); 226 | } 227 | 228 | // Comment (Dimok): 229 | // time measurement at this position for logger -> we don't need it right now except maybe for debugging 230 | //unsigned long long systemTime2 = Loader_GetSystemTime(); 231 | 232 | //------------------------------------------------------------------------------------------------------------------ 233 | // Start of our function intrusion: 234 | // After IOSU is done writing the data into the 0xF6000000/0xF6400000 address, 235 | // we overwrite it with our data before setting the global flag for IsLoadingBuffer to 0 236 | // Do this only if we are in the game that was launched by our method 237 | s_mem_area *mem_area = MEM_AREA_TABLE; 238 | if((ELF_DATA_ADDR == mem_area->address) && (fileType == 0)) { 239 | unsigned int load_address = (sgBufferNumber == 1) ? 0xF6000000 : (0xF6000000 + 0x00400000); 240 | unsigned int load_addressPhys = (sgBufferNumber == 1) ? 0x1B000000 : (0x1B000000 + 0x00400000); // virtual 0xF6000000 and 0xF6400000 241 | 242 | remaining_bytes = ELF_DATA_SIZE - sgFileOffset; 243 | if (remaining_bytes > 0x400000) 244 | // truncate size 245 | remaining_bytes = 0x400000; 246 | 247 | DCFlushRange((void*)load_address, remaining_bytes); 248 | 249 | u32 rpxBlockPos = 0; 250 | u32 done = 0; 251 | u32 mapOffset = 0; 252 | 253 | while((done < (u32)sgFileOffset) && mem_area) { 254 | if((done + mem_area->size) > (u32)sgFileOffset) { 255 | mapOffset = sgFileOffset - done; 256 | done = sgFileOffset; 257 | } else { 258 | done += mem_area->size; 259 | mem_area = mem_area->next; 260 | } 261 | } 262 | 263 | while((done < ELF_DATA_SIZE) && (rpxBlockPos < 0x400000) && mem_area) { 264 | u32 address = mem_area->address + mapOffset; 265 | u32 blockSize = ELF_DATA_SIZE - done; 266 | 267 | if(blockSize > (0x400000 - rpxBlockPos)) { 268 | blockSize = 0x400000 - rpxBlockPos; 269 | } 270 | if((mapOffset + blockSize) >= mem_area->size) { 271 | blockSize = mem_area->size - mapOffset; 272 | //! this value is incremented later by blockSize, so set it to -blockSize for it to be 0 after copy 273 | //! it makes smaller code then if(mapOffset == mem_area->size) after copy 274 | mapOffset = -blockSize; 275 | mem_area = mem_area->next; 276 | } 277 | 278 | SC0x25_KernelCopyData(load_addressPhys + rpxBlockPos, address, blockSize); 279 | done += blockSize; 280 | rpxBlockPos += blockSize; 281 | mapOffset += blockSize; 282 | } 283 | 284 | DCInvalidateRange((void*)load_address, remaining_bytes); 285 | 286 | if((u32)(sgFileOffset + remaining_bytes) == ELF_DATA_SIZE) { 287 | ELF_DATA_ADDR = 0xDEADC0DE; 288 | ELF_DATA_SIZE = 0; 289 | MAIN_ENTRY_ADDR = 0xC001C0DE; 290 | } 291 | // set result to 0 -> "everything OK" 292 | result = 0; 293 | } 294 | 295 | // end of our little intrusion into this function 296 | //------------------------------------------------------------------------------------------------------------------ 297 | 298 | // set the result to the global bounce error variable 299 | if(sgBounceError) { 300 | *sgBounceError = result; 301 | } 302 | 303 | // disable global flag that buffer is still loaded by IOSU 304 | if(sgFinishedLoadingBuffer) { 305 | unsigned int zeroBitCount = 0; 306 | asm volatile("cntlzw %0, %0" : "=r" (zeroBitCount) : "r"(*sgFinishedLoadingBuffer)); 307 | *sgFinishedLoadingBuffer = zeroBitCount >> 5; 308 | } else if(sgIsLoadingBuffer) { 309 | *sgIsLoadingBuffer = 0; 310 | } 311 | 312 | // check result for errors 313 | if(result == 0) { 314 | // the remaining size is set globally and in stack variable only 315 | // if a pointer was passed to this function 316 | if(iRemainingBytes) { 317 | if(sgGotBytes) { 318 | *sgGotBytes = remaining_bytes; 319 | } 320 | 321 | *iRemainingBytes = remaining_bytes; 322 | 323 | // on 5.5.x a new variable for total loaded bytes was added 324 | if(sgTotalBytes) { 325 | *sgTotalBytes += remaining_bytes; 326 | } 327 | } 328 | // Comment (Dimok): 329 | // calculate time difference and print it on logging how long the wait for asynchronous data load took 330 | // something like (systemTime2 - systemTime1) * constant / bus speed, did not look deeper into it as we don't need that crap 331 | } else { 332 | // Comment (Dimok): 333 | // a lot of error handling here. depending on error code sometimes calls Loader_Panic() -> we don't make errors so we can skip that part ;-P 334 | } 335 | return result; 336 | } 337 | 338 | void my_PrepareTitle(CosAppXmlInfo *xmlKernelInfo) { 339 | if(ELF_DATA_ADDR == MEM_AREA_TABLE->address) { 340 | xmlKernelInfo->max_size = RPX_MAX_SIZE; 341 | xmlKernelInfo->max_codesize = RPX_MAX_CODE_SIZE; 342 | //! setup our hook to LiWaitOneChunk for RPX loading 343 | hook_LiWaitOneChunk = ((u32)LiWaitOneChunk) | 0x48000002; 344 | KernelCopyData(addrphys_LiWaitOneChunk, (u32) &hook_LiWaitOneChunk, 4); 345 | asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31)); 346 | } else if((MAIN_ENTRY_ADDR == 0xC001C0DE) && (*(u32*)xmlKernelInfo->rpx_name == 0x66666c5f)) { // ffl_ 347 | //! restore original LiWaitOneChunk instruction as our RPX is done 348 | MAIN_ENTRY_ADDR = 0xDEADC0DE; 349 | KernelCopyData(addrphys_LiWaitOneChunk, (u32)&OS_SPECIFICS->orig_LiWaitOneChunkInstr, 4); 350 | asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31)); 351 | } 352 | } 353 | 354 | static int LoadFileToMem(private_data_t *private_data, const char *filepath, unsigned char **fileOut, unsigned int * sizeOut) { 355 | int iFd = -1; 356 | void *pClient = private_data->MEMAllocFromDefaultHeapEx(FS_CLIENT_SIZE, 4); 357 | if(!pClient) 358 | return 0; 359 | 360 | void *pCmd = private_data->MEMAllocFromDefaultHeapEx(FS_CMD_BLOCK_SIZE, 4); 361 | if(!pCmd) { 362 | private_data->MEMFreeToDefaultHeap(pClient); 363 | return 0; 364 | } 365 | 366 | int success = 0; 367 | private_data->FSInit(); 368 | private_data->FSInitCmdBlock(pCmd); 369 | private_data->FSAddClientEx(pClient, 0, -1); 370 | 371 | do { 372 | char tempPath[FS_MOUNT_SOURCE_SIZE]; 373 | char mountPath[FS_MAX_MOUNTPATH_SIZE]; 374 | 375 | int status = private_data->FSGetMountSource(pClient, pCmd, 0, tempPath, -1); 376 | if (status != 0) { 377 | private_data->OSFatal("-13"); 378 | } 379 | status = private_data->FSMount(pClient, pCmd, tempPath, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); 380 | if(status != 0) { 381 | private_data->OSFatal("-12"); 382 | } 383 | 384 | status = private_data->FSOpenFile(pClient, pCmd, filepath, "r", &iFd, -1); 385 | if(status != 0) { 386 | private_data->OSFatal("-11"); 387 | } 388 | 389 | FSStat stat; 390 | stat.size = 0; 391 | 392 | void *pBuffer = NULL; 393 | 394 | private_data->FSGetStatFile(pClient, pCmd, iFd, &stat, -1); 395 | 396 | if (stat.size > 0) { 397 | pBuffer = private_data->MEMAllocFromDefaultHeapEx((stat.size + 0x3F) & ~0x3F, 0x40); 398 | } else { 399 | private_data->OSFatal("-10"); 400 | } 401 | 402 | unsigned int done = 0; 403 | 404 | while(done < stat.size) { 405 | int readBytes = private_data->FSReadFile(pClient, pCmd, pBuffer + done, 1, stat.size - done, iFd, 0, -1); 406 | if(readBytes <= 0) { 407 | break; 408 | } 409 | done += readBytes; 410 | } 411 | 412 | if(done != stat.size) { 413 | private_data->MEMFreeToDefaultHeap(pBuffer); 414 | } else { 415 | *fileOut = (unsigned char*)pBuffer; 416 | *sizeOut = stat.size; 417 | success = 1; 418 | } 419 | 420 | private_data->FSCloseFile(pClient, pCmd, iFd, -1); 421 | private_data->FSUnmount(pClient, pCmd, mountPath, -1); 422 | } while(0); 423 | 424 | private_data->FSDelClient(pClient); 425 | private_data->MEMFreeToDefaultHeap(pClient); 426 | private_data->MEMFreeToDefaultHeap(pCmd); 427 | return success; 428 | } 429 | 430 | static void setup_patches(private_data_t *private_data) { 431 | //! setup necessary syscalls and hooks for HBL 432 | kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl1 + (0x25 * 4)), (unsigned int)KernelCopyData); 433 | kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl2 + (0x25 * 4)), (unsigned int)KernelCopyData); 434 | kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl3 + (0x25 * 4)), (unsigned int)KernelCopyData); 435 | kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl4 + (0x25 * 4)), (unsigned int)KernelCopyData); 436 | kern_write((void*)(OS_SPECIFICS->addr_KernSyscallTbl5 + (0x25 * 4)), (unsigned int)KernelCopyData); 437 | 438 | //! store physical address for later use 439 | addrphys_LiWaitOneChunk = private_data->OSEffectiveToPhysical((void*)OS_SPECIFICS->addr_LiWaitOneChunk); 440 | 441 | u32 addr_my_PrepareTitle_hook = ((u32)my_PrepareTitle_hook) | 0x48000003; 442 | DCFlushRange(&addr_my_PrepareTitle_hook, 4); 443 | 444 | //! create our copy syscall 445 | SC0x25_KernelCopyData(OS_SPECIFICS->addr_PrepareTitle_hook, private_data->OSEffectiveToPhysical(&addr_my_PrepareTitle_hook), 4); 446 | 447 | } 448 | 449 | static unsigned int load_elf_image (private_data_t *private_data, unsigned char *elfstart) { 450 | Elf32_Ehdr *ehdr; 451 | Elf32_Phdr *phdrs; 452 | unsigned char *image; 453 | int i; 454 | 455 | ehdr = (Elf32_Ehdr *) elfstart; 456 | 457 | if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0) 458 | return 0; 459 | 460 | if(ehdr->e_phentsize != sizeof(Elf32_Phdr)) 461 | return 0; 462 | 463 | phdrs = (Elf32_Phdr*)(elfstart + ehdr->e_phoff); 464 | 465 | for(i = 0; i < ehdr->e_phnum; i++) { 466 | if(phdrs[i].p_type != PT_LOAD) 467 | continue; 468 | 469 | if(phdrs[i].p_filesz > phdrs[i].p_memsz) 470 | continue; 471 | 472 | if(!phdrs[i].p_filesz) 473 | continue; 474 | 475 | unsigned int p_paddr = phdrs[i].p_paddr; 476 | image = (unsigned char *) (elfstart + phdrs[i].p_offset); 477 | 478 | private_data->memcpy ((void *) p_paddr, image, phdrs[i].p_filesz); 479 | DCFlushRange((void*)p_paddr, phdrs[i].p_filesz); 480 | 481 | if(phdrs[i].p_flags & PF_X) 482 | ICInvalidateRange ((void *) p_paddr, phdrs[i].p_memsz); 483 | } 484 | 485 | //! clear BSS 486 | Elf32_Shdr *shdr = (Elf32_Shdr *) (elfstart + ehdr->e_shoff); 487 | for(i = 0; i < ehdr->e_shnum; i++) { 488 | const char *section_name = ((const char*)elfstart) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; 489 | if(section_name[0] == '.' && section_name[1] == 'b' && section_name[2] == 's' && section_name[3] == 's') { 490 | private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size); 491 | DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size); 492 | } else if(section_name[0] == '.' && section_name[1] == 's' && section_name[2] == 'b' && section_name[3] == 's' && section_name[4] == 's') { 493 | private_data->memset((void*)shdr[i].sh_addr, 0, shdr[i].sh_size); 494 | DCFlushRange((void*)shdr[i].sh_addr, shdr[i].sh_size); 495 | } 496 | } 497 | 498 | return ehdr->e_entry; 499 | } 500 | 501 | static void loadFunctionPointers(private_data_t * private_data) { 502 | unsigned int coreinit_handle; 503 | 504 | EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle); 505 | EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address); 506 | 507 | OSDynLoad_Acquire = (int (*)(const char*, u32 *))OS_SPECIFICS->addr_OSDynLoad_Acquire; 508 | OSDynLoad_FindExport = (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport; 509 | 510 | OSDynLoad_Acquire("coreinit", &coreinit_handle); 511 | 512 | unsigned int *functionPtr = 0; 513 | 514 | OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr); 515 | private_data->MEMAllocFromDefaultHeapEx = (void *(*)(int, int)) *functionPtr; 516 | OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr); 517 | private_data->MEMFreeToDefaultHeap = (void (*)(void *)) *functionPtr; 518 | 519 | OS_FIND_EXPORT(coreinit_handle, "OSGetTitleID", private_data->OSGetTitleID); 520 | OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy); 521 | OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset); 522 | OS_FIND_EXPORT(coreinit_handle, "OSFatal", private_data->OSFatal); 523 | OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", DCFlushRange); 524 | OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", DCInvalidateRange); 525 | OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", ICInvalidateRange); 526 | OS_FIND_EXPORT(coreinit_handle, "OSEffectiveToPhysical", private_data->OSEffectiveToPhysical); 527 | OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit); 528 | 529 | OS_FIND_EXPORT(coreinit_handle, "FSInit", private_data->FSInit); 530 | OS_FIND_EXPORT(coreinit_handle, "FSAddClientEx", private_data->FSAddClientEx); 531 | OS_FIND_EXPORT(coreinit_handle, "FSDelClient", private_data->FSDelClient); 532 | OS_FIND_EXPORT(coreinit_handle, "FSInitCmdBlock", private_data->FSInitCmdBlock); 533 | OS_FIND_EXPORT(coreinit_handle, "FSGetMountSource", private_data->FSGetMountSource); 534 | OS_FIND_EXPORT(coreinit_handle, "FSMount", private_data->FSMount); 535 | OS_FIND_EXPORT(coreinit_handle, "FSUnmount", private_data->FSUnmount); 536 | OS_FIND_EXPORT(coreinit_handle, "FSOpenFile", private_data->FSOpenFile); 537 | OS_FIND_EXPORT(coreinit_handle, "FSGetStatFile", private_data->FSGetStatFile); 538 | OS_FIND_EXPORT(coreinit_handle, "FSReadFile", private_data->FSReadFile); 539 | OS_FIND_EXPORT(coreinit_handle, "FSCloseFile", private_data->FSCloseFile); 540 | 541 | unsigned int sysapp_handle; 542 | OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); 543 | OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle); 544 | } 545 | 546 | int _start(int argc, char **argv) { 547 | private_data_t private_data; 548 | 549 | if(MAIN_ENTRY_ADDR != 0xC001C0DE) { 550 | loadFunctionPointers(&private_data); 551 | 552 | while (1) { 553 | if (ELF_DATA_ADDR != 0xDEADC0DE && ELF_DATA_SIZE > 0) { 554 | //! copy data to safe area before processing it 555 | unsigned char *pElfBuffer = (unsigned char *) private_data.MEMAllocFromDefaultHeapEx(ELF_DATA_SIZE, 4); 556 | if (pElfBuffer) { 557 | private_data.memcpy(pElfBuffer, (unsigned char *) ELF_DATA_ADDR, ELF_DATA_SIZE); 558 | MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); 559 | private_data.MEMFreeToDefaultHeap(pElfBuffer); 560 | 561 | } 562 | ELF_DATA_ADDR = 0xDEADC0DE; 563 | ELF_DATA_SIZE = 0; 564 | } 565 | 566 | if (MAIN_ENTRY_ADDR == 0xDEADC0DE || MAIN_ENTRY_ADDR == 0) { 567 | //! setup necessary syscalls and hooks for HBL before launching it 568 | setup_patches(&private_data); 569 | 570 | if (HBL_CHANNEL) { 571 | break; 572 | } else { 573 | unsigned char *pElfBuffer = NULL; 574 | unsigned int uiElfSize = 0; 575 | if (private_data.OSGetTitleID() == 0x000500101004A200L || // mii maker eur 576 | private_data.OSGetTitleID() == 0x000500101004A100L || // mii maker usa 577 | private_data.OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn 578 | 579 | LoadFileToMem(&private_data, CAFE_OS_SD_PATH WIIU_PATH "/apps/homebrew_launcher/homebrew_launcher.elf", &pElfBuffer, &uiElfSize); 580 | }else{ 581 | break; 582 | } 583 | 584 | if (!pElfBuffer) { 585 | private_data.OSFatal("Failed to load homebrew_launcher.elf"); 586 | } else { 587 | MAIN_ENTRY_ADDR = load_elf_image(&private_data, pElfBuffer); 588 | if (MAIN_ENTRY_ADDR == 0) { 589 | private_data.OSFatal("Failed to load homebrew_launcher.elf"); 590 | } else { 591 | private_data.MEMFreeToDefaultHeap(pElfBuffer); 592 | } 593 | } 594 | } 595 | } else { 596 | int returnVal = ((int (*)(int, char **)) MAIN_ENTRY_ADDR)(argc, argv); 597 | //! exit to miimaker and restart application on re-enter of another application 598 | if (returnVal == (int) EXIT_RELAUNCH_ON_LOAD) { 599 | break; 600 | } 601 | //! exit to homebrew launcher in all other cases 602 | else { 603 | MAIN_ENTRY_ADDR = 0xDEADC0DE; 604 | private_data.SYSRelaunchTitle(0, 0); 605 | private_data.exit(0); 606 | break; 607 | } 608 | } 609 | } 610 | } 611 | 612 | int ret = ( (int (*)(int, char **))(*(unsigned int*)OS_SPECIFICS->addr_OSTitle_main_entry) )(argc, argv); 613 | 614 | //! if an application returns and was an RPX launch then launch HBL again 615 | if(MAIN_ENTRY_ADDR == 0xC001C0DE) { 616 | private_data.SYSRelaunchTitle(0, 0); 617 | private_data.exit(0); 618 | } 619 | return ret; 620 | } 621 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------