diff --git a/makerom/src/code.c b/makerom/src/code.c index 15386c4..fd11df4 100644 --- a/makerom/src/code.c +++ b/makerom/src/code.c @@ -6,8 +6,7 @@ #include -const u32 CTR_PAGE_SIZE = 0x1000; -const u32 DEFAULT_STACK_SIZE = 0x4000; // 10KB +static const u32 DEFAULT_STACK_SIZE = 0x4000; // 10KB typedef struct code_segment { @@ -18,14 +17,14 @@ typedef struct code_segment const u8 *data; } code_segment; -u32 SizeToPage(u32 memorySize) +u32 SizeToPage(u32 memorySize, u32 pageSize) { - return align(memorySize, CTR_PAGE_SIZE) / CTR_PAGE_SIZE; + return align(memorySize, pageSize) / pageSize; } -u32 PageToSize(u32 pageNum) +u32 PageToSize(u32 pageNum, u32 pageSize) { - return pageNum * CTR_PAGE_SIZE; + return pageNum * pageSize; } int ImportPlainRegionFromFile(ncch_settings *set) @@ -123,10 +122,11 @@ int ImportPlainRegionFromElf(elf_context *elf, ncch_settings *set) return 0; } -void CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_flags) +void CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_flags, u32 pageSize, bool baremetal, u32 baremetalOrder) { u32 segmentNum = elf_SegmentNum(elf); const elf_segment *segments = elf_GetSegments(elf); + u16 foundSegmentId = segmentNum; /* Initialise struct data */ out->address = 0; @@ -135,24 +135,42 @@ void CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_f out->fileSize = 0; out->data = NULL; - /* Find segment */ - for (u16 i = 0; i < segmentNum; i++) { - /* Skip SDK ELF .module_id segment - The last segment should always be data in valid ELFs, - unless this is an SDK ELF with .module_id segment */ - if (i == segmentNum-1 && segments[i].flags == PF_RODATA) - continue; - - /* Found segment */ - if ((segments[i].flags & ~PF_CTRSDK) == segment_flags && segments[i].type == PT_LOAD) { - out->address = segments[i].vAddr; - out->memSize = segments[i].memSize; - out->fileSize = segments[i].fileSize; - out->pageNum = SizeToPage(out->fileSize); - out->data = segments[i].ptr; - break; + if (baremetal) { + /* With Kernel9 and with LGY firm K11, everything is RWX with no memory management. + While it is a bit hard to replicate what Nintendo do with their toolchain, we can + abuse how these kernels work and remove meaning from "text segment" etc. + + The other option would be to add support for multiple phdr per "section" and allow + for RWX phdrs (and perhaps parse phdr list from .rsf), plus read LMA instead of VMA below, + but that's a lot more work compared to this dirty workaround. + + First segment defines entrypoint and LMA for the rest of the image.*/ + if (baremetalOrder < segmentNum && (segments[baremetalOrder].flags & segment_flags) == segment_flags && segments[baremetalOrder].type == PT_LOAD) + foundSegmentId = baremetalOrder; + } else { + /* Find segment */ + for (u16 i = 0; i < segmentNum; i++) { + /* Skip SDK ELF .module_id segment + The last segment should always be data in valid ELFs, + unless this is an SDK ELF with .module_id segment */ + if (i == segmentNum-1 && segments[i].flags == PF_RODATA) + continue; + + /* Found segment */ + if ((segments[i].flags & ~PF_CTRSDK) == segment_flags && segments[i].type == PT_LOAD) { + foundSegmentId = i; + break; + } } } + + if (foundSegmentId < segmentNum) { + out->address = segments[foundSegmentId].vAddr; + out->memSize = segments[foundSegmentId].memSize; + out->fileSize = segments[foundSegmentId].fileSize; + out->pageNum = SizeToPage(out->fileSize, pageSize); + out->data = segments[foundSegmentId].ptr; + } } int CreateExeFsCode(elf_context *elf, ncch_settings *set) @@ -162,28 +180,30 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set) code_segment rodata; code_segment rwdata; - CreateCodeSegmentFromElf(&text, elf, PF_TEXT); - CreateCodeSegmentFromElf(&rodata, elf, PF_RODATA); - CreateCodeSegmentFromElf(&rwdata, elf, PF_DATA); + bool baremetal = set->options.baremetal; + u32 pageSize = set->options.pageSize; + CreateCodeSegmentFromElf(&text, elf, PF_TEXT, pageSize, baremetal, 0); + CreateCodeSegmentFromElf(&rodata, elf, PF_RODATA, pageSize, baremetal, 1); + CreateCodeSegmentFromElf(&rwdata, elf, PF_DATA, pageSize, baremetal, 2); /* Checking the existence of essential ELF Segments */ if (!text.fileSize) return NOT_FIND_TEXT_SEGMENT; /* Allocating Buffer for ExeFs Code */ - bool noCodePadding = set->options.noCodePadding; + bool noCodePadding = set->options.noCodePadding || baremetal; u32 size; if (noCodePadding) { size = text.fileSize + rodata.fileSize + rwdata.fileSize; } else { - size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum); + size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum, pageSize); } u8 *code = calloc(1, size); /* Writing Code into Buffer */ u8 *textPos = code; - u8 *rodataPos = (textPos + (noCodePadding ? text.fileSize : PageToSize(text.pageNum))); - u8 *rwdataPos = (rodataPos + (noCodePadding ? rodata.fileSize : PageToSize(rodata.pageNum))); + u8 *rodataPos = (textPos + (noCodePadding ? text.fileSize : PageToSize(text.pageNum, pageSize))); + u8 *rwdataPos = (rodataPos + (noCodePadding ? rodata.fileSize : PageToSize(rodata.pageNum, pageSize))); 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); @@ -219,7 +239,7 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set) set->codeDetails.rwSize = rwdata.fileSize; /* Calculating BSS size */ - if (rwdata.fileSize) { + if (rwdata.fileSize && !baremetal) { set->codeDetails.bssSize = rwdata.memSize - rwdata.fileSize; } else { @@ -313,7 +333,7 @@ int BuildExeFsCode(ncch_settings *set) default: fprintf(stderr, "[CODE ERROR] Failed to process ELF file (%d)\n", result); } - + elf_Free(&elf); free(elfFile); return result; diff --git a/makerom/src/exheader.c b/makerom/src/exheader.c index f84f098..a4c264d 100644 --- a/makerom/src/exheader.c +++ b/makerom/src/exheader.c @@ -78,7 +78,7 @@ int BuildExHeader(ncch_settings *ncchset) exheader_settings *exhdrset = calloc(1,sizeof(exheader_settings)); if(!exhdrset) { - fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); + fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); return MEM_ERROR; } @@ -114,14 +114,14 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings * ncchset->sections.exhdr.size = sizeof(extended_hdr); ncchset->sections.exhdr.buffer = calloc(1,ncchset->sections.exhdr.size); if(!ncchset->sections.exhdr.buffer) { - fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); + fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); return MEM_ERROR; } - + ncchset->sections.acexDesc.size = sizeof(access_descriptor); ncchset->sections.acexDesc.buffer = calloc(1,ncchset->sections.acexDesc.size); if(!ncchset->sections.acexDesc.buffer) { - fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); + fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); return MEM_ERROR; } @@ -161,27 +161,27 @@ int get_ExHeaderSettingsFromRsf(exheader_settings *exhdrset) { int result = 0; if(!exhdrset->useAccessDescPreset){ - if((result = get_ExHeaderCodeSetInfo(&exhdrset->exHdr->codeSetInfo, exhdrset->rsf))) + if((result = get_ExHeaderCodeSetInfo(&exhdrset->exHdr->codeSetInfo, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderDependencyList((u8*)exhdrset->exHdr->dependencyList, exhdrset->rsf))) + if((result = get_ExHeaderDependencyList((u8*)exhdrset->exHdr->dependencyList, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderSystemInfo(&exhdrset->exHdr->systemInfo, exhdrset->rsf))) + if((result = get_ExHeaderSystemInfo(&exhdrset->exHdr->systemInfo, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderARM11SystemLocalInfo(&exhdrset->exHdr->arm11SystemLocalCapabilities, exhdrset->rsf))) + if((result = get_ExHeaderARM11SystemLocalInfo(&exhdrset->exHdr->arm11SystemLocalCapabilities, exhdrset->rsf))) goto finish; if((result = get_ExHeaderARM11KernelInfo(&exhdrset->exHdr->arm11KernelCapabilities, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderARM9AccessControlInfo(&exhdrset->exHdr->arm9AccessControlInfo, exhdrset->rsf))) + if((result = get_ExHeaderARM9AccessControlInfo(&exhdrset->exHdr->arm9AccessControlInfo, exhdrset->rsf))) goto finish; } else{ - if((result = get_ExHeaderCodeSetInfo(&exhdrset->exHdr->codeSetInfo, exhdrset->rsf))) + if((result = get_ExHeaderCodeSetInfo(&exhdrset->exHdr->codeSetInfo, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderSystemInfo(&exhdrset->exHdr->systemInfo, exhdrset->rsf))) + if((result = get_ExHeaderSystemInfo(&exhdrset->exHdr->systemInfo, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderARM11SystemLocalInfoLimited(&exhdrset->exHdr->arm11SystemLocalCapabilities, exhdrset->rsf))) + if((result = get_ExHeaderARM11SystemLocalInfoLimited(&exhdrset->exHdr->arm11SystemLocalCapabilities, exhdrset->rsf))) goto finish; - if((result = get_ExHeaderARM9AccessControlInfo(&exhdrset->exHdr->arm9AccessControlInfo, exhdrset->rsf))) + if((result = get_ExHeaderARM9AccessControlInfo(&exhdrset->exHdr->arm9AccessControlInfo, exhdrset->rsf))) goto finish; } @@ -196,13 +196,13 @@ int get_ExHeaderCodeSetInfo(exhdr_CodeSetInfo *CodeSetInfo, rsf_settings *rsf) strncpy((char*)CodeSetInfo->name, rsf->BasicInfo.Title, 8); else strncpy((char*)CodeSetInfo->name, DEFAULT_EXHEADER_NAME, 8); - + /* Remaster Version */ if(rsf->SystemControlInfo.RemasterVersion) u16_to_u8(CodeSetInfo->remasterVersion, strtol(rsf->SystemControlInfo.RemasterVersion,NULL,0), LE); else u16_to_u8(CodeSetInfo->remasterVersion, 0, LE); - + return 0; } @@ -224,20 +224,20 @@ int get_ExHeaderSystemInfo(exhdr_SystemInfo *systemInfo, rsf_settings *rsf) /* SaveDataSize */ if(rsf->SystemControlInfo.SaveDataSize){ u64 saveSize = 0; - if(GetSaveDataSizeFromString(&saveSize,rsf->SystemControlInfo.SaveDataSize,"EXHEADER")) + if(GetSaveDataSizeFromString(&saveSize,rsf->SystemControlInfo.SaveDataSize,"EXHEADER")) return EXHDR_BAD_RSF_OPT; u64_to_u8(systemInfo->savedataSize, saveSize, LE); } else u64_to_u8(systemInfo->savedataSize,0,LE); - + /* Jump Id */ if(rsf->SystemControlInfo.JumpId) u64_to_u8(systemInfo->jumpId, strtoull(rsf->SystemControlInfo.JumpId,NULL,0), LE); - + else{ u64 jumpId = 0; - if(GetProgramID(&jumpId,rsf,false)) + if(GetProgramID(&jumpId,rsf,false)) return EXHDR_BAD_RSF_OPT; u64_to_u8(systemInfo->jumpId,jumpId,LE); } @@ -248,20 +248,20 @@ int get_ExHeaderARM11SystemLocalInfo(exhdr_ARM11SystemLocalCapabilities *arm11, { /* Program Id */ u64 programId = 0; - if(GetProgramID(&programId,rsf,true)) + if(GetProgramID(&programId,rsf,true)) return EXHDR_BAD_RSF_OPT; u64_to_u8(arm11->programId,programId,LE); - + /* Flags */ - if(SetARM11SystemLocalInfoFlags(arm11, rsf)) + if(SetARM11SystemLocalInfoFlags(arm11, rsf)) return EXHDR_BAD_RSF_OPT; /* Resource Limit Descriptors */ - if(SetARM11ResLimitDesc(arm11, rsf)) + if(SetARM11ResLimitDesc(arm11, rsf)) return EXHDR_BAD_RSF_OPT; /* Storage Info */ - if(SetARM11StorageInfo(arm11, rsf)) + if(SetARM11StorageInfo(arm11, rsf)) return EXHDR_BAD_RSF_OPT; /* Service Access Control */ @@ -275,7 +275,7 @@ int get_ExHeaderARM11SystemLocalInfo(exhdr_ARM11SystemLocalCapabilities *arm11, else if(strcasecmp(rsf->AccessControlInfo.ResourceLimitCategory,"libapplet") == 0) arm11->resourceLimitCategory = resrc_limit_LIB_APPLET; else if(strcasecmp(rsf->AccessControlInfo.ResourceLimitCategory,"other") == 0) arm11->resourceLimitCategory = resrc_limit_OTHER; } - + /* Finish */ return 0; } @@ -284,12 +284,12 @@ int get_ExHeaderARM11SystemLocalInfoLimited(exhdr_ARM11SystemLocalCapabilities * { /* Program Id */ u64 programId = 0; - if(GetProgramID(&programId,rsf,true)) + if(GetProgramID(&programId,rsf,true)) return EXHDR_BAD_RSF_OPT; u64_to_u8(arm11->programId,programId,LE); /* Storage Info */ - if(SetARM11StorageInfo(arm11, rsf)) + if(SetARM11StorageInfo(arm11, rsf)) return EXHDR_BAD_RSF_OPT; /* Finish */ @@ -336,12 +336,12 @@ int SetARM11SystemLocalInfoFlags(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_ arm11->systemModeExt = sysmode_ext_124MB; else if (strcasecmp(rsf->AccessControlInfo.SystemModeExt, "178MB") == 0) arm11->systemModeExt = sysmode_ext_178MB; - + else { fprintf(stderr, "[EXHEADER ERROR] Unexpected SystemModeExt: %s\n", rsf->AccessControlInfo.SystemModeExt); return EXHDR_BAD_RSF_OPT; } - } + } /* flag[2] */ if(rsf->AccessControlInfo.AffinityMask){ @@ -397,11 +397,11 @@ int SetARM11SystemLocalInfoFlags(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_ } int GetAppType(rsf_settings *rsf) -{ +{ if(rsf->SystemControlInfo.AppType){ - if(strcasecmp(rsf->SystemControlInfo.AppType,"application") == 0) + if(strcasecmp(rsf->SystemControlInfo.AppType,"application") == 0) return processtype_APPLICATION; - else if(strcasecmp(rsf->SystemControlInfo.AppType,"system") == 0) + else if(strcasecmp(rsf->SystemControlInfo.AppType,"system") == 0) return processtype_SYSTEM; } return processtype_APPLICATION; @@ -418,7 +418,7 @@ int SetARM11ResLimitDesc(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_settings } } } - + return 0; } @@ -438,10 +438,10 @@ int SetARM11StorageInfo(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_settings } /* System Savedata Id */ - SetARM11StorageInfoSystemSaveDataId(arm11,rsf); + SetARM11StorageInfoSystemSaveDataId(arm11,rsf); /* FileSystem Access Info */ - return SetARM11StorageInfoFsAccessInfo(arm11,rsf); + return SetARM11StorageInfoFsAccessInfo(arm11,rsf); } int SetARM11StorageInfoFsAccessInfo(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_settings *rsf) @@ -498,7 +498,7 @@ int SetARM11StorageInfoFsAccessInfo(exhdr_ARM11SystemLocalCapabilities *arm11, r } } u32_to_u8(arm11->storageInfo.accessInfo,accessInfo,LE); - + return 0; } @@ -506,7 +506,7 @@ void SetARM11StorageInfoSystemSaveDataId(exhdr_ARM11SystemLocalCapabilities *arm { if(rsf->AccessControlInfo.SystemSaveDataId1) u32_to_u8(arm11->storageInfo.systemSavedataId[0], strtoul(rsf->AccessControlInfo.SystemSaveDataId1,NULL,0), LE); - + if(rsf->AccessControlInfo.SystemSaveDataId2) u32_to_u8(arm11->storageInfo.systemSavedataId[1], strtoul(rsf->AccessControlInfo.SystemSaveDataId2,NULL,0), LE); } @@ -519,12 +519,12 @@ void SetARM11StorageInfoExtSaveDataId(exhdr_ARM11SystemLocalCapabilities *arm11, else u32_to_u8(arm11->storageInfo.extSavedataId, GetTidUniqueId(u8_to_u64(arm11->programId,LE)), LE); } - + } void SetARM11StorageInfoOtherUserSaveData(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_settings *rsf) { - u64 value = 0; + u64 value = 0; if(rsf->AccessControlInfo.OtherUserSaveDataId1) value = 0xffffff & strtoul(rsf->AccessControlInfo.OtherUserSaveDataId1,NULL,0); value = value << 20; @@ -537,7 +537,7 @@ void SetARM11StorageInfoOtherUserSaveData(exhdr_ARM11SystemLocalCapabilities *ar /* UseOtherVariationSaveData Flag */ if(rsf->AccessControlInfo.UseOtherVariationSaveData) value |= 0x1000000000000000; - + u64_to_u8(arm11->storageInfo.storageAccessableUniqueIds,value,LE); } @@ -647,13 +647,13 @@ int get_ExHeaderARM11KernelInfo(exhdr_ARM11KernelCapabilities *arm11, rsf_settin totalDesc = 0; for(int i = 0; i < 6; i++) totalDesc += desc[i].num; - + if(totalDesc >= 28){ fprintf(stderr,"[EXHEADER ERROR] Too many Kernel Capabilities.\n"); result = EXHDR_BAD_RSF_OPT; goto finish; } - + descIndex = 0; for(int i = 0; i < 6; i++){ for(int j = 0; j < desc[i].num; j++){ @@ -662,7 +662,7 @@ int get_ExHeaderARM11KernelInfo(exhdr_ARM11KernelCapabilities *arm11, rsf_settin } } - /* Fill Remaining Descriptors with 0xffffffff */ + /* Fill Remaining Descriptors with 0xffffffff */ for(int i = descIndex; i < 28; i++) u32_to_u8(arm11->descriptors[i],0xffffffff,LE); @@ -692,9 +692,9 @@ int SetARM11KernelDescSysCallControl(ARM11KernelCapabilityDescriptor *desc, rsf_ // Count Active Syscall Descs activeSysCallDesc = 0; for(int i = 0; i < 8; i++) - if((tmp.data[i] & 0x00ffffff) != 0) + if((tmp.data[i] & 0x00ffffff) != 0) activeSysCallDesc++; - + // Transfer Active Syscall Descs to out Descriptor AllocateARM11KernelDescMemory(desc,activeSysCallDesc); sysCallDescPos = 0; @@ -744,15 +744,15 @@ void DisableSystemCall(ARM11KernelCapabilityDescriptor *desc, int sysCall) } int SetARM11KernelDescInteruptNumList(ARM11KernelCapabilityDescriptor *desc, rsf_settings *rsf) -{ +{ int ret = 0; u16 activeInteruptDesc, interuptDescPos; - + // Create Temporary Descriptor ARM11KernelCapabilityDescriptor tmp; memset(&tmp,0,sizeof(ARM11KernelCapabilityDescriptor)); - AllocateARM11KernelDescMemory(&tmp,8); + AllocateARM11KernelDescMemory(&tmp, 80/4); // Get Interupts ret = GetARM11Interupts(&tmp,rsf); @@ -760,14 +760,14 @@ int SetARM11KernelDescInteruptNumList(ARM11KernelCapabilityDescriptor *desc, rsf // Count Active Interupt Descs activeInteruptDesc = 0; - for(int i = 0; i < 8; i++) - if(tmp.data[i]) + for(int i = 0; i < 80/4; i++) + if(tmp.data[i]) activeInteruptDesc++; - + // Transfer Active Interupt Descs to output Descriptor AllocateARM11KernelDescMemory(desc,activeInteruptDesc); interuptDescPos = 0; - for(int i = 0; i < 8; i++){ + for(int i = 0; i < 80/4; i++){ if(tmp.data[i]) { SetARM11KernelDescValue(desc,interuptDescPos,(tmp.data[i] & 0x0fffffff) | desc_InteruptNumList); interuptDescPos++; @@ -784,9 +784,10 @@ int GetARM11Interupts(ARM11KernelCapabilityDescriptor *desc, rsf_settings *rsf) { if(!rsf->AccessControlInfo.InterruptNumbers) return 0; - - if(rsf->AccessControlInfo.InterruptNumbersNum > 32){ - fprintf(stderr,"[EXHEADER ERROR] Too many Interupts. Maximum is 32\n"); + + if(rsf->AccessControlInfo.InterruptNumbersNum > 80){ + // There are between 80 and 88 valid PPIs on 3DS, and a dozen of them are reserved by kernel (CDMA) + fprintf(stderr,"[EXHEADER ERROR] Too many Interupts. Maximum is 80\n"); return EXHDR_BAD_RSF_OPT; } for(int i = 0; i < rsf->AccessControlInfo.InterruptNumbersNum; i++){ @@ -813,7 +814,7 @@ int SetARM11KernelDescAddressMapping(ARM11KernelCapabilityDescriptor *desc, rsf_ { int ret = 0; u16 memMapDescPos; - + // Create Temporary Descriptors ARM11KernelCapabilityDescriptor io_tmp; clrmem(&io_tmp,sizeof(ARM11KernelCapabilityDescriptor)); @@ -851,10 +852,10 @@ int GetARM11IOMappings(ARM11KernelCapabilityDescriptor *desc, rsf_settings *rsf) { if(!rsf->AccessControlInfo.IORegisterMapping) return 0; - + AllocateARM11KernelDescMemory(desc,rsf->AccessControlInfo.IORegisterMappingNum*2); u16 descUsed = 0; - + for(int i = 0; i < rsf->AccessControlInfo.IORegisterMappingNum; i++){ if(strlen(rsf->AccessControlInfo.IORegisterMapping[i])){ // Parse Address String @@ -863,7 +864,7 @@ int GetARM11IOMappings(ARM11KernelCapabilityDescriptor *desc, rsf_settings *rsf) if(AddressEndStr){ if(strlen(AddressEndStr) > 1) // if not just '-' AddressEndStr = (AddressEndStr+1); // Setting the str to the expected start of address string - else + else AddressEndStr = NULL; } @@ -916,7 +917,7 @@ int GetARM11StaticMappings(ARM11KernelCapabilityDescriptor *desc, rsf_settings * char *AddressStartStr = rsf->AccessControlInfo.MemoryMapping[i]; char *AddressEndStr = strstr(AddressStartStr,"-"); char *ROFlagStr = strstr(AddressStartStr,":"); - bool IsRO = false; + bool IsRO = false; if(ROFlagStr) IsRO = strcasecmp(ROFlagStr,":r") == 0 ? true : false; @@ -926,7 +927,7 @@ int GetARM11StaticMappings(ARM11KernelCapabilityDescriptor *desc, rsf_settings * if(AddressEndStr == ROFlagStr) AddressEndStr = NULL; } - else + else AddressEndStr = NULL; } u32 AddressStart = strtoul(AddressStartStr,NULL,16); @@ -1000,8 +1001,8 @@ u32 GetMappingDesc(u32 address, u32 prefixVal, s32 numPrefixBits, bool IsRO) int SetARM11KernelDescOtherCapabilities(ARM11KernelCapabilityDescriptor *desc, rsf_settings *rsf) { u32 otherCapabilities = 0; - u32 memType = 0; - + u32 memType = 0; + if(!rsf->AccessControlInfo.DisableDebug) otherCapabilities |= othcap_PERMIT_DEBUG; if(rsf->AccessControlInfo.EnableForceDebug) @@ -1060,7 +1061,7 @@ int SetARM11KernelDescHandleTableSize(ARM11KernelCapabilityDescriptor *desc, rsf else{ ErrorParamNotFound("AccessControlInfo/HandleTableSize"); return EXHDR_BAD_RSF_OPT; - } + } return 0; } @@ -1082,7 +1083,7 @@ int SetARM11KernelDescReleaseKernelVersion(ARM11KernelCapabilityDescriptor *desc void SetARM11KernelDescValue(ARM11KernelCapabilityDescriptor *desc, u16 index, u32 value) { if(index >= desc->num) return; - desc->data[index] |= value; + desc->data[index] |= value; } void SetARM11KernelDescBitmask(ARM11KernelCapabilityDescriptor *desc, u32 bitmask) @@ -1135,7 +1136,7 @@ int get_ExHeaderARM9AccessControlInfo(exhdr_ARM9AccessControlInfo *arm9, rsf_set return EXHDR_BAD_RSF_OPT; } } - + for(int i = 0; i < rsf->AccessControlInfo.FileSystemAccessNum; i++){ if(strcmp(rsf->AccessControlInfo.FileSystemAccess[i],"DirectSdmc") == 0) arm9AccessControl |= arm9cap_USE_DIRECT_SDMC; @@ -1209,7 +1210,7 @@ int GetDependencyList_frm_exhdr(u8 *Dest, extended_hdr *hdr) { if(!Dest) return -1; memcpy(Dest,hdr->dependencyList,0x30*8); - + return 0; } @@ -1260,7 +1261,7 @@ int GetSaveDataSizeFromString(u64 *out, char *string, char *moduleName) } int GetSaveDataSize_rsf(u64 *SaveDataSize, user_settings *usrset) -{ +{ if(usrset->common.rsfSet.SystemControlInfo.SaveDataSize){ *SaveDataSize = strtoull(usrset->common.rsfSet.SystemControlInfo.SaveDataSize,NULL,10); diff --git a/makerom/src/ncch.c b/makerom/src/ncch.c index 8207e97..6fcd1cf 100644 --- a/makerom/src/ncch.c +++ b/makerom/src/ncch.c @@ -238,6 +238,8 @@ int GetBasicOptions(ncch_settings *ncchset, user_settings *usrset) 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.baremetal = usrset->ncch.baremetal; + ncchset->options.pageSize = usrset->ncch.pageSize; ncchset->options.useSecCrypto = usrset->ncch.useSecCrypto; ncchset->options.keyXID = usrset->ncch.keyXID; @@ -878,7 +880,6 @@ int VerifyNcch(u8 *ncch, keys_struct *keys, bool CheckHash, bool SuppressOutput) if(!acexDesc){ fprintf(stderr,"[NCCH ERROR] Not enough memory\n"); free(ncchInfo); - free(exHdr); return MEM_ERROR; } memcpy(acexDesc,ncch+ncchInfo->acexOffset,ncchInfo->acexSize); @@ -1198,4 +1199,4 @@ void CryptNcchRegion(u8 *buffer, u64 size, u64 src_pos, u64 titleId, u8 key[16], GetNcchAesCounter(ctr,titleId,type); AesCtrCrypt(key,ctr,buffer,buffer,size,src_pos); return; -} \ No newline at end of file +} diff --git a/makerom/src/ncch_build.h b/makerom/src/ncch_build.h index 7aa9095..a8f8a8a 100644 --- a/makerom/src/ncch_build.h +++ b/makerom/src/ncch_build.h @@ -10,6 +10,7 @@ typedef struct struct { u32 blockSize; + u32 pageSize; bool verbose; bool IncludeExeFsLogo; bool CompressCode; @@ -20,7 +21,8 @@ typedef struct bool IsBuildingCodeSection; bool UseRomFS; bool noCodePadding; - + bool baremetal; + bool useSecCrypto; u8 keyXID; } options; @@ -87,4 +89,4 @@ typedef struct } ncch_settings; // NCCH Build Functions -int build_NCCH(user_settings *usrset); \ No newline at end of file +int build_NCCH(user_settings *usrset); diff --git a/makerom/src/user_settings.c b/makerom/src/user_settings.c index 1192270..c3f9425 100644 --- a/makerom/src/user_settings.c +++ b/makerom/src/user_settings.c @@ -95,6 +95,7 @@ void SetDefaults(user_settings *set) set->common.outFormat = NCCH; set->ncch.ncchType = format_not_set; set->ncch.noCodePadding = false; + set->ncch.pageSize = 0x1000; // RSF Settings clrmem(&set->common.rsfSet, sizeof(rsf_settings)); @@ -363,6 +364,22 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) set->ncch.noCodePadding = true; return 1; } + else if (strcmp(argv[i], "-baremetal") == 0) { + if (ParamNum) { + PrintNoNeedParam(argv[i]); + return USR_BAD_ARG; + } + set->ncch.baremetal = true; + return 1; + } else if (strcmp(argv[i], "-pagesize") == 0) { + if (ParamNum != 1) { + PrintArgReqParam(argv[i], 1); + return USR_BAD_ARG; + } + u32 pgsz = strtoul(argv[i + 1], NULL, 0); + set->ncch.pageSize = pgsz; + return 2; + } // Ncch Rebuild Options else if (strcmp(argv[i], "-code") == 0) { @@ -1006,4 +1023,4 @@ void DisplayExtendedHelp(char *app_name) printf(" -ccitocia Convert CCI to CIA\n"); printf(" -ciatocci Convert CIA to CCI\n"); printf(" -inclupd Include \"Update NCCH\" in CCI to CIA conversion\n"); -} \ No newline at end of file +} diff --git a/makerom/src/user_settings.h b/makerom/src/user_settings.h index e09ec50..7f8d6d2 100644 --- a/makerom/src/user_settings.h +++ b/makerom/src/user_settings.h @@ -268,7 +268,8 @@ typedef struct char *plainRegionPath; // prebuilt Plain Region char *romfsPath; // Prebuild _cleartext_ romfs binary bool noCodePadding; // do not pad code.bin for sysmodule - + bool baremetal; // abuse K9/LGY K11's lack of memory management to support arbitrary VMA and RWX phdr + u32 pageSize; // Memory page size (256 for Kernel9, 4096 for anything else) bool useSecCrypto; u8 keyXID; } ncch; // Ncch0 Build @@ -305,4 +306,4 @@ typedef struct void init_UserSettings(user_settings *set); void free_UserSettings(user_settings *set); -int ParseArgs(int argc, char *argv[], user_settings *usr_settings); \ No newline at end of file +int ParseArgs(int argc, char *argv[], user_settings *usr_settings);