Use <string.h> & <3ds/exheader.h>, fix some bugs, etc.

also fix all warnings and use -Werror
This commit is contained in:
TuxSH 2018-05-24 00:55:38 +02:00
parent e6b7dc1dc5
commit d28e961adc
85 changed files with 276 additions and 643 deletions

View File

@ -28,8 +28,8 @@ INCLUDES := include include/svc
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
-Wno-main -fno-builtin $(ARCH) $(DEFINES) -Wno-main -fno-builtin $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -58,7 +58,7 @@ start:
mov r1, #0 mov r1, #0
ldr r2, =__bss_end__ ldr r2, =__bss_end__
sub r2, r0 sub r2, r0
bl memset32 bl memset
@ Call the init array @ Call the init array
bl __libc_init_array bl __libc_init_array

View File

@ -54,9 +54,9 @@ INCLUDES := include
ARCH := -marm -march=armv5te -mtune=arm946e-s ARCH := -marm -march=armv5te -mtune=arm946e-s
DEFINES := -DARM9 -D_3DS DEFINES := -DARM9 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
-Wno-main -fno-builtin $(ARCH) $(DEFINES) -Wno-main $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -30,21 +30,21 @@
#pragma once #pragma once
typedef struct __attribute__((packed)) typedef struct
{ {
u32 address; u32 address;
u32 phyRegionSize; u32 phyRegionSize;
u32 size; u32 size;
} CodeSetInfo; } CodeSetInfo;
typedef struct __attribute__((packed)) typedef struct
{ {
u32 saveDataSize[2]; u32 saveDataSize[2];
u32 jumpID[2]; u32 jumpID[2];
u8 reserved[0x30]; u8 reserved[0x30];
} SystemInfo; } SystemInfo;
typedef struct __attribute__((packed)) typedef struct
{ {
char appTitle[8]; char appTitle[8];
u8 reserved1[5]; u8 reserved1[5];
@ -60,7 +60,7 @@ typedef struct __attribute__((packed))
SystemInfo systemInfo; SystemInfo systemInfo;
} SystemControlInfo; } SystemControlInfo;
typedef struct __attribute__((packed)) typedef struct
{ {
SystemControlInfo systemControlInfo; SystemControlInfo systemControlInfo;
u8 aci[0x200]; u8 aci[0x200];
@ -69,7 +69,7 @@ typedef struct __attribute__((packed))
u8 aciLim[0x200]; u8 aciLim[0x200];
} ExHeader; } ExHeader;
typedef struct __attribute__((packed)) typedef struct
{ {
u8 sig[0x100]; //RSA-2048 signature of the NCCH header, using SHA-256 u8 sig[0x100]; //RSA-2048 signature of the NCCH header, using SHA-256
char magic[4]; //NCCH char magic[4]; //NCCH
@ -102,13 +102,13 @@ typedef struct __attribute__((packed))
u8 romFsHash[0x20]; //RomFS superblock SHA-256 hash u8 romFsHash[0x20]; //RomFS superblock SHA-256 hash
} Ncch; } Ncch;
typedef struct __attribute__((packed)) typedef struct
{ {
Ncch ncch; Ncch ncch;
ExHeader exHeader; ExHeader exHeader;
} Cxi; } Cxi;
typedef struct __attribute__((packed)) typedef struct
{ {
char sigIssuer[0x40]; char sigIssuer[0x40];
u8 eccPubKey[0x3C]; u8 eccPubKey[0x3C];
@ -134,7 +134,7 @@ typedef struct __attribute__((packed))
u8 contentIndex[0xAC]; u8 contentIndex[0xAC];
} Ticket; } Ticket;
typedef struct __attribute__((packed)) typedef struct
{ {
u32 offset; u32 offset;
u8 *address; u8 *address;
@ -143,7 +143,7 @@ typedef struct __attribute__((packed))
u8 hash[0x20]; u8 hash[0x20];
} FirmSection; } FirmSection;
typedef struct __attribute__((packed)) typedef struct
{ {
char magic[4]; char magic[4];
u32 reserved1; u32 reserved1;
@ -153,7 +153,7 @@ typedef struct __attribute__((packed))
FirmSection section[4]; FirmSection section[4];
} Firm; } Firm;
typedef struct __attribute__((packed)) typedef struct
{ {
u8 keyX[0x10]; u8 keyX[0x10];
u8 keyY[0x10]; u8 keyY[0x10];

View File

@ -27,7 +27,6 @@
#include "config.h" #include "config.h"
#include "memory.h" #include "memory.h"
#include "fs.h" #include "fs.h"
#include "strings.h"
#include "utils.h" #include "utils.h"
#include "screen.h" #include "screen.h"
#include "draw.h" #include "draw.h"
@ -237,8 +236,8 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption), u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption),
singleOptionsAmount = sizeof(singleOptions) / sizeof(struct singleOption), singleOptionsAmount = sizeof(singleOptions) / sizeof(struct singleOption),
totalIndexes = multiOptionsAmount + singleOptionsAmount - 1, totalIndexes = multiOptionsAmount + singleOptionsAmount - 1,
selectedOption, selectedOption = 0,
singleSelected; singleSelected = 0;
bool isMultiOption = false; bool isMultiOption = false;
//Parse the existing options //Parse the existing options

View File

@ -34,7 +34,6 @@
#include "crypto.h" #include "crypto.h"
#include "memory.h" #include "memory.h"
#include "emunand.h" #include "emunand.h"
#include "strings.h"
#include "utils.h" #include "utils.h"
#include "alignedseqmemcpy.h" #include "alignedseqmemcpy.h"
#include "fatfs/sdmmc/sdmmc.h" #include "fatfs/sdmmc/sdmmc.h"
@ -581,6 +580,11 @@ void kernel9Loader(Arm9Bin *arm9Section)
u8 arm9BinSlot = k9lVersion == 0 ? 0x15 : 0x16; u8 arm9BinSlot = k9lVersion == 0 ? 0x15 : 0x16;
// Get size
u32 arm9SectionSize = 0;
for(u32 i = 0; i < 8; i++)
arm9SectionSize = (arm9Section->size[i] - '0') + 10*arm9SectionSize;
//Set keyX //Set keyX
__attribute__((aligned(4))) u8 keyX[AES_BLOCK_SIZE]; __attribute__((aligned(4))) u8 keyX[AES_BLOCK_SIZE];
aes_use_keyslot(0x11); aes_use_keyslot(0x11);
@ -598,7 +602,7 @@ void kernel9Loader(Arm9Bin *arm9Section)
//Decrypt ARM9 binary //Decrypt ARM9 binary
aes_use_keyslot(arm9BinSlot); aes_use_keyslot(arm9BinSlot);
aes(startOfArm9Bin, startOfArm9Bin, decAtoi(arm9Section->size, sizeof(arm9Section->size)) / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(startOfArm9Bin, startOfArm9Bin, arm9SectionSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary."); if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary.");
} }

View File

@ -30,7 +30,7 @@
*/ */
#include "draw.h" #include "draw.h"
#include "strings.h" #include "memory.h"
#include "screen.h" #include "screen.h"
#include "utils.h" #include "utils.h"
#include "fs.h" #include "fs.h"

View File

@ -26,7 +26,6 @@
#include "exceptions.h" #include "exceptions.h"
#include "fs.h" #include "fs.h"
#include "strings.h"
#include "memory.h" #include "memory.h"
#include "screen.h" #include "screen.h"
#include "draw.h" #include "draw.h"
@ -134,16 +133,16 @@ void detectAndProcessExceptionDumps(void)
for(u32 i = 0; i < 17; i += 2) for(u32 i = 0; i < 17; i += 2)
{ {
posY = drawFormattedString(true, 10, posY + SPACING_Y, COLOR_WHITE, "%-7s%08X", registerNames[i], regs[i]); posY = drawFormattedString(true, 10, posY + SPACING_Y, COLOR_WHITE, "%-7s%08lx", registerNames[i], regs[i]);
if(i != 16) if(i != 16)
posY = drawFormattedString(true, 10 + 22 * SPACING_X, posY, COLOR_WHITE, "%-7s%08X", registerNames[i + 1], regs[i + 1]); posY = drawFormattedString(true, 10 + 22 * SPACING_X, posY, COLOR_WHITE, "%-7s%08lx", registerNames[i + 1], regs[i + 1]);
else if(dumpHeader->processor == 11) else if(dumpHeader->processor == 11)
posY = drawFormattedString(true, 10 + 22 * SPACING_X, posY, COLOR_WHITE, "%-7s%08X", registerNames[i + 1], regs[20]); posY = drawFormattedString(true, 10 + 22 * SPACING_X, posY, COLOR_WHITE, "%-7s%08lx", registerNames[i + 1], regs[20]);
} }
if(dumpHeader->processor == 11 && dumpHeader->type == 3) if(dumpHeader->processor == 11 && dumpHeader->type == 3)
posY = drawFormattedString(true, 10, posY + SPACING_Y, COLOR_WHITE, "%-7s%08X Access type: %s", "FAR", regs[19], regs[17] & (1u << 11) ? "Write" : "Read"); posY = drawFormattedString(true, 10, posY + SPACING_Y, COLOR_WHITE, "%-7s%08lx Access type: %s", "FAR", regs[19], regs[17] & (1u << 11) ? "Write" : "Read");
posY += SPACING_Y; posY += SPACING_Y;
@ -155,7 +154,7 @@ void detectAndProcessExceptionDumps(void)
for(u32 line = 0; line < 19 && stackDump < additionalData; line++) for(u32 line = 0; line < 19 && stackDump < additionalData; line++)
{ {
posYBottom = drawFormattedString(false, 10, posYBottom + SPACING_Y, COLOR_WHITE, "%08X:", regs[13] + 8 * line); posYBottom = drawFormattedString(false, 10, posYBottom + SPACING_Y, COLOR_WHITE, "%08lx:", regs[13] + 8 * line);
for(u32 i = 0; i < 8 && stackDump < additionalData; i++, stackDump++) for(u32 i = 0; i < 8 && stackDump < additionalData; i++, stackDump++)
drawFormattedString(false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE, "%02X", *stackDump); drawFormattedString(false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE, "%02X", *stackDump);
@ -171,9 +170,9 @@ void detectAndProcessExceptionDumps(void)
drawString(true, 10, posY + SPACING_Y, COLOR_BLACK, choiceMessage[0]); drawString(true, 10, posY + SPACING_Y, COLOR_BLACK, choiceMessage[0]);
drawString(true, 10, posY + SPACING_Y + SPACING_Y , COLOR_BLACK, choiceMessage[1]); drawString(true, 10, posY + SPACING_Y + SPACING_Y , COLOR_BLACK, choiceMessage[1]);
char folderPath[12], char folderPath[32],
path[36], path[128],
fileName[24]; fileName[32];
sprintf(folderPath, "dumps/arm%u", dumpHeader->processor); sprintf(folderPath, "dumps/arm%u", dumpHeader->processor);
findDumpFile(folderPath, fileName); findDumpFile(folderPath, fileName);
@ -191,6 +190,6 @@ void detectAndProcessExceptionDumps(void)
waitInput(false); waitInput(false);
exit: exit:
memset32((void *)dumpHeader, 0, dumpHeader->totalSize); memset((void *)dumpHeader, 0, dumpHeader->totalSize);
mcuPowerOff(); mcuPowerOff();
} }

View File

@ -31,7 +31,6 @@
#include "exceptions.h" #include "exceptions.h"
#include "patches.h" #include "patches.h"
#include "memory.h" #include "memory.h"
#include "strings.h"
#include "cache.h" #include "cache.h"
#include "emunand.h" #include "emunand.h"
#include "crypto.h" #include "crypto.h"

View File

