From cf2ba24d69f3cae1f06e91ea62fc7c2798e69c0f Mon Sep 17 00:00:00 2001 From: Yifan Lu Date: Thu, 24 Mar 2016 17:48:14 -0500 Subject: [PATCH] Added support for disabling padding between segments for code Fixed potential bug where code size is calculated by taking the page size of combined segments rather than the combined padded segment size. This could be a problem, for example, if two segments add up to require two pages of padding. Fixed potential bug where memory-size is used for codeDetails.rwSize; this counts .bss which is not in the file --- makerom/code.c | 21 ++++++++++++++------- makerom/ncch.c | 1 + makerom/ncch_build.h | 1 + makerom/user_settings.c | 10 ++++++++++ makerom/user_settings.h | 1 + 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/makerom/code.c b/makerom/code.c index 1112447..e7d60c4 100644 --- a/makerom/code.c +++ b/makerom/code.c @@ -173,13 +173,20 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set) set->codeDetails.bssSize = rwdata.memSize - rwdata.fileSize; /* Allocating Buffer for ExeFs Code */ - u32 size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum); + bool noCodePadding = set->options.noCodePadding; + u32 size; + if (noCodePadding) { + size = text.fileSize + rodata.fileSize + rwdata.fileSize; + } + else { + size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum); + } u8 *code = calloc(1, size); /* Writing Code into Buffer */ - u8 *textPos = (code + PageToSize(0)); - u8 *rodataPos = (code + PageToSize(text.pageNum)); - u8 *rwdataPos = (code + PageToSize(text.pageNum + rodata.pageNum)); + u8 *textPos = code; + u8 *rodataPos = (textPos + (noCodePadding ? text.fileSize : PageToSize(text.pageNum))); + u8 *rwdataPos = (rodataPos + (noCodePadding ? rodata.fileSize : PageToSize(rodata.pageNum))); if (text.fileSize) memcpy(textPos, text.data, text.fileSize); if (rodata.fileSize) memcpy(rodataPos, rodata.data, rodata.fileSize); if (rwdata.fileSize) memcpy(rwdataPos, rwdata.data, rwdata.fileSize); @@ -204,15 +211,15 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set) /* Setting code_segment data and freeing original buffers */ set->codeDetails.textAddress = text.address; set->codeDetails.textMaxPages = text.pageNum; - set->codeDetails.textSize = text.memSize; + set->codeDetails.textSize = text.fileSize; set->codeDetails.roAddress = rodata.address; set->codeDetails.roMaxPages = rodata.pageNum; - set->codeDetails.roSize = rodata.memSize; + set->codeDetails.roSize = rodata.fileSize; set->codeDetails.rwAddress = rwdata.address; set->codeDetails.rwMaxPages = rwdata.pageNum; - set->codeDetails.rwSize = rwdata.memSize; + set->codeDetails.rwSize = rwdata.fileSize; if (set->rsfSet->SystemControlInfo.StackSize) set->codeDetails.stackSize = strtoul(set->rsfSet->SystemControlInfo.StackSize, NULL, 0); diff --git a/makerom/ncch.c b/makerom/ncch.c index e8d6412..ccc2e3c 100644 --- a/makerom/ncch.c +++ b/makerom/ncch.c @@ -177,6 +177,7 @@ int GetBasicOptions(ncch_settings *ncchset, user_settings *usrset) ncchset->options.IsCfa = (usrset->ncch.ncchType == CFA); ncchset->options.IsBuildingCodeSection = (usrset->ncch.elfPath != NULL); ncchset->options.UseRomFS = ((ncchset->rsfSet->RomFs.RootPath && strlen(ncchset->rsfSet->RomFs.RootPath) > 0) || usrset->ncch.romfsPath); + ncchset->options.noCodePadding = usrset->ncch.noCodePadding; ncchset->options.useSecCrypto = usrset->ncch.useSecCrypto; ncchset->options.keyXID = usrset->ncch.keyXID; diff --git a/makerom/ncch_build.h b/makerom/ncch_build.h index d97ab7b..7aa9095 100644 --- a/makerom/ncch_build.h +++ b/makerom/ncch_build.h @@ -19,6 +19,7 @@ typedef struct bool IsCfa; bool IsBuildingCodeSection; bool UseRomFS; + bool noCodePadding; bool useSecCrypto; u8 keyXID; diff --git a/makerom/user_settings.c b/makerom/user_settings.c index 3702316..f1a864e 100644 --- a/makerom/user_settings.c +++ b/makerom/user_settings.c @@ -92,6 +92,7 @@ void SetDefaults(user_settings *set) set->ncch.includeExefsLogo = false; set->common.outFormat = NCCH; set->ncch.ncchType = format_not_set; + set->ncch.noCodePadding = false; // RSF Settings clrmem(&set->common.rsfSet, sizeof(rsf_settings)); @@ -352,6 +353,14 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) set->ncch.ncchType |= CFA; return 1; } + else if (strcmp(argv[i], "-nocodepadding") == 0) { + if (ParamNum) { + PrintNoNeedParam(argv[i]); + return USR_BAD_ARG; + } + set->ncch.noCodePadding = true; + return 1; + } // Ncch Rebuild Options else if (strcmp(argv[i], "-code") == 0) { @@ -941,6 +950,7 @@ void DisplayExtendedHelp(char *app_name) printf(" -logo Logo file (Overrides \"BasicInfo/Logo\" in RSF)\n"); printf(" -desc : Specify Access Descriptor template\n"); printf(" -exefslogo Include Logo in ExeFS (Required for usage on <5.0 systems)\n"); + printf(" -nocodepadding For building sysmodules, do not pad .code segments\n"); printf("NCCH REBUILD OPTIONS:\n"); printf(" -code Decompressed ExeFS \".code\"\n"); printf(" -exheader Exheader template\n"); diff --git a/makerom/user_settings.h b/makerom/user_settings.h index ea0f008..ba6af79 100644 --- a/makerom/user_settings.h +++ b/makerom/user_settings.h @@ -267,6 +267,7 @@ typedef struct char *exheaderPath; // for .code details char *plainRegionPath; // prebuilt Plain Region char *romfsPath; // Prebuild _cleartext_ romfs binary + bool noCodePadding; // do not pad code.bin for sysmodule bool useSecCrypto; u8 keyXID;