@ -59,7 +59,7 @@ This code is based on a file that contains the following:
//TuxSH's changes: add support for 64-bit numbers, remove floating-point code //TuxSH's changes: add support for 64-bit numbers, remove floating-point code
#include "strings.h" #include "memory.h"
#include "fmt.h" #include "fmt.h"
#define ZEROPAD (1<<0) //Pad with zero #define ZEROPAD (1<<0) //Pad with zero
@ -148,7 +148,7 @@ static char *processNumber(char *str, s64 num, bool isHex, s32 size, s32 precisi
return str; return str;
} }
u32 vsprintf(char *buf, const char *fmt, va_list args) int vsprintf(char *buf, const char *fmt, va_list args)
{ {
char *str; char *str;
@ -306,14 +306,14 @@ u32 vsprintf(char *buf, const char *fmt, va_list args)
} }
*str = 0; *str = 0;
return str - buf; return (int)(str - buf);
} }
u32 sprintf(char *buf, const char *fmt, ...) int sprintf(char *buf, const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
u32 res = vsprintf(buf, fmt, args); int res = vsprintf(buf, fmt, args);
va_end(args); va_end(args);
return res; return res;
} }

View File

@ -28,5 +28,5 @@
#include "memory.h" #include "memory.h"
#include <stdarg.h> #include <stdarg.h>
u32 vsprintf(char *buf, const char *fmt, va_list args); int vsprintf(char *buf, const char *fmt, va_list args);
u32 sprintf(char *buf, const char *fmt, ...); int sprintf(char *buf, const char *fmt, ...);

View File

@ -26,7 +26,6 @@
#include "fs.h" #include "fs.h"
#include "memory.h" #include "memory.h"
#include "strings.h"
#include "fmt.h" #include "fmt.h"
#include "crypto.h" #include "crypto.h"
#include "cache.h" #include "cache.h"
@ -87,7 +86,7 @@ u32 getFileSize(const char *path)
bool fileWrite(const void *buffer, const char *path, u32 size) bool fileWrite(const void *buffer, const char *path, u32 size)
{ {
FIL file; FIL file;
FRESULT result; FRESULT result = FR_OK;
switch(f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS)) switch(f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS))
{ {
@ -273,7 +272,10 @@ u32 firmRead(void *dest, u32 firmType)
//Not a cxi //Not a cxi
if(info.fname[9] != 'a' || strlen(info.fname) != 12) continue; if(info.fname[9] != 'a' || strlen(info.fname) != 12) continue;
u32 tempVersion = hexAtoi(info.altname, 8); u32 tempVersion = 0;
char *tmp = info.fname;
for(u32 i = 0; i < 8 && *tmp != 0; tmp++, i++)
tempVersion = (*tmp > '9' ? (*tmp >= 'A' ? *tmp - 'A' : *tmp - 'a') + 10 : *tmp - '0') + (tempVersion << 4);
//Found an older cxi //Found an older cxi
if(tempVersion < firmVersion) firmVersion = tempVersion; if(tempVersion < firmVersion) firmVersion = tempVersion;
@ -282,7 +284,7 @@ u32 firmRead(void *dest, u32 firmType)
if(f_closedir(&dir) != FR_OK || firmVersion == 0xFFFFFFFF) goto exit; if(f_closedir(&dir) != FR_OK || firmVersion == 0xFFFFFFFF) goto exit;
//Complete the string with the .app name //Complete the string with the .app name
sprintf(path, "%s/%08x.app", folderPath, firmVersion); sprintf(path, "%s/%08lx.app", folderPath, firmVersion);
if(fileRead(dest, path, 0x400000 + sizeof(Cxi) + 0x200) <= sizeof(Cxi) + 0x400) firmVersion = 0xFFFFFFFF; if(fileRead(dest, path, 0x400000 + sizeof(Cxi) + 0x200) <= sizeof(Cxi) + 0x400) firmVersion = 0xFFFFFFFF;
@ -299,7 +301,7 @@ void findDumpFile(const char *folderPath, char *fileName)
{ {
FILINFO info; FILINFO info;
sprintf(fileName, "crash_dump_%08u.dmp", n); sprintf(fileName, "crash_dump_%08lu.dmp", n);
result = f_findfirst(&dir, &info, folderPath, fileName); result = f_findfirst(&dir, &info, folderPath, fileName);
if(result != FR_OK || !info.fname[0]) break; if(result != FR_OK || !info.fname[0]) break;

View File

@ -31,7 +31,6 @@
#include "utils.h" #include "utils.h"
#include "exceptions.h" #include "exceptions.h"
#include "draw.h" #include "draw.h"
#include "strings.h"
#include "buttons.h" #include "buttons.h"
#include "pin.h" #include "pin.h"
#include "crypto.h" #include "crypto.h"
@ -336,7 +335,7 @@ boot:
u32 firmVersion = loadNintendoFirm(&firmType, firmSource, loadFromStorage, isSafeMode); u32 firmVersion = loadNintendoFirm(&firmType, firmSource, loadFromStorage, isSafeMode);
bool doUnitinfoPatch = CONFIG(PATCHUNITINFO); bool doUnitinfoPatch = CONFIG(PATCHUNITINFO);
u32 res; u32 res = 0;
switch(firmType) switch(firmType)
{ {
case NATIVE_FIRM: case NATIVE_FIRM:

View File

@ -26,50 +26,11 @@
/* /*
* Boyer-Moore Horspool algorithm adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 * Boyer-Moore Horspool algorithm adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
* memcpy, memset32 and memcmp adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c * memcpy, memset and memcmp adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
*/ */
#include "memory.h" #include "memory.h"
void memcpy(void *dest, const void *src, u32 size)
{
u8 *destc = (u8 *)dest;
const u8 *srcc = (const u8 *)src;
for(u32 i = 0; i < size; i++)
destc[i] = srcc[i];
}
void memset(void *dest, u32 filler, u32 size)
{
u8 *destc = (u8 *)dest;
for(u32 i = 0; i < size; i++)
destc[i] = (u8)filler;
}
void memset32(void *dest, u32 filler, u32 size)
{
u32 *dest32 = (u32 *)dest;
for(u32 i = 0; i < size / 4; i++)
dest32[i] = filler;
}
int memcmp(const void *buf1, const void *buf2, u32 size)
{
const u8 *buf1c = (const u8 *)buf1,
*buf2c = (const u8 *)buf2;
for(u32 i = 0; i < size; i++)
{
int cmp = buf1c[i] - buf2c[i];
if(cmp != 0) return cmp;
}
return 0;
}
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
{ {
const u8 *patternc = (const u8 *)pattern; const u8 *patternc = (const u8 *)pattern;

View File

@ -26,15 +26,11 @@
/* /*
* Boyer-Moore Horspool algorithm adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 * Boyer-Moore Horspool algorithm adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
* memcpy, memset32 and memcmp adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
*/ */
#pragma once #pragma once
#include <string.h>
#include "types.h" #include "types.h"
void memcpy(void *dest, const void *src, u32 size);
void memset(void *dest, u32 filler, u32 size) __attribute__((used));
void memset32(void *dest, u32 filler, u32 size);
int memcmp(const void *buf1, const void *buf2, u32 size);
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize); u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);

View File

@ -373,7 +373,7 @@ u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion)
off++; off++;
//Zero out the first TitleID in the list //Zero out the first TitleID in the list
memset32(off, 0, 8); memset(off, 0, 8);
return 0; return 0;
} }

View File

@ -113,7 +113,7 @@ _start:
mov r1, #0 mov r1, #0
ldr r2, =__bss_end__ ldr r2, =__bss_end__
sub r2, r0 sub r2, r0
bl memset32 bl memset
@ Set additional sections up @ Set additional sections up
ldr r0, =__itcm_start__ ldr r0, =__itcm_start__
@ -126,9 +126,9 @@ _start:
mov r1, #0 mov r1, #0
ldr r2, =__itcm_end__ ldr r2, =__itcm_end__
sub r2, r0 sub r2, r0
bl memset32 bl memset
@ bl __libc_init_array bl __libc_init_array
mov r0, r9 mov r0, r9
mov r1, r10 mov r1, r10

View File

@ -61,7 +61,7 @@ typedef volatile s64 vs64;
#define ISN3DS (CFG11_SOCINFO & 2) #define ISN3DS (CFG11_SOCINFO & 2)
#define ISDEVUNIT (CFG_UNITINFO != 0) #define ISDEVUNIT (CFG_UNITINFO != 0)
typedef struct __attribute__((packed)) typedef struct __attribute__((packed, aligned(4)))
{ {
char magic[4]; char magic[4];
u16 formatVersionMajor, formatVersionMinor; u16 formatVersionMajor, formatVersionMinor;
@ -71,7 +71,7 @@ typedef struct __attribute__((packed))
u32 rosalinaMenuCombo; u32 rosalinaMenuCombo;
} CfgData; } CfgData;
typedef struct __attribute__((packed)) typedef struct
{ {
char magic[4]; char magic[4];
u16 formatVersionMajor, formatVersionMinor; u16 formatVersionMajor, formatVersionMinor;
@ -80,7 +80,7 @@ typedef struct __attribute__((packed))
u8 hash[32]; u8 hash[32];
} PinData; } PinData;
typedef struct __attribute__((packed)) typedef struct
{ {
u32 magic[2]; u32 magic[2];
u16 versionMinor, versionMajor; u16 versionMinor, versionMajor;

View File

@ -35,7 +35,7 @@
#include "draw.h" #include "draw.h"
#include "cache.h" #include "cache.h"
#include "fmt.h" #include "fmt.h"
#include "strings.h" #include "memory.h"
#include "fs.h" #include "fs.h"
static void startChrono(void) static void startChrono(void)
@ -86,8 +86,8 @@ u32 waitInput(bool isMenu)
if(!key) if(!key)
{ {
if((!(I2C_readReg(I2C_DEV_MCU, 0xF) & 2) && shouldShellShutdown) || if((!(I2C_readReg(I2C_DEV_MCU, 0xF) & 2) && shouldShellShutdown) ||
(I2C_readReg(I2C_DEV_MCU, 0x10) & 1) == 1) mcuPowerOff(); (I2C_readReg(I2C_DEV_MCU, 0x10) & 1) == 1) mcuPowerOff();
oldKey = 0; oldKey = 0;
dPadDelay = 0; dPadDelay = 0;
continue; continue;

View File

@ -28,9 +28,9 @@ INCLUDES := include include/svc
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
-Wno-main -fno-builtin $(ARCH) $(DEFINES) -Wno-main $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -36,7 +36,7 @@ void undefinedInstructionHandler(void);
void prefetchAbortHandler(void); void prefetchAbortHandler(void);
void dataAbortHandler(void); void dataAbortHandler(void);
typedef struct __attribute__((packed)) typedef struct
{ {
u32 magic[2]; u32 magic[2];
u16 versionMinor, versionMajor; u16 versionMinor, versionMajor;

View File

@ -24,8 +24,8 @@
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "debug.h" #include "debug.h"
#include "memory.h"
#include "synchronization.h" #include "synchronization.h"
KRecursiveLock dbgParamsLock = { NULL }; KRecursiveLock dbgParamsLock = { NULL };

View File

@ -23,11 +23,11 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "fatalExceptionHandlers.h" #include "fatalExceptionHandlers.h"
#include "utils.h" #include "utils.h"
#include "kernel.h" #include "kernel.h"
#include "memory.h"
#include "globals.h" #include "globals.h"
#define REG_DUMP_SIZE 4 * 23 #define REG_DUMP_SIZE 4 * 23

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "ipc.h" #include "ipc.h"
#include "memory.h"
static SessionInfo sessionInfos[MAX_SESSION] = { {NULL} }; static SessionInfo sessionInfos[MAX_SESSION] = { {NULL} };
static u32 nbActiveSessions = 0; static u32 nbActiveSessions = 0;

View File

@ -23,7 +23,7 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "utils.h" #include "utils.h"
#include "globals.h" #include "globals.h"
#include "synchronization.h" #include "synchronization.h"
@ -31,7 +31,6 @@
#include "svc.h" #include "svc.h"
#include "svc/ConnectToPort.h" #include "svc/ConnectToPort.h"
#include "svcHandler.h" #include "svcHandler.h"
#include "memory.h"
struct KExtParameters struct KExtParameters
{ {
@ -53,7 +52,7 @@ void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
// Relocate ourselves, and clear BSS // Relocate ourselves, and clear BSS
// This is only OK because the jumps will be relative... // This is only OK because the jumps will be relative...
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__); memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
memset32((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__); memset((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
// Map the kernel ext to 0x40000000 // Map the kernel ext to 0x40000000
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA] // 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]

View File

@ -24,7 +24,7 @@
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include "memory.h" #include <string.h>
#include "synchronization.h" #include "synchronization.h"
#include "svc.h" #include "svc.h"
#include "svc/ControlMemory.h" #include "svc/ControlMemory.h"

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/ConnectToPort.h" #include "svc/ConnectToPort.h"
#include "memory.h"
#include "ipc.h" #include "ipc.h"
Result ConnectToPortHook(Handle *out, const char *name) Result ConnectToPortHook(Handle *out, const char *name)

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/ControlService.h" #include "svc/ControlService.h"
#include "memory.h"
#include "ipc.h" #include "ipc.h"
Result ControlService(ServiceOp op, u32 varg1, u32 varg2) Result ControlService(ServiceOp op, u32 varg1, u32 varg2)

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/CopyHandle.h" #include "svc/CopyHandle.h"
#include "memory.h"
Result CopyHandle(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle) Result CopyHandle(Handle *outHandle, Handle outProcessHandle, Handle inHandle, Handle inProcessHandle)
{ {

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/GetThreadInfo.h" #include "svc/GetThreadInfo.h"
#include "memory.h"
Result GetHandleInfoHook(s64 *out, Handle handle, u32 type) Result GetHandleInfoHook(s64 *out, Handle handle, u32 type)
{ {

View File

@ -25,7 +25,7 @@
*/ */
#include "svc/GetProcessInfo.h" #include "svc/GetProcessInfo.h"
#include "memory.h" #include <string.h>
Result GetProcessInfoHook(s64 *out, Handle processHandle, u32 type) Result GetProcessInfoHook(s64 *out, Handle processHandle, u32 type)
{ {

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/GetThreadInfo.h" #include "svc/GetThreadInfo.h"
#include "memory.h"
Result GetThreadInfoHook(s64 *out, Handle threadHandle, u32 type) Result GetThreadInfoHook(s64 *out, Handle threadHandle, u32 type)
{ {

View File

@ -23,12 +23,12 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/KernelSetState.h" #include "svc/KernelSetState.h"
#include "synchronization.h" #include "synchronization.h"
#include "ipc.h" #include "ipc.h"
#include "debug.h" #include "debug.h"
#include "memory.h"
#define MAX_DEBUG 3 #define MAX_DEBUG 3

View File

@ -23,9 +23,9 @@
* or requiring that modified versions of such material be marked in * or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version. * reasonable ways as different from the original version.
*/ */
#include <string.h>
#include "svc/SendSyncRequest.h" #include "svc/SendSyncRequest.h"
#include "memory.h"
#include "ipc.h" #include "ipc.h"
Result SendSyncRequestHook(Handle handle) Result SendSyncRequestHook(Handle handle)

View File

@ -25,7 +25,7 @@
*/ */
#include "svc/TranslateHandle.h" #include "svc/TranslateHandle.h"
#include "memory.h" #include <string.h>
Result TranslateHandle(u32 *outKAddr, char *outClassName, Handle handle) Result TranslateHandle(u32 *outKAddr, char *outClassName, Handle handle)
{ {

View File

@ -28,8 +28,8 @@ INCLUDES := include
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -1,99 +0,0 @@
#pragma once
#include <3ds/types.h>
typedef struct
{
u8 reserved[5];
u8 flag;
u8 remasterversion[2];
} PACKED exheader_systeminfoflags;
typedef struct
{
u32 address;
u32 nummaxpages;
u32 codesize;
} PACKED exheader_codesegmentinfo;
typedef struct
{
u8 name[8];
exheader_systeminfoflags flags;
exheader_codesegmentinfo text;
u8 stacksize[4];
exheader_codesegmentinfo ro;
u8 reserved[4];
exheader_codesegmentinfo data;
u32 bsssize;
} PACKED exheader_codesetinfo;
typedef struct
{
u64 programid[0x30];
} PACKED exheader_dependencylist;
typedef struct
{
u8 savedatasize[4];
u8 reserved[4];
u8 jumpid[8];
u8 reserved2[0x30];
} PACKED exheader_systeminfo;
typedef struct
{
u8 extsavedataid[8];
u8 systemsavedataid[8];
u8 reserved[8];
u8 accessinfo[7];
u8 otherattributes;
} PACKED exheader_storageinfo;
typedef struct
{
u64 programid;
u32 firm;
u8 flags[3];
u8 priority;
u16 resourcelimitdescriptor[0x10];
exheader_storageinfo storageinfo;
u64 serviceaccesscontrol[0x22];
u8 reserved[0xf];
u8 resourcelimitcategory;
} PACKED exheader_arm11systemlocalcaps;
typedef struct
{
u32 descriptors[28];
u8 reserved[0x10];
} PACKED exheader_arm11kernelcapabilities;
typedef struct
{
u8 descriptors[15];
u8 descversion;
} PACKED exheader_arm9accesscontrol;
typedef struct
{
// systemcontrol info {
// coreinfo {
exheader_codesetinfo codesetinfo;
exheader_dependencylist deplist;
// }
exheader_systeminfo systeminfo;
// }
// accesscontrolinfo {
exheader_arm11systemlocalcaps arm11systemlocalcaps;
exheader_arm11kernelcapabilities arm11kernelcaps;
exheader_arm9accesscontrol arm9accesscontrol;
// }
struct {
u8 signature[0x100];
u8 ncchpubkeymodulus[0x100];
exheader_arm11systemlocalcaps arm11systemlocalcaps;
exheader_arm11kernelcapabilities arm11kernelcaps;
exheader_arm9accesscontrol arm9accesscontrol;
} PACKED accessdesc;
} PACKED exheader_header;

View File

@ -14,16 +14,16 @@ static Result fsldrPatchPermissions(void)
u32 pid; u32 pid;
Result res; Result res;
FS_ProgramInfo info; FS_ProgramInfo info;
u32 storage[8] = {0}; ExHeader_Arm11StorageInfo storage = {0};
storage[6] = 0x680; // SDMC access and NAND access flag // SDMC access and NAND access flags
storage.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RO | FSACCESS_SDMC_RW;
info.programId = 0x0004013000001302LL; // loader PID info.programId = 0x0004013000001302LL; // loader PID
info.mediaType = MEDIATYPE_NAND; info.mediaType = MEDIATYPE_NAND;
res = svcGetProcessId(&pid, 0xFFFF8001);
if (R_SUCCEEDED(res)) if(R_SUCCEEDED(res = svcGetProcessId(&pid, CUR_PROCESS_HANDLE)))
{ res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storage);
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, (u8 *)storage);
}
return res; return res;
} }
@ -163,4 +163,4 @@ Result FSLDR_OpenDirectory(Handle* out, FS_Archive archive, FS_Path path)
if(out) *out = cmdbuf[3]; if(out) *out = cmdbuf[3];
return cmdbuf[1]; return cmdbuf[1];
} }

View File

@ -54,7 +54,7 @@ Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title)
return cmdbuf[1]; return cmdbuf[1];
} }
Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle) Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle)
{ {
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include "exheader.h" #include <3ds/exheader.h>
Result fsregInit(void); Result fsregInit(void);
void fsregExit(void); void fsregExit(void);
Result FSREG_CheckHostLoadId(u64 prog_handle); Result FSREG_CheckHostLoadId(u64 prog_handle);
Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title); Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title);
Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle); Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle);
Result FSREG_UnloadProgram(u64 prog_handle); Result FSREG_UnloadProgram(u64 prog_handle);
Result FSREG_Unregister(u32 pid); Result FSREG_Unregister(u32 pid);
Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo); Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo);

View File

@ -1,7 +1,6 @@
#include <3ds.h> #include <3ds.h>
#include "memory.h" #include "memory.h"
#include "patcher.h" #include "patcher.h"
#include "exheader.h"
#include "ifile.h" #include "ifile.h"
#include "fsldr.h" #include "fsldr.h"
#include "fsreg.h" #include "fsreg.h"
@ -30,7 +29,7 @@ typedef struct
static Handle g_handles[MAX_SESSIONS+2]; static Handle g_handles[MAX_SESSIONS+2];
static int g_active_handles; static int g_active_handles;
static u64 g_cached_prog_handle; static u64 g_cached_prog_handle;
static exheader_header g_exheader; static ExHeader g_exheader;
static char g_ret_buf[1024]; static char g_ret_buf[1024];
static inline void loadCFWInfo(void) static inline void loadCFWInfo(void)
@ -184,10 +183,12 @@ static Result load_code(u64 progid, prog_addrs_t *shared, u64 prog_handle, int i
} }
} }
u16 progver = g_exheader.codesetinfo.flags.remasterversion[0] | (g_exheader.codesetinfo.flags.remasterversion[1] << 8); ExHeader_CodeSetInfo *csi = &g_exheader.info.sci.codeset_info;
u16 progver = csi->flags.remaster_version;
// patch // patch
patchCode(progid, progver, (u8 *)shared->text_addr, shared->total_size << 12, g_exheader.codesetinfo.text.codesize, g_exheader.codesetinfo.ro.codesize, g_exheader.codesetinfo.data.codesize, g_exheader.codesetinfo.ro.address, g_exheader.codesetinfo.data.address); patchCode(progid, progver, (u8 *)shared->text_addr, shared->total_size << 12,
csi->text.size, csi->rodata.size, csi->data.size, csi->rodata.address, csi->data.address);
return 0; return 0;
} }
@ -207,7 +208,7 @@ static Result HBLDR_Init(Handle *session)
return res; return res;
} }
static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle) static Result loader_GetProgramInfo(ExHeader *exheader, u64 prog_handle)
{ {
Result res; Result res;
@ -236,13 +237,13 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
svcGetSystemInfo(&nbSection0Modules, 26, 0); svcGetSystemInfo(&nbSection0Modules, 26, 0);
// Force always having sdmc:/ and nand:/rw permission // Force always having sdmc:/ and nand:/rw permission
exheader->arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480; exheader->info.aci.local_caps.storage_info.fs_access_info |= FSACCESS_SDMC_RW | FSACCESS_NANDRW;
exheader->accessdesc.arm11systemlocalcaps.storageinfo.accessinfo[0] |= 0x480; exheader->access_descriptor.acli.local_caps.storage_info.fs_access_info |= FSACCESS_SDMC_RW | FSACCESS_NANDRW;;
// Tweak 3dsx placeholder title exheader // Tweak 3dsx placeholder title exheader
if (nbSection0Modules == 6) if (nbSection0Modules == 6)
{ {
if(exheader->arm11systemlocalcaps.programid == HBLDR_3DSX_TID) if(exheader->info.aci.local_caps.title_id == HBLDR_3DSX_TID)
{ {
Handle hbldr = 0; Handle hbldr = 0;
res = HBLDR_Init(&hbldr); res = HBLDR_Init(&hbldr);
@ -260,11 +261,11 @@ static Result loader_GetProgramInfo(exheader_header *exheader, u64 prog_handle)
} }
} }
u64 originalProgId = exheader->arm11systemlocalcaps.programid; u64 originalProgId = exheader->info.aci.local_caps.title_id;
if(CONFIG(PATCHGAMES) && loadTitleExheader(exheader->arm11systemlocalcaps.programid, exheader)) if(CONFIG(PATCHGAMES) && loadTitleExheader(exheader->info.aci.local_caps.title_id, exheader))
{ {
exheader->arm11systemlocalcaps.programid = originalProgId; exheader->info.aci.local_caps.title_id = originalProgId;
exheader->accessdesc.arm11systemlocalcaps.programid = originalProgId; exheader->access_descriptor.acli.local_caps.title_id = originalProgId;
} }
} }
} }
@ -287,7 +288,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
u64 progid; u64 progid;
// make sure the cached info corrosponds to the current prog_handle // make sure the cached info corrosponds to the current prog_handle
if (g_cached_prog_handle != prog_handle || g_exheader.arm11systemlocalcaps.programid == HBLDR_3DSX_TID) if (g_cached_prog_handle != prog_handle || g_exheader.info.aci.local_caps.title_id == HBLDR_3DSX_TID)
{ {
res = loader_GetProgramInfo(&g_exheader, prog_handle); res = loader_GetProgramInfo(&g_exheader, prog_handle);
g_cached_prog_handle = prog_handle; g_cached_prog_handle = prog_handle;
@ -302,7 +303,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
flags = 0; flags = 0;
for (count = 0; count < 28; count++) for (count = 0; count < 28; count++)
{ {
desc = g_exheader.arm11kernelcaps.descriptors[count]; desc = g_exheader.info.aci.kernel_caps.descriptors[count];
if (0x1FE == desc >> 23) if (0x1FE == desc >> 23)
{ {
flags = desc & 0xF00; flags = desc & 0xF00;
@ -314,7 +315,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
} }
// check for 3dsx process // check for 3dsx process
progid = g_exheader.arm11systemlocalcaps.programid; progid = g_exheader.info.aci.local_caps.title_id;
if (progid == HBLDR_3DSX_TID) if (progid == HBLDR_3DSX_TID)
{ {
Handle hbldr = 0; Handle hbldr = 0;
@ -326,11 +327,11 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
} }
u32* cmdbuf = getThreadCommandBuffer(); u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(1,6,0); cmdbuf[0] = IPC_MakeHeader(1,6,0);
cmdbuf[1] = g_exheader.codesetinfo.text.address; cmdbuf[1] = g_exheader.info.sci.codeset_info.text.address;
cmdbuf[2] = flags & 0xF00; cmdbuf[2] = flags & 0xF00;
cmdbuf[3] = progid; cmdbuf[3] = progid;
cmdbuf[4] = progid>>32; cmdbuf[4] = progid>>32;
memcpy(&cmdbuf[5], g_exheader.codesetinfo.name, 8); memcpy(&cmdbuf[5], g_exheader.info.sci.codeset_info.name, 8);
res = svcSendSyncRequest(hbldr); res = svcSendSyncRequest(hbldr);
svcCloseHandle(hbldr); svcCloseHandle(hbldr);
if (R_SUCCEEDED(res)) if (R_SUCCEEDED(res))
@ -343,19 +344,20 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
return res; return res;
} }
codeset = (Handle)cmdbuf[3]; codeset = (Handle)cmdbuf[3];
res = svcCreateProcess(process, codeset, g_exheader.arm11kernelcaps.descriptors, count); res = svcCreateProcess(process, codeset, g_exheader.info.aci.kernel_caps.descriptors, count);
svcCloseHandle(codeset); svcCloseHandle(codeset);
return res; return res;
} }
// allocate process memory // allocate process memory
vaddr.text_addr = g_exheader.codesetinfo.text.address; ExHeader_CodeSetInfo *csi = &g_exheader.info.sci.codeset_info;
vaddr.text_size = (g_exheader.codesetinfo.text.codesize + 4095) >> 12; vaddr.text_addr = csi->text.address;
vaddr.ro_addr = g_exheader.codesetinfo.ro.address; vaddr.text_size = (csi->text.size + 4095) >> 12;
vaddr.ro_size = (g_exheader.codesetinfo.ro.codesize + 4095) >> 12; vaddr.ro_addr = csi->rodata.address;
vaddr.data_addr = g_exheader.codesetinfo.data.address; vaddr.ro_size = (csi->rodata.size + 4095) >> 12;
vaddr.data_size = (g_exheader.codesetinfo.data.codesize + 4095) >> 12; vaddr.data_addr = csi->data.address;
data_mem_size = (g_exheader.codesetinfo.data.codesize + g_exheader.codesetinfo.bsssize + 4095) >> 12; vaddr.data_size = (csi->data.size + 4095) >> 12;
data_mem_size = (csi->data.size + csi->bss_size + 4095) >> 12;
vaddr.total_size = vaddr.text_size + vaddr.ro_size + vaddr.data_size; vaddr.total_size = vaddr.text_size + vaddr.ro_size + vaddr.data_size;
if ((res = allocate_shared_mem(&shared_addr, &vaddr, flags)) < 0) if ((res = allocate_shared_mem(&shared_addr, &vaddr, flags)) < 0)
{ {
@ -363,9 +365,9 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
} }
// load code // load code
if ((res = load_code(progid, &shared_addr, prog_handle, g_exheader.codesetinfo.flags.flag & 1)) >= 0) if ((res = load_code(progid, &shared_addr, prog_handle, csi->flags.compress_exefs_code)) >= 0)
{ {
memcpy(&codesetinfo.name, g_exheader.codesetinfo.name, 8); memcpy(&codesetinfo.name, csi->name, 8);
codesetinfo.program_id = progid; codesetinfo.program_id = progid;
codesetinfo.text_addr = vaddr.text_addr; codesetinfo.text_addr = vaddr.text_addr;
codesetinfo.text_size = vaddr.text_size; codesetinfo.text_size = vaddr.text_size;
@ -379,7 +381,7 @@ static Result loader_LoadProcess(Handle *process, u64 prog_handle)
res = svcCreateCodeSet(&codeset, &codesetinfo, (void *)shared_addr.text_addr, (void *)shared_addr.ro_addr, (void *)shared_addr.data_addr); res = svcCreateCodeSet(&codeset, &codesetinfo, (void *)shared_addr.text_addr, (void *)shared_addr.ro_addr, (void *)shared_addr.data_addr);
if (res >= 0) if (res >= 0)
{ {
res = svcCreateProcess(process, codeset, g_exheader.arm11kernelcaps.descriptors, count); res = svcCreateProcess(process, codeset, g_exheader.info.aci.kernel_caps.descriptors, count);
svcCloseHandle(codeset); svcCloseHandle(codeset);
if (res >= 0) if (res >= 0)
{ {
@ -515,7 +517,7 @@ static void handle_commands(void)
case 4: // GetProgramInfo case 4: // GetProgramInfo
{ {
prog_handle = *(u64 *)&cmdbuf[1]; prog_handle = *(u64 *)&cmdbuf[1];
if (prog_handle != g_cached_prog_handle || g_exheader.arm11systemlocalcaps.programid == HBLDR_3DSX_TID) if (prog_handle != g_cached_prog_handle || g_exheader.info.aci.local_caps.title_id == HBLDR_3DSX_TID)
{ {
res = loader_GetProgramInfo(&g_exheader, prog_handle); res = loader_GetProgramInfo(&g_exheader, prog_handle);
if (res >= 0) if (res >= 0)
@ -582,7 +584,7 @@ void __appExit()
void __sync_init(); void __sync_init();
void __sync_fini(); void __sync_fini();
void __system_initSyscalls(); void __system_initSyscalls();
void __ctru_exit() void __ctru_exit()
{ {
void __libc_fini_array(void); void __libc_fini_array(void);
@ -669,7 +671,7 @@ int main()
g_active_handles--; g_active_handles--;
reply_target = 0; reply_target = 0;
} }
else else
{ {
svcBreak(USERBREAK_ASSERT); svcBreak(USERBREAK_ASSERT);
} }

View File

@ -1,36 +1,5 @@
#include "memory.h" #include "memory.h"
void memcpy(void *dest, const void *src, u32 size)
{
u8 *destc = (u8 *)dest;
const u8 *srcc = (const u8 *)src;
for(u32 i = 0; i < size; i++)
destc[i] = srcc[i];
}
void memset32(void *dest, u32 filler, u32 size)
{
u32 *dest32 = (u32 *)dest;
for(u32 i = 0; i < size / 4; i++)
dest32[i] = filler;
}
int memcmp(const void *buf1, const void *buf2, u32 size)
{
const u8 *buf1c = (const u8 *)buf1,
*buf2c = (const u8 *)buf2;
for(u32 i = 0; i < size; i++)
{
int cmp = buf1c[i] - buf2c[i];
if(cmp != 0) return cmp;
}
return 0;
}
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 //Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
{ {
@ -54,4 +23,4 @@ u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
} }
return NULL; return NULL;
} }

View File

@ -1,8 +1,6 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include <string.h>
void memcpy(void *dest, const void *src, u32 size); u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);
void memset32(void *dest, u32 filler, u32 size);
int memcmp(const void *buf1, const void *buf2, u32 size);
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);

View File

@ -356,7 +356,7 @@ error:
while(true); while(true);
} }
bool loadTitleExheader(u64 progId, exheader_header *exheader) bool loadTitleExheader(u64 progId, ExHeader *exheader)
{ {
/* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/exheader.bin" /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/exheader.bin"
If it exists it should be a decrypted exheader */ If it exists it should be a decrypted exheader */
@ -370,7 +370,7 @@ bool loadTitleExheader(u64 progId, exheader_header *exheader)
u64 fileSize; u64 fileSize;
if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize != sizeof(exheader_header)) goto error; if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize != sizeof(ExHeader)) goto error;
else else
{ {
u64 total; u64 total;
@ -715,7 +715,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro
//Patch N3DS CPU Clock and L2 cache setting //Patch N3DS CPU Clock and L2 cache setting
*(off - 4) = *(off - 3); *(off - 4) = *(off - 3);
*(off - 3) = *(off - 1); *(off - 3) = *(off - 1);
memcpy(off - 1, off, 16); memmove(off - 1, off, 16);
*(off + 3) = 0xE3800000 | cpuSetting; *(off + 3) = 0xE3800000 | cpuSetting;
} }
} }
@ -736,7 +736,7 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 ro
for(end = start + 8; *(u32 *)end != 0xCC010000; end += 8) for(end = start + 8; *(u32 *)end != 0xCC010000; end += 8)
if(end >= roStart + roSize - 12) goto error; if(end >= roStart + roSize - 12) goto error;
memset32(start, 0, end - start); memset(start, 0, end - start);
} }
s64 nbSection0Modules; s64 nbSection0Modules;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include "exheader.h" #include <3ds/exheader.h>
#include "ifile.h" #include "ifile.h"
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF)) #define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
@ -44,4 +44,4 @@ extern bool isN3DS, needToInitSd, isSdMode;
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 roSize, u32 dataSize, u32 roAddress, u32 dataAddress); void patchCode(u64 progId, u16 progVer, u8 *code, u32 size, u32 textSize, u32 roSize, u32 dataSize, u32 roAddress, u32 dataAddress);
Result fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags); Result fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags);
bool loadTitleCodeSection(u64 progId, u8 *code, u32 size); bool loadTitleCodeSection(u64 progId, u8 *code, u32 size);
bool loadTitleExheader(u64 progId, exheader_header *exheader); bool loadTitleExheader(u64 progId, ExHeader *exheader);

View File

@ -43,7 +43,7 @@ Result PXIPM_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_Program
return cmdbuf[1]; return cmdbuf[1];
} }
Result PXIPM_GetProgramInfo(exheader_header *exheader, u64 prog_handle) Result PXIPM_GetProgramInfo(ExHeader *exheader, u64 prog_handle)
{ {
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include "exheader.h" #include <3ds/exheader.h>
Result pxipmInit(void); Result pxipmInit(void);
void pxipmExit(void); void pxipmExit(void);
Result PXIPM_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_ProgramInfo *update); Result PXIPM_RegisterProgram(u64 *prog_handle, FS_ProgramInfo *title, FS_ProgramInfo *update);
Result PXIPM_GetProgramInfo(exheader_header *exheader, u64 prog_handle); Result PXIPM_GetProgramInfo(ExHeader *exheader, u64 prog_handle);
Result PXIPM_UnregisterProgram(u64 prog_handle); Result PXIPM_UnregisterProgram(u64 prog_handle);

View File

@ -1,14 +1,5 @@
#include "strings.h" #include "strings.h"
size_t strnlen(const char *string, size_t maxlen)
{
size_t size;
for(size = 0; *string && size < maxlen; string++, size++);
return size;
}
void progIdToStr(char *strEnd, u64 progId) void progIdToStr(char *strEnd, u64 progId)
{ {
while(progId > 0) while(progId > 0)

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include <string.h>
size_t strnlen(const char *string, size_t maxlen);
void progIdToStr(char *strEnd, u64 progId); void progIdToStr(char *strEnd, u64 progId);

View File

@ -28,8 +28,8 @@ INCLUDES := include
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -7,7 +7,6 @@ This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE fo
*/ */
#include "MyThread.h" #include "MyThread.h"
#include "memory.h"
static void _thread_begin(void* arg) static void _thread_begin(void* arg)
{ {

View File

@ -6,12 +6,13 @@ main.c
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details). This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/ */
#include <string.h>
#include "PXI.h" #include "PXI.h"
#include "common.h" #include "common.h"
#include "MyThread.h" #include "MyThread.h"
#include "receiver.h" #include "receiver.h"
#include "sender.h" #include "sender.h"
#include "memory.h"
Handle PXISyncInterrupt = 0, PXITransferMutex = 0; Handle PXISyncInterrupt = 0, PXITransferMutex = 0;
Handle terminationRequestedEvent = 0; Handle terminationRequestedEvent = 0;

View File

@ -1,19 +0,0 @@
/*
memory.c:
Memory functions
(c) TuxSH, 2016-2017
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/
#include "memory.h"
//Adpated from CakesFW
void memcpy(void *dest, const void *src, u32 size)
{
u8 *destc = (u8 *)dest;
const u8 *srcc = (const u8 *)src;
for(u32 i = 0; i < size; i++)
destc[i] = srcc[i];
}

View File

@ -1,13 +0,0 @@
/*
memory.h:
Memory functions
(c) TuxSH, 2016-2017
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/
#pragma once
#include <3ds/types.h>
void memcpy(void *dest, const void *src, u32 size);

View File

@ -6,9 +6,10 @@ receiver.c:
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details). This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/ */
#include <string.h>
#include "receiver.h" #include "receiver.h"
#include "PXI.h" #include "PXI.h"
#include "memory.h"
static inline void receiveFromArm9(void) static inline void receiveFromArm9(void)
{ {

View File

@ -7,9 +7,10 @@ sender.c
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details). This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
*/ */
#include <string.h>
#include "sender.h" #include "sender.h"
#include "PXI.h" #include "PXI.h"
#include "memory.h"
Result sendPXICmdbuf(Handle *additionalHandle, u32 serviceId, u32 *buffer) Result sendPXICmdbuf(Handle *additionalHandle, u32 serviceId, u32 *buffer)
{ {

View File

@ -28,8 +28,8 @@ INCLUDES := include include/gdb include/menus
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -1,2 +0,0 @@
#pragma once
#include "../../loader/source/exheader.h"

View File

@ -27,13 +27,13 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include "exheader.h" #include <3ds/exheader.h>
Result fsregInit(void); Result fsregInit(void);
void fsregExit(void); void fsregExit(void);
Result FSREG_CheckHostLoadId(u64 prog_handle); Result FSREG_CheckHostLoadId(u64 prog_handle);
Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title); Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title);
Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle); Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle);
Result FSREG_UnloadProgram(u64 prog_handle); Result FSREG_UnloadProgram(u64 prog_handle);
Result FSREG_Unregister(u32 pid); Result FSREG_Unregister(u32 pid);
Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo); Result FSREG_Register(u32 pid, u64 prog_handle, FS_ProgramInfo *info, void *storageinfo);

View File

@ -27,18 +27,8 @@
#pragma once #pragma once
#include <3ds/types.h> #include <3ds/types.h>
#include <string.h>
void *memcpy(void *dest, const void *src, u32 size);
int memcmp(const void *buf1, const void *buf2, u32 size);
void *memset(void *dest, u32 value, u32 size) __attribute__((used));
void *memset32(void *dest, u32 value, u32 size);
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize); u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, u32 size);
s32 strnlen(const char *string, s32 maxlen);
s32 strlen(const char *string);
s32 strcmp(const char *str1, const char *str2);
s32 strncmp(const char *str1, const char *str2, u32 size);
const char *strchr(const char *string, int c);
void hexItoa(u64 number, char *out, u32 digits, bool uppercase); void hexItoa(u64 number, char *out, u32 digits, bool uppercase);
unsigned long int xstrtoul(const char *nptr, char **endptr, int base, bool allowPrefix, bool *ok); unsigned long int xstrtoul(const char *nptr, char **endptr, int base, bool allowPrefix, bool *ok);

View File

@ -261,7 +261,7 @@ Handle Ldr_CodesetFrom3dsx(const char* name, u32* codePages, u32 baseAddr, IFile
// Create the codeset // Create the codeset
CodeSetInfo csinfo; CodeSetInfo csinfo;
memset(&csinfo, 0, sizeof(csinfo)); memset(&csinfo, 0, sizeof(csinfo));
strncpy((char*)csinfo.name, name, 8); memcpy(csinfo.name, name, 8);
csinfo.program_id = tid; csinfo.program_id = tid;
csinfo.text_addr = d.segAddrs[0]; csinfo.text_addr = d.segAddrs[0];
csinfo.text_size = d.segSizes[0] >> 12; csinfo.text_size = d.segSizes[0] >> 12;

View File

@ -114,7 +114,7 @@ u32 Draw_DrawFormattedString(u32 posX, u32 posY, u32 color, const char *fmt, ...
void Draw_FillFramebuffer(u32 value) void Draw_FillFramebuffer(u32 value)
{ {
memset32(FB_BOTTOM_VRAM_ADDR, value, FB_BOTTOM_SIZE); memset(FB_BOTTOM_VRAM_ADDR, value, FB_BOTTOM_SIZE);
} }
void Draw_ClearFramebuffer(void) void Draw_ClearFramebuffer(void)

View File

@ -52,12 +52,12 @@ MyThread *errDispCreateThread(void)
static inline u32 ERRF_DisplayRegisterValue(u32 posX, u32 posY, const char *name, u32 value) static inline u32 ERRF_DisplayRegisterValue(u32 posX, u32 posY, const char *name, u32 value)
{ {
return Draw_DrawFormattedString(posX, posY, COLOR_WHITE, "%-9s %08x", name, value); return Draw_DrawFormattedString(posX, posY, COLOR_WHITE, "%-9s %08lx", name, value);
} }
static inline int ERRF_FormatRegisterValue(char *out, const char *name, u32 value) static inline int ERRF_FormatRegisterValue(char *out, const char *name, u32 value)
{ {
return sprintf(out, "%-9s %08x", name, value); return sprintf(out, "%-9s %08lx", name, value);
} }
static int ERRF_FormatError(char *out, ERRF_FatalErrInfo *info) static int ERRF_FormatError(char *out, ERRF_FatalErrInfo *info)
@ -88,7 +88,7 @@ static int ERRF_FormatError(char *out, ERRF_FatalErrInfo *info)
Handle processHandle; Handle processHandle;
Result res; Result res;
out += sprintf(out, "\nProcess ID: %u\n", info->procId); out += sprintf(out, "\nProcess ID: %lu\n", info->procId);
res = svcOpenProcess(&processHandle, info->procId); res = svcOpenProcess(&processHandle, info->procId);
if(R_SUCCEEDED(res)) if(R_SUCCEEDED(res))
@ -149,9 +149,9 @@ static int ERRF_FormatError(char *out, ERRF_FatalErrInfo *info)
else if(info->type != ERRF_ERRTYPE_CARD_REMOVED) else if(info->type != ERRF_ERRTYPE_CARD_REMOVED)
{ {
if(info->type != ERRF_ERRTYPE_FAILURE) if(info->type != ERRF_ERRTYPE_FAILURE)
out += sprintf(out, "Address: 0x%08x\n", info->pcAddr); out += sprintf(out, "Address: 0x%08lx\n", info->pcAddr);
out += sprintf(out, "Error code: 0x%08x\n", info->resCode); out += sprintf(out, "Error code: 0x%08lx\n", info->resCode);
} }
const char *desc; const char *desc;

View File

@ -69,14 +69,16 @@ Result fsregSetupPermissions(void)
u32 pid; u32 pid;
Result res; Result res;
FS_ProgramInfo info; FS_ProgramInfo info;
u32 storage[8] = {0}; ExHeader_Arm11StorageInfo storage = {0};
storage[6] = 0x800 | 0x400 | 0x80 | 0x1; // SDMC access and NAND access flags // SDMC access and NAND access flags
storage.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RW |
FSACCESS_SDMC_RW | FSACCESS_CATEGORY_SYSTEM_APPLICATION;
info.programId = 0x0004013000006902LL; // Rosalina TID info.programId = 0x0004013000006902LL; // Rosalina TID
info.mediaType = MEDIATYPE_NAND; info.mediaType = MEDIATYPE_NAND;
if(R_SUCCEEDED(res = svcGetProcessId(&pid, 0xFFFF8001))) // 0xFFFF8001 is an handle to the active process if(R_SUCCEEDED(res = svcGetProcessId(&pid, CUR_PROCESS_HANDLE))) // 0xFFFF8001 is an handle to the active process
res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, (u8*)storage); res = FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storage);
return res; return res;
} }
@ -113,7 +115,7 @@ Result FSREG_LoadProgram(u64 *prog_handle, FS_ProgramInfo *title)
return cmdbuf[1]; return cmdbuf[1];
} }
Result FSREG_GetProgramInfo(exheader_header *exheader, u32 entry_count, u64 prog_handle) Result FSREG_GetProgramInfo(ExHeader *exheader, u32 entry_count, u64 prog_handle)
{ {
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();

View File

@ -163,7 +163,7 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
s64 dummy; s64 dummy;
u32 core; u32 core;
Result r = svcGetDebugThreadContext(&regs, ctx->debug, threadId, THREADCONTEXT_CONTROL_ALL); Result r = svcGetDebugThreadContext(&regs, ctx->debug, threadId, THREADCONTEXT_CONTROL_ALL);
int n = sprintf(out, "T%02xthread:%x;", sig, threadId); int n = sprintf(out, "T%02xthread:%lx;", sig, threadId);
if(R_FAILED(r)) if(R_FAILED(r))
return n; return n;
@ -171,12 +171,12 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
r = svcGetDebugThreadParam(&dummy, &core, ctx->debug, ctx->currentThreadId, DBGTHREAD_PARAMETER_CPU_CREATOR); // Creator = "first ran, and running the thread" r = svcGetDebugThreadParam(&dummy, &core, ctx->debug, ctx->currentThreadId, DBGTHREAD_PARAMETER_CPU_CREATOR); // Creator = "first ran, and running the thread"
if(R_SUCCEEDED(r)) if(R_SUCCEEDED(r))
n += sprintf(out + n, "core:%x;", core); n += sprintf(out + n, "core:%lx;", core);
for(u32 i = 0; i <= 12; i++) for(u32 i = 0; i <= 12; i++)
n += sprintf(out + n, "%x:%08x;", i, __builtin_bswap32(regs.cpu_registers.r[i])); n += sprintf(out + n, "%lx:%08lx;", i, __builtin_bswap32(regs.cpu_registers.r[i]));
n += sprintf(out + n, "d:%08x;e:%08x;f:%08x;19:%08x;", n += sprintf(out + n, "d:%08lx;e:%08lx;f:%08lx;19:%08lx;",
__builtin_bswap32(regs.cpu_registers.sp), __builtin_bswap32(regs.cpu_registers.lr), __builtin_bswap32(regs.cpu_registers.pc), __builtin_bswap32(regs.cpu_registers.sp), __builtin_bswap32(regs.cpu_registers.lr), __builtin_bswap32(regs.cpu_registers.pc),
__builtin_bswap32(regs.cpu_registers.cpsr)); __builtin_bswap32(regs.cpu_registers.cpsr));
@ -184,10 +184,10 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
{ {
u64 val; u64 val;
memcpy(&val, &regs.fpu_registers.d[i], 8); memcpy(&val, &regs.fpu_registers.d[i], 8);
n += sprintf(out + n, "%x:%016llx;", 26 + i, __builtin_bswap64(val)); n += sprintf(out + n, "%lx:%016llx;", 26 + i, __builtin_bswap64(val));
} }
n += sprintf(out + n, "2a:%08x;2b:%08x;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc)); n += sprintf(out + n, "2a:%08lx;2b:%08lx;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc));
return n; return n;
} }
@ -301,7 +301,7 @@ int GDB_SendStopReply(GDBContext *ctx, const DebugEventInfo *info)
{ {
// no signal, SIGTERM, SIGQUIT (process exited), SIGTERM (process terminated) // no signal, SIGTERM, SIGQUIT (process exited), SIGTERM (process terminated)
static int threadExitRepliesSigs[] = { 0, SIGTERM, SIGQUIT, SIGTERM }; static int threadExitRepliesSigs[] = { 0, SIGTERM, SIGQUIT, SIGTERM };
return GDB_SendFormattedPacket(ctx, "w%02x;%x", threadExitRepliesSigs[(u32)info->exit_thread.reason], info->thread_id); return GDB_SendFormattedPacket(ctx, "w%02x;%lx", threadExitRepliesSigs[(u32)info->exit_thread.reason], info->thread_id);
} }
break; break;
} }
@ -365,7 +365,7 @@ int GDB_SendStopReply(GDBContext *ctx, const DebugEventInfo *info)
GDB_SendDebugString(ctx, "Warning: unknown watchpoint encountered!\n"); GDB_SendDebugString(ctx, "Warning: unknown watchpoint encountered!\n");
GDB_ParseCommonThreadInfo(buffer, ctx, SIGTRAP); GDB_ParseCommonThreadInfo(buffer, ctx, SIGTRAP);
return GDB_SendFormattedPacket(ctx, "%s%swatch:%08x;", buffer, kinds[(u32)kind], exc.stop_point.fault_information); return GDB_SendFormattedPacket(ctx, "%s%swatch:%08lx;", buffer, kinds[(u32)kind], exc.stop_point.fault_information);
break; break;
} }

View File

@ -127,7 +127,7 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo)
if(R_FAILED(r)) if(R_FAILED(r))
name[0] = 0; name[0] = 0;
n = sprintf(outbuf, "%s 0x%x, 0x%08x\n", name, cmdId, ctx->threadInfos[id].tls + 0x80); n = sprintf(outbuf, "%s 0x%lx, 0x%08lx\n", name, cmdId, ctx->threadInfos[id].tls + 0x80);
end: end:
svcCloseHandle(handle); svcCloseHandle(handle);
@ -181,9 +181,9 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle)
svcControlService(SERVICEOP_GET_NAME, serviceBuf, handle); svcControlService(SERVICEOP_GET_NAME, serviceBuf, handle);
refcount = (u32)(refcountRaw - 1); refcount = (u32)(refcountRaw - 1);
if(serviceBuf[0] != 0) if(serviceBuf[0] != 0)
n = sprintf(outbuf, "(%s *)0x%08x /* %s handle, %u %s */\n", classBuf, kernelAddr, serviceBuf, refcount, refcount == 1 ? "reference" : "references"); n = sprintf(outbuf, "(%s *)0x%08lx /* %s handle, %lu %s */\n", classBuf, kernelAddr, serviceBuf, refcount, refcount == 1 ? "reference" : "references");
else else
n = sprintf(outbuf, "(%s *)0x%08x /* %u %s */\n", classBuf, kernelAddr, refcount, refcount == 1 ? "reference" : "references"); n = sprintf(outbuf, "(%s *)0x%08lx /* %lu %s */\n", classBuf, kernelAddr, refcount, refcount == 1 ? "reference" : "references");
end: end:
svcCloseHandle(handle); svcCloseHandle(handle);
@ -210,16 +210,16 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig)
s64 TTBCR, TTBR0; s64 TTBCR, TTBR0;
svcGetSystemInfo(&TTBCR, 0x10002, 0); svcGetSystemInfo(&TTBCR, 0x10002, 0);
svcGetProcessInfo(&TTBR0, process, 0x10008); svcGetProcessInfo(&TTBR0, process, 0x10008);
n = sprintf(outbuf, "TTBCR = %u\nTTBR0 = 0x%08x\nTTBR1 =", (u32)TTBCR, (u32)TTBR0); n = sprintf(outbuf, "TTBCR = %lu\nTTBR0 = 0x%08lx\nTTBR1 =", (u32)TTBCR, (u32)TTBR0);
for(u32 i = 0; i < (isN3DS ? 4 : 2); i++) for(u32 i = 0; i < (isN3DS ? 4 : 2); i++)
{ {
s64 TTBR1; s64 TTBR1;
svcGetSystemInfo(&TTBR1, 0x10002, 1 + i); svcGetSystemInfo(&TTBR1, 0x10002, 1 + i);
if(i == (isN3DS ? 3 : 1)) if(i == (isN3DS ? 3 : 1))
n += sprintf(outbuf + n, " 0x%08x\n", (u32)TTBR1); n += sprintf(outbuf + n, " 0x%08lx\n", (u32)TTBR1);
else else
n += sprintf(outbuf + n, " 0x%08x /", (u32)TTBR1); n += sprintf(outbuf + n, " 0x%08lx /", (u32)TTBR1);
} }
svcCloseHandle(process); svcCloseHandle(process);
} }
@ -294,7 +294,7 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMemRegions)
const char *perm = FormatMemPerm(memi.perm); const char *perm = FormatMemPerm(memi.perm);
const char *state = FormatMemState(memi.state); const char *state = FormatMemState(memi.state);
posInBuffer += sprintf(outbuf + posInBuffer, "%08X - %08X %s %s\n", posInBuffer += sprintf(outbuf + posInBuffer, "%08lx - %08lx %s %s\n",
memi.base_addr, address, perm, state); memi.base_addr, address, perm, state);
} }
} }

View File

@ -163,7 +163,7 @@ GDB_DECLARE_QUERY_HANDLER(CurrentThreadId)
if(ctx->currentThreadId == 0) if(ctx->currentThreadId == 0)
ctx->currentThreadId = GDB_GetCurrentThread(ctx); ctx->currentThreadId = GDB_GetCurrentThread(ctx);
return ctx->currentThreadId != 0 ? GDB_SendFormattedPacket(ctx, "QC%x", ctx->currentThreadId) : GDB_ReplyErrno(ctx, EPERM); return ctx->currentThreadId != 0 ? GDB_SendFormattedPacket(ctx, "QC%lx", ctx->currentThreadId) : GDB_ReplyErrno(ctx, EPERM);
} }
static void GDB_GenerateThreadListData(GDBContext *ctx) static void GDB_GenerateThreadListData(GDBContext *ctx)
@ -187,7 +187,7 @@ static void GDB_GenerateThreadListData(GDBContext *ctx)
char *bufptr = ctx->threadListData; char *bufptr = ctx->threadListData;
for(u32 i = 0; i < nbAliveThreads; i++) for(u32 i = 0; i < nbAliveThreads; i++)
bufptr += sprintf(bufptr, i == (nbAliveThreads - 1) ? "%x" : "%x,", aliveThreadIds[i]); bufptr += sprintf(bufptr, i == (nbAliveThreads - 1) ? "%lx" : "%lx,", aliveThreadIds[i]);
} }
static int GDB_SendThreadData(GDBContext *ctx) static int GDB_SendThreadData(GDBContext *ctx)
@ -277,27 +277,27 @@ GDB_DECLARE_QUERY_HANDLER(ThreadExtraInfo)
if(val == 65) if(val == 65)
sThreadDynamicPriority[0] = 0; sThreadDynamicPriority[0] = 0;
else else
sprintf(sThreadDynamicPriority, "dynamic prio.: %d, ", (s32)val); sprintf(sThreadDynamicPriority, "dynamic prio.: %ld, ", (s32)val);
r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_PRIORITY); r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_PRIORITY);
if(R_FAILED(r)) if(R_FAILED(r))
sThreadStaticPriority[0] = 0; sThreadStaticPriority[0] = 0;
else else
sprintf(sThreadStaticPriority, "static prio.: %d, ", (s32)val); sprintf(sThreadStaticPriority, "static prio.: %ld, ", (s32)val);
r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_CPU_IDEAL); r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_CPU_IDEAL);
if(R_FAILED(r)) if(R_FAILED(r))
sCoreIdeal[0] = 0; sCoreIdeal[0] = 0;
else else
sprintf(sCoreIdeal, "ideal core: %u, ", val); sprintf(sCoreIdeal, "ideal core: %lu, ", val);
r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_CPU_CREATOR); // Creator = "first ran, and running the thread" r = svcGetDebugThreadParam(&dummy, &val, ctx->debug, id, DBGTHREAD_PARAMETER_CPU_CREATOR); // Creator = "first ran, and running the thread"
if(R_FAILED(r)) if(R_FAILED(r))
sCoreCreator[0] = 0; sCoreCreator[0] = 0;
else else
sprintf(sCoreCreator, "running on core %u", val); sprintf(sCoreCreator, "running on core %lu", val);
n = sprintf(buf, "TLS: 0x%08x%s%s%s%s%s", tls, sStatus, sThreadDynamicPriority, sThreadStaticPriority, n = sprintf(buf, "TLS: 0x%08lx%s%s%s%s%s", tls, sStatus, sThreadDynamicPriority, sThreadStaticPriority,
sCoreIdeal, sCoreCreator); sCoreIdeal, sCoreCreator);
return GDB_SendHexPacket(ctx, buf, (u32)n); return GDB_SendHexPacket(ctx, buf, (u32)n);
@ -324,5 +324,5 @@ GDB_DECLARE_QUERY_HANDLER(GetTLSAddr)
if(tls == 0) if(tls == 0)
return GDB_ReplyErrno(ctx, EINVAL); return GDB_ReplyErrno(ctx, EINVAL);
return GDB_SendFormattedPacket(ctx, "%08x", tls + offset); return GDB_SendFormattedPacket(ctx, "%08lx", tls + offset);
} }

View File

@ -87,9 +87,9 @@ GDB_DECLARE_XFER_OSDATA_HANDLER(CfwVersion)
isRelease = (bool)out; isRelease = (bool)out;
if(GET_VERSION_REVISION(version) == 0) if(GET_VERSION_REVISION(version) == 0)
sprintf(versionString, "v%u.%u", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version)); sprintf(versionString, "v%lu.%lu", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version));
else else
sprintf(versionString, "v%u.%u.%u", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version), GET_VERSION_REVISION(version)); sprintf(versionString, "v%lu.%lu.%lu", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version), GET_VERSION_REVISION(version));
sz = (u32)sprintf(buf, (const char *)osdata_cfw_version_template_xml, versionString, commitHash, isRelease ? "Yes" : "No"); sz = (u32)sprintf(buf, (const char *)osdata_cfw_version_template_xml, versionString, commitHash, isRelease ? "Yes" : "No");
@ -150,7 +150,7 @@ GDB_DECLARE_XFER_OSDATA_HANDLER(Processes)
static const char item[] = static const char item[] =
" <item>\n" " <item>\n"
" <column name=\"pid\">%u</column>\n" " <column name=\"pid\">%lu</column>\n"
" <column name=\"command\">%s</column>\n" " <column name=\"command\">%s</column>\n"
" </item>\n"; " </item>\n";

View File

@ -3,7 +3,7 @@
<osdata type="cfwversion"> <osdata type="cfwversion">
<item> <item>
<column name="Version">%s</column> <column name="Version">%s</column>
<column name="Commit hash">%08x</column> <column name="Commit hash">%08lx</column>
<column name="Release">%s</column> <column name="Release">%s</column>
</item> </item>
</osdata> </osdata>

View File

@ -32,7 +32,6 @@
#include "menu.h" #include "menu.h"
#include "csvc.h" #include "csvc.h"
#include "memory.h" #include "memory.h"
#include "exheader.h"
#define MAP_BASE 0x10000000 #define MAP_BASE 0x10000000
@ -254,45 +253,66 @@ static void HBLDR_HandleCommands(void)
} }
case 4: case 4:
{ {
if (cmdbuf[0] != IPC_MakeHeader(4, 0, 2) || cmdbuf[1] != IPC_Desc_Buffer(sizeof(exheader_header), IPC_BUFFER_RW)) if (cmdbuf[0] != IPC_MakeHeader(4, 0, 2) || cmdbuf[1] != IPC_Desc_Buffer(sizeof(ExHeader), IPC_BUFFER_RW))
{ {
error(cmdbuf, 0xD9001830); error(cmdbuf, 0xD9001830);
break; break;
} }
// Perform ExHeader patches // Perform ExHeader patches
exheader_header* exh = (exheader_header*)cmdbuf[2]; ExHeader* exh = (ExHeader*)cmdbuf[2];
u32 stacksize = 4096; // 3dsx/libctru don't require anymore than this memcpy(exh->info.sci.codeset_info.name, "3dsx_app", 8);
memcpy(exh->codesetinfo.name, "3dsx_app", 8); exh->info.sci.codeset_info.stack_size = 0x1000; // 3dsx/libctru don't require anymore than this
memcpy(exh->codesetinfo.stacksize, &stacksize, 4); memset(&exh->info.sci.dependencies, 0, sizeof(exh->info.sci.dependencies));
memset(&exh->deplist, 0, sizeof(exh->deplist)); memcpy(exh->info.sci.dependencies, dependencyList, sizeof(dependencyList));
memcpy(exh->deplist.programid, dependencyList, sizeof(dependencyList));
exheader_arm11systemlocalcaps* localcaps0 = &exh->arm11systemlocalcaps; ExHeader_Arm11SystemLocalCapabilities* localcaps0 = &exh->info.aci.local_caps;
exheader_arm11systemlocalcaps* localcaps1 = &exh->accessdesc.arm11systemlocalcaps; ExHeader_Arm11SystemLocalCapabilities* localcaps1 = &exh->access_descriptor.acli.local_caps;
localcaps0->flags[0] = 0x00;
localcaps1->flags[0] = 0x00;
localcaps0->flags[1] = 0x01;
localcaps1->flags[1] = 0x01;
localcaps0->flags[2] = 0x04;
localcaps1->flags[2] = 0x05;
localcaps0->priority = 0x30;
localcaps1->priority = 0;
memset(localcaps0->resourcelimitdescriptor, 0, 0x10);
memset(localcaps1->resourcelimitdescriptor, 0, 0x10);
localcaps0->resourcelimitdescriptor[0] = 0x9E;
localcaps0->resourcelimitdescriptor[1] = 0x9E;
memset(localcaps0->storageinfo.accessinfo, 0xFF, 7);
memset(localcaps1->storageinfo.accessinfo, 0xFF, 7);
memcpy(localcaps0->serviceaccesscontrol, serviceList, sizeof(serviceList));
memcpy(localcaps1->serviceaccesscontrol, serviceList, sizeof(serviceList));
memset(localcaps0->serviceaccesscontrol+0x20, 0, 2);
memset(localcaps1->serviceaccesscontrol+0x20, 0, 2);
localcaps0->resourcelimitcategory = 0;
localcaps1->resourcelimitcategory = 0;
exheader_arm11kernelcapabilities* kcaps0 = &exh->arm11kernelcaps; localcaps0->core_info.core_version = 2;
exheader_arm11kernelcapabilities* kcaps1 = &exh->accessdesc.arm11kernelcaps; localcaps0->core_info.use_cpu_clockrate_804MHz = false;
localcaps0->core_info.enable_l2c = false;
localcaps0->core_info.n3ds_system_mode = SYSMODE_N3DS_PROD;
localcaps0->core_info.ideal_processor = 0;
localcaps0->core_info.affinity_mask = BIT(0);
localcaps0->core_info.o3ds_system_mode = SYSMODE_O3DS_PROD;
localcaps0->core_info.priority = 0x30;
localcaps1->core_info.core_version = 2;
localcaps1->core_info.use_cpu_clockrate_804MHz = false;
localcaps1->core_info.enable_l2c = false;
localcaps1->core_info.n3ds_system_mode = SYSMODE_N3DS_PROD;
localcaps1->core_info.ideal_processor = BIT(0); // Intended, this is an oddity of the ExHeader
localcaps1->core_info.affinity_mask = BIT(0);
localcaps1->core_info.o3ds_system_mode = SYSMODE_O3DS_PROD;
localcaps1->core_info.priority = 0; // Intended
memset(localcaps0->reslimits, 0, sizeof(localcaps0->reslimits));
memset(localcaps1->reslimits, 0, sizeof(localcaps0->reslimits));
localcaps0->reslimits[0] = 0x9E; // Stuff needed to run stuff on core1
localcaps1->reslimits[1] = 0x9E;
localcaps0->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything
localcaps0->storage_info.no_romfs = true;
localcaps0->storage_info.use_extended_savedata_access = true; // Whatever
localcaps1->storage_info.fs_access_info = 0xFFFFFFFF; // Give access to everything
localcaps0->storage_info.no_romfs = true;
localcaps0->storage_info.use_extended_savedata_access = true; // Whatever
/* We have a patched SM, so whatever... */
memset(localcaps0->service_access, 0, sizeof(localcaps0->service_access));
memcpy(localcaps0->service_access, serviceList, sizeof(serviceList));
memset(localcaps1->service_access, 0, sizeof(localcaps0->service_access));
memcpy(localcaps1->service_access, serviceList, sizeof(serviceList));
localcaps0->reslimit_category = RESLIMIT_CATEGORY_APPLICATION;
localcaps1->reslimit_category = RESLIMIT_CATEGORY_APPLICATION;
ExHeader_Arm11KernelCapabilities* kcaps0 = &exh->info.aci.kernel_caps;
ExHeader_Arm11KernelCapabilities* kcaps1 = &exh->access_descriptor.acli.kernel_caps;
memset(kcaps0->descriptors, 0xFF, sizeof(kcaps0->descriptors)); memset(kcaps0->descriptors, 0xFF, sizeof(kcaps0->descriptors));
memset(kcaps1->descriptors, 0xFF, sizeof(kcaps1->descriptors)); memset(kcaps1->descriptors, 0xFF, sizeof(kcaps1->descriptors));
memcpy(kcaps0->descriptors, kernelCaps, sizeof(kernelCaps)); memcpy(kcaps0->descriptors, kernelCaps, sizeof(kernelCaps));
@ -301,22 +321,22 @@ static void HBLDR_HandleCommands(void)
u64 lastdep = sizeof(dependencyList)/8; u64 lastdep = sizeof(dependencyList)/8;
if (osGetFirmVersion() >= SYSTEM_VERSION(2,50,0)) // 9.6+ FIRM if (osGetFirmVersion() >= SYSTEM_VERSION(2,50,0)) // 9.6+ FIRM
{ {
exh->deplist.programid[lastdep++] = 0x0004013000004002ULL; // nfc exh->info.sci.dependencies[lastdep++] = 0x0004013000004002ULL; // nfc
strncpy((char*)&localcaps0->serviceaccesscontrol[0x20], "nfc:u", 8); strncpy((char*)&localcaps0->service_access[0x20], "nfc:u", 8);
strncpy((char*)&localcaps1->serviceaccesscontrol[0x20], "nfc:u", 8); strncpy((char*)&localcaps1->service_access[0x20], "nfc:u", 8);
s64 dummy = 0; s64 dummy = 0;
bool isN3DS = svcGetSystemInfo(&dummy, 0x10001, 0) == 0; bool isN3DS = svcGetSystemInfo(&dummy, 0x10001, 0) == 0;
if (isN3DS) if (isN3DS)
{ {
exh->deplist.programid[lastdep++] = 0x0004013020004102ULL; // mvd exh->info.sci.dependencies[lastdep++] = 0x0004013020004102ULL; // mvd
strncpy((char*)&localcaps0->serviceaccesscontrol[0x21], "mvd:STD", 8); strncpy((char*)&localcaps0->service_access[0x21], "mvd:STD", 8);
strncpy((char*)&localcaps1->serviceaccesscontrol[0x21], "mvd:STD", 8); strncpy((char*)&localcaps1->service_access[0x21], "mvd:STD", 8);
} }
} }
cmdbuf[0] = IPC_MakeHeader(4, 1, 2); cmdbuf[0] = IPC_MakeHeader(4, 1, 2);
cmdbuf[1] = 0; cmdbuf[1] = 0;
cmdbuf[2] = IPC_Desc_Buffer(sizeof(exheader_header), IPC_BUFFER_RW); cmdbuf[2] = IPC_Desc_Buffer(sizeof(ExHeader), IPC_BUFFER_RW);
cmdbuf[3] = (u32)exh; cmdbuf[3] = (u32)exh;
break; break;
} }

View File

@ -26,50 +26,6 @@
#include "memory.h" #include "memory.h"
void *memcpy(void *dest, const void *src, u32 size)
{
u8 *destc = (u8 *)dest;
const u8 *srcc = (const u8 *)src;
for(u32 i = 0; i < size; i++)
destc[i] = srcc[i];
return dest;
}
int memcmp(const void *buf1, const void *buf2, u32 size)
{
const u8 *buf1c = (const u8 *)buf1;
const u8 *buf2c = (const u8 *)buf2;
for(u32 i = 0; i < size; i++)
{
int cmp = buf1c[i] - buf2c[i];
if(cmp)
return cmp;
}
return 0;
}
void *memset(void *dest, u32 value, u32 size)
{
u8 *destc = (u8 *)dest;
for(u32 i = 0; i < size; i++) destc[i] = (u8)value;
return dest;
}
void *memset32(void *dest, u32 value, u32 size)
{
u32 *dest32 = (u32 *)dest;
for(u32 i = 0; i < size/4; i++) dest32[i] = value;
return dest;
}
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180 //Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
{ {
@ -95,82 +51,6 @@ u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)
return NULL; return NULL;
} }
char *strcpy(char *dest, const char *src)
{
u32 i;
for(i = 0; src[i] != 0; i++)
dest[i] = src[i];
dest[i] = 0;
return dest;
}
char *strncpy(char *dest, const char *src, u32 size)
{
u32 i;
for(i = 0; i < size && src[i] != 0; i++)
dest[i] = src[i];
for(; i < size; i++)
dest[i] = 0;
return dest;
}
s32 strnlen(const char *string, s32 maxlen)
{
s32 size;
for(size = 0; size < maxlen && *string; string++, size++);
return size;
}
s32 strlen(const char *string)
{
char *stringEnd = (char *)string;
while(*stringEnd) stringEnd++;
return stringEnd - string;
}
s32 strcmp(const char *str1, const char *str2)
{
while(*str1 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1 - *str2;
}
s32 strncmp(const char *str1, const char *str2, u32 size)
{
while(size && *str1 && (*str1 == *str2))
{
str1++;
str2++;
size--;
}
if (!size)
return 0;
else
return *(u8*)str1 - *(u8*)str2;
}
const char *strchr(const char *string, int c)
{
char *stringEnd = (char *)string;
while(*stringEnd != 0)
{
if(*stringEnd == c) return stringEnd;
stringEnd++;
}
return NULL;
}
void hexItoa(u64 number, char *out, u32 digits, bool uppercase) void hexItoa(u64 number, char *out, u32 digits, bool uppercase)
{ {
const char hexDigits[] = "0123456789ABCDEF"; const char hexDigits[] = "0123456789ABCDEF";

View File

@ -228,9 +228,9 @@ static void menuDraw(Menu *menu, u32 selected)
isRelease = (bool)out; isRelease = (bool)out;
if(GET_VERSION_REVISION(version) == 0) if(GET_VERSION_REVISION(version) == 0)
sprintf(versionString, "v%u.%u", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version)); sprintf(versionString, "v%lu.%lu", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version));
else else
sprintf(versionString, "v%u.%u.%u", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version), GET_VERSION_REVISION(version)); sprintf(versionString, "v%lu.%lu.%lu", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version), GET_VERSION_REVISION(version));
Draw_DrawString(10, 10, COLOR_TITLE, menu->title); Draw_DrawString(10, 10, COLOR_TITLE, menu->title);
@ -261,7 +261,7 @@ static void menuDraw(Menu *menu, u32 selected)
if(isRelease) if(isRelease)
Draw_DrawFormattedString(10, SCREEN_BOT_HEIGHT - 20, COLOR_TITLE, "Luma3DS %s", versionString); Draw_DrawFormattedString(10, SCREEN_BOT_HEIGHT - 20, COLOR_TITLE, "Luma3DS %s", versionString);
else else
Draw_DrawFormattedString(10, SCREEN_BOT_HEIGHT - 20, COLOR_TITLE, "Luma3DS %s-%08x", versionString, commitHash); Draw_DrawFormattedString(10, SCREEN_BOT_HEIGHT - 20, COLOR_TITLE, "Luma3DS %s-%08lx", versionString, commitHash);
Draw_FlushFramebuffer(); Draw_FlushFramebuffer();
} }

View File

@ -224,7 +224,7 @@ void RosalinaMenu_TakeScreenshot(void)
days++; days++;
month++; month++;
sprintf(filename, "/luma/screenshots/%04u-%02u-%02u_%02u-%02u-%02u.%03u_top.bmp", year, month, days, hours, minutes, seconds, milliseconds); sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_top.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE)); TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
Draw_CreateBitmapHeader(framebufferCache, 400, 240); Draw_CreateBitmapHeader(framebufferCache, 400, 240);
@ -239,7 +239,7 @@ void RosalinaMenu_TakeScreenshot(void)
TRY(IFile_Write(&file, &total, framebufferCache, 3 * 400 * 120, 0)); TRY(IFile_Write(&file, &total, framebufferCache, 3 * 400 * 120, 0));
TRY(IFile_Close(&file)); TRY(IFile_Close(&file));
sprintf(filename, "/luma/screenshots/%04u-%02u-%02u_%02u-%02u-%02u.%03u_bot.bmp", year, month, days, hours, minutes, seconds, milliseconds); sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_bot.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE)); TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
Draw_CreateBitmapHeader(framebufferCache, 320, 240); Draw_CreateBitmapHeader(framebufferCache, 320, 240);
@ -256,7 +256,7 @@ void RosalinaMenu_TakeScreenshot(void)
if((GPU_FB_TOP_FMT & 0x20) && (Draw_GetCurrentFramebufferAddress(true, true) != Draw_GetCurrentFramebufferAddress(true, false))) if((GPU_FB_TOP_FMT & 0x20) && (Draw_GetCurrentFramebufferAddress(true, true) != Draw_GetCurrentFramebufferAddress(true, false)))
{ {
sprintf(filename, "/luma/screenshots/%04u-%02u-%02u_%02u-%02u-%02u.%03u_top_right.bmp", year, month, days, hours, minutes, seconds, milliseconds); sprintf(filename, "/luma/screenshots/%04lu-%02lu-%02lu_%02lu-%02lu-%02lu.%03llu_top_right.bmp", year, month, days, hours, minutes, seconds, milliseconds);
TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE)); TRY(IFile_Open(&file, archiveId, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_ASCII, filename), FS_OPEN_CREATE | FS_OPEN_WRITE));
Draw_CreateBitmapHeader(framebufferCache, 400, 240); Draw_CreateBitmapHeader(framebufferCache, 400, 240);
@ -285,7 +285,7 @@ end:
Draw_Lock(); Draw_Lock();
Draw_DrawString(10, 10, COLOR_TITLE, "Screenshot"); Draw_DrawString(10, 10, COLOR_TITLE, "Screenshot");
if(R_FAILED(res)) if(R_FAILED(res))
Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08x).", (u32)res); Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08lx).", (u32)res);
else else
Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded."); Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded.");

View File

@ -1080,7 +1080,8 @@ static void Cheat_LoadCheatsIntoMemory(u64 titleId)
cheat = Cheat_AllocCheat(); cheat = Cheat_AllocCheat();
} }
} }
strncpy(cheat->name, line, 39); strncpy(cheat->name, line, 38);
cheat->name[38] = '\0';
} }
} }
} while (R_SUCCEEDED(res)); } while (R_SUCCEEDED(res));
@ -1225,7 +1226,7 @@ void RosalinaMenu_Cheats(void)
} }
else else
{ {
Draw_DrawFormattedString(10, 10, COLOR_TITLE, "ERROR: %08x", r); Draw_DrawFormattedString(10, 10, COLOR_TITLE, "ERROR: %08lx", r);
Draw_DrawFormattedString(10, 30, COLOR_RED, failureReason); Draw_DrawFormattedString(10, 30, COLOR_RED, failureReason);
} }
Draw_FlushFramebuffer(); Draw_FlushFramebuffer();

View File

@ -103,7 +103,7 @@ void DebuggerMenu_EnableDebugger(void)
} }
if(res != 0) if(res != 0)
sprintf(buf, "Starting debugger... failed (0x%08x).", (u32)res); sprintf(buf, "Starting debugger... failed (0x%08lx).", (u32)res);
done = true; done = true;
} }
@ -135,7 +135,7 @@ void DebuggerMenu_DisableDebugger(void)
} }
if(res != 0) if(res != 0)
sprintf(buf, "Failed to disable debugger (0x%08x).", (u32)res); sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res);
do do
{ {

View File

@ -78,7 +78,7 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void)
miscellaneousMenu.items[0].title = "Switch the hb. title to hblauncher_loader"; miscellaneousMenu.items[0].title = "Switch the hb. title to hblauncher_loader";
} }
else if(R_FAILED(res)) else if(R_FAILED(res))
sprintf(failureReason, "%08x", (u32)res); sprintf(failureReason, "%08lx", (u32)res);
else else
{ {
res = -1; res = -1;
@ -175,7 +175,7 @@ void MiscellaneousMenu_SaveSettings(void)
IFile file; IFile file;
u64 total; u64 total;
struct PACKED struct PACKED ALIGN(4)
{ {
char magic[4]; char magic[4];
u16 formatVersionMajor, formatVersionMinor; u16 formatVersionMajor, formatVersionMinor;
@ -227,7 +227,7 @@ void MiscellaneousMenu_SaveSettings(void)
if(R_SUCCEEDED(res)) if(R_SUCCEEDED(res))
Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded."); Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded.");
else else
Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08x).", res); Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08lx).", res);
Draw_FlushFramebuffer(); Draw_FlushFramebuffer();
Draw_Unlock(); Draw_Unlock();
} }
@ -252,7 +252,7 @@ void MiscellaneousMenu_InputRedirection(void)
svcCloseHandle(inputRedirectionThreadStartedEvent); svcCloseHandle(inputRedirectionThreadStartedEvent);
if(res != 0) if(res != 0)
sprintf(buf, "Failed to stop InputRedirection (0x%08x).", (u32)res); sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res);
else else
miscellaneousMenu.items[2].title = "Start InputRedirection"; miscellaneousMenu.items[2].title = "Start InputRedirection";
} }
@ -308,7 +308,7 @@ void MiscellaneousMenu_InputRedirection(void)
} }
if(res != 0) if(res != 0)
sprintf(buf, "Starting InputRedirection... failed (0x%08x).", (u32)res); sprintf(buf, "Starting InputRedirection... failed (0x%08lx).", (u32)res);
else else
miscellaneousMenu.items[2].title = "Stop InputRedirection"; miscellaneousMenu.items[2].title = "Stop InputRedirection";

View File

@ -50,7 +50,7 @@ void N3DSMenu_UpdateStatus(void)
svcGetSystemInfo(&L2CacheEnabled, 0x10001, 2); svcGetSystemInfo(&L2CacheEnabled, 0x10001, 2);
N3DSMenu.items[0].title = L2CacheEnabled ? "Disable L2 cache" : "Enable L2 cache"; N3DSMenu.items[0].title = L2CacheEnabled ? "Disable L2 cache" : "Enable L2 cache";
sprintf(clkRateBuf, "Set clock rate to %uMHz", clkRate != 268 ? 268 : (u32)higherClkRate); sprintf(clkRateBuf, "Set clock rate to %luMHz", clkRate != 268 ? 268 : (u32)higherClkRate);
} }
void N3DSMenu_ChangeClockRate(void) void N3DSMenu_ChangeClockRate(void)

View File

@ -73,11 +73,11 @@ static inline int ProcessListMenu_FormatInfoLine(char *out, const ProcessInfo *i
else else
{ {
checkbox = "(W) "; checkbox = "(W) ";
sprintf(commentBuf, "Port: %d", GDB_PORT_BASE + id); sprintf(commentBuf, "Port: %ld", GDB_PORT_BASE + id);
} }
} }
return sprintf(out, "%s%-4u %-8.8s %s", checkbox, info->pid, info->name, commentBuf); // Theoritically PIDs are 32-bit ints, but we'll only justify 4 digits return sprintf(out, "%s%-4lu %-8.8s %s", checkbox, info->pid, info->name, commentBuf); // Theoritically PIDs are 32-bit ints, but we'll only justify 4 digits
} }
static void ProcessListMenu_DumpMemory(const char *name, void *start, u32 size) static void ProcessListMenu_DumpMemory(const char *name, void *start, u32 size)

View File

@ -28,8 +28,8 @@ INCLUDES := include
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
DEFINES := -DARM11 -D_3DS DEFINES := -DARM11 -D_3DS
CFLAGS := -g -std=gnu11 -Wall -Wextra -O2 -mword-relocations \ CFLAGS := -g -std=gnu11 -Wall -Wextra -Werror -O2 -mword-relocations \
-fomit-frame-pointer -ffunction-sections -fdata-sections -fno-builtin \ -fomit-frame-pointer -ffunction-sections -fdata-sections \
$(ARCH) $(DEFINES) $(ARCH) $(DEFINES)
CFLAGS += $(INCLUDE) CFLAGS += $(INCLUDE)

View File

@ -8,7 +8,7 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for
#pragma once #pragma once
#include <3ds.h> #include <3ds.h>
#include "memory.h" #include <string.h>
#define IS_PRE_7X (osGetFirmVersion() < SYSTEM_VERSION(2, 39, 4)) #define IS_PRE_7X (osGetFirmVersion() < SYSTEM_VERSION(2, 39, 4))
#define IS_PRE_93 (osGetFirmVersion() < SYSTEM_VERSION(2, 48, 3)) #define IS_PRE_93 (osGetFirmVersion() < SYSTEM_VERSION(2, 48, 3))

View File

@ -6,7 +6,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for
*/ */
#include "list.h" #include "list.h"
#include "memory.h"
#include "common.h" #include "common.h"
struct ListBase; struct ListBase;

View File

@ -6,7 +6,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for
*/ */
#include "common.h" #include "common.h"
#include "memory.h"
#include "services.h" #include "services.h"
#include "processes.h" #include "processes.h"
#include "srv.h" #include "srv.h"

View File

@ -1,27 +0,0 @@
/*
memory.c
(c) TuxSH, 2017
This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for details).
*/
#include "memory.h"
/*
//Adpated from CakesFW
void memcpy(void *dest, const void *src, u32 size)
{
u8 *destc = (u8 *)dest;
const u8 *srcc = (const u8 *)src;
for(u32 i = 0; i < size; i++)
destc[i] = srcc[i];
}*/
s32 strnlen(const char *string, s32 maxlen)
{
s32 size;
for(size = 0; size < maxlen && *string; string++, size++);
return size;
}

View File

@ -1,18 +0,0 @@
/*
memory.h
(c) TuxSH, 2017
This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for details).
*/
#pragma once
#include <3ds/types.h>
//void memcpy(void *dest, const void *src, u32 size);
#define memcpy __builtin_memcpy
#define memset __builtin_memset
#define strncmp __builtin_strncmp
#define strncpy __builtin_strncpy
s32 strnlen(const char *string, s32 maxlen);

View File

@ -5,9 +5,9 @@ services.c
This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for details). This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for details).
*/ */
#include "common.h"
#include "services.h" #include "services.h"
#include "processes.h" #include "processes.h"
#include "memory.h"
#include "list.h" #include "list.h"
ServiceInfo servicesInfo[0xA0] = { 0 }; ServiceInfo servicesInfo[0xA0] = { 0 };
@ -17,7 +17,7 @@ static Result checkServiceName(const char *name, s32 nameSize)
{ {
if(nameSize <= 0 || nameSize > 8) if(nameSize <= 0 || nameSize > 8)
return 0xD9006405; return 0xD9006405;
else if(strnlen(name, nameSize) < nameSize) else if(strnlen(name, nameSize) < (size_t)nameSize)
return 0xD9006407; return 0xD9006407;
else else
return 0; return 0;