diff --git a/makerom/accessdesc.c b/makerom/accessdesc.c
index fcb17be..dde1b58 100644
--- a/makerom/accessdesc.c
+++ b/makerom/accessdesc.c
@@ -44,12 +44,10 @@ int accessdesc_SignWithKey(exheader_settings *exhdrset)
memcpy(&exhdrset->acexDesc->arm9AccessControlInfo,&exhdrset->exHdr->arm9AccessControlInfo,sizeof(exhdr_ARM9AccessControlInfo));
/* Adjust Data */
- u8 *flag = &exhdrset->acexDesc->arm11SystemLocalCapabilities.flag[2];
- u8 SystemMode = (*flag>>4)&0xF;
- u8 AffinityMask = (*flag>>2)&0x3;
- u8 IdealProcessor = 1<<((*flag>>0)&0x3);
- *flag = (u8)(SystemMode << 4 | AffinityMask << 2 | IdealProcessor);
- exhdrset->acexDesc->arm11SystemLocalCapabilities.flag[3] /= 2;
+ exhdr_ARM11SystemLocalCapabilities *arm11 = &exhdrset->acexDesc->arm11SystemLocalCapabilities;
+
+ arm11->idealProcessor = 1 << arm11->idealProcessor;
+ arm11->threadPriority /= 2;
/* Sign AccessDesc */
return SignAccessDesc(exhdrset->acexDesc,exhdrset->keys);
diff --git a/makerom/code.c b/makerom/code.c
new file mode 100644
index 0000000..ea31b2c
--- /dev/null
+++ b/makerom/code.c
@@ -0,0 +1,388 @@
+#include "lib.h"
+#include "elf.h"
+#include "blz.h"
+#include "ncch_build.h"
+#include "exheader_read.h"
+#include "code.h"
+
+const char *SDK_PLAINREGION_SEGMENT_NAME = ".module_id";
+
+typedef struct code_segment
+{
+ u32 address;
+ u32 size;
+ u32 maxPageNum;
+ u8 *data;
+} code_segment;
+
+u32 GetPageSize(ncch_settings *set)
+{
+ if (set->rsfSet->Option.PageSize)
+ return strtoul(set->rsfSet->Option.PageSize, NULL, 10);
+ return 0x1000;
+}
+
+u32 SizeToPage(u32 memorySize, elf_context *elf)
+{
+ return align(memorySize, elf->pageSize) / elf->pageSize;
+}
+
+int ImportPlainRegionFromFile(ncch_settings *set)
+{
+ set->sections.plainRegion.size = align(set->componentFilePtrs.plainregionSize, set->options.blockSize);
+ set->sections.plainRegion.buffer = malloc(set->sections.plainRegion.size);
+ if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
+ ReadFile64(set->sections.plainRegion.buffer, set->componentFilePtrs.plainregionSize, 0, set->componentFilePtrs.plainregion);
+ return 0;
+}
+
+int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
+{
+ u32 size = set->componentFilePtrs.codeSize;
+ u8 *buffer = malloc(size);
+ if (!buffer) {
+ fprintf(stderr, "[ELF ERROR] Not enough memory\n");
+ return MEM_ERROR;
+ }
+ ReadFile64(buffer, size, 0, set->componentFilePtrs.code);
+
+ set->exefsSections.code.size = set->componentFilePtrs.codeSize;
+ set->exefsSections.code.buffer = malloc(set->exefsSections.code.size);
+ if (!set->exefsSections.code.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
+ ReadFile64(set->exefsSections.code.buffer, set->exefsSections.code.size, 0, set->componentFilePtrs.code);
+ if (set->options.CompressCode) {
+ u32 new_len;
+ set->exefsSections.code.buffer = BLZ_Code(buffer, size, &new_len, BLZ_NORMAL);
+ set->exefsSections.code.size = new_len;
+ free(buffer);
+ }
+ else {
+ set->exefsSections.code.size = size;
+ set->exefsSections.code.buffer = buffer;
+ }
+
+ size = set->componentFilePtrs.exhdrSize;
+ if (size < sizeof(extended_hdr)) {
+ fprintf(stderr, "[ELF ERROR] Exheader code info template is too small\n");
+ return FAILED_TO_IMPORT_FILE;
+ }
+ extended_hdr *exhdr = malloc(size);
+ if (!exhdr) {
+ fprintf(stderr, "[ELF ERROR] Not enough memory\n");
+ return MEM_ERROR;
+ }
+ ReadFile64(exhdr, size, 0, set->componentFilePtrs.exhdr);
+
+ /* Setting code_segment data */
+ set->codeDetails.textAddress = u8_to_u32(exhdr->codeSetInfo.text.address, LE);
+ set->codeDetails.textMaxPages = u8_to_u32(exhdr->codeSetInfo.text.numMaxPages, LE);
+ set->codeDetails.textSize = u8_to_u32(exhdr->codeSetInfo.text.codeSize, LE);
+
+ set->codeDetails.roAddress = u8_to_u32(exhdr->codeSetInfo.rodata.address, LE);
+ set->codeDetails.roMaxPages = u8_to_u32(exhdr->codeSetInfo.rodata.numMaxPages, LE);
+ set->codeDetails.roSize = u8_to_u32(exhdr->codeSetInfo.rodata.codeSize, LE);
+
+ set->codeDetails.rwAddress = u8_to_u32(exhdr->codeSetInfo.data.address, LE);
+ set->codeDetails.rwMaxPages = u8_to_u32(exhdr->codeSetInfo.data.numMaxPages, LE);
+ set->codeDetails.rwSize = u8_to_u32(exhdr->codeSetInfo.data.codeSize, LE);
+
+ set->codeDetails.bssSize = u8_to_u32(exhdr->codeSetInfo.bssSize, LE);
+
+ set->codeDetails.stackSize = u8_to_u32(exhdr->codeSetInfo.stackSize, LE);
+
+ free(exhdr);
+
+ return 0;
+}
+
+int GetBSSFromElf(elf_context *elf, ncch_settings *set)
+{
+ set->codeDetails.bssSize = 0;
+
+ for (int i = 0; i < elf->sectionTableEntryCount; i++) {
+ if (IsBss(&elf->sections[i]))
+ set->codeDetails.bssSize = elf->sections[i].size;
+ }
+
+ return 0;
+}
+
+int ImportPlainRegionFromElf(elf_context *elf, ncch_settings *set) // Doesn't work same as N makerom
+{
+ u64 size = 0;
+ u64 offset = 0;
+ for (u16 i = 0; i < elf->activeSegments; i++) {
+ if (strcmp(elf->segments[i].name, SDK_PLAINREGION_SEGMENT_NAME) == 0) {
+ size = elf->segments[i].header->sizeInFile;
+ offset = elf->segments[i].header->offsetInFile;
+ break;
+ }
+ }
+
+
+ if (size > 0) {
+ /* Creating Output Buffer */
+ set->sections.plainRegion.size = align(size, set->options.blockSize);
+ set->sections.plainRegion.buffer = malloc(set->sections.plainRegion.size);
+ if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
+ memset(set->sections.plainRegion.buffer, 0, set->sections.plainRegion.size);
+
+ /* Copy Plain Region */
+ memcpy(set->sections.plainRegion.buffer, elf->file + offset, size);
+ }
+
+ return 0;
+}
+
+int CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_flags)
+{
+ memset(out, 0, sizeof(code_segment));
+
+ u16 seg_num = 0;
+ elf_segment **seg = calloc(elf->activeSegments, sizeof(elf_segment*));
+
+ for (u16 i = 0; i < elf->activeSegments; i++) {
+ // Skip SDK ELF plain region
+ if (strcmp(elf->segments[i].name, SDK_PLAINREGION_SEGMENT_NAME) == 0)
+ continue;
+
+ //printf("SegName: %s (flags: %x)\n", elf->segments[i].name, elf->segments[i].header->flags);
+ if ((elf->segments[i].header->flags & ~PF_CTRSDK) == segment_flags) {
+ if (seg_num == 0) {
+ seg[seg_num] = &elf->segments[i];
+ seg_num++;
+ }
+ else if (elf->segments[i].vAddr == (u32)align(seg[seg_num - 1]->vAddr, seg[seg_num - 1]->header->alignment)) {
+ seg[seg_num] = &elf->segments[i];
+ seg_num++;
+ }
+ }
+ }
+
+ /* Return if there are no applicable segment */
+ if (seg_num == 0)
+ return 0;
+
+ /* Getting Segment Size/Settings */
+ u32 vAddr = 0;
+ u32 memorySize = 0;
+ for (u16 i = 0; i < seg_num; i++) {
+ if (i == 0) {
+ vAddr = seg[i]->vAddr;
+ }
+ else { // Add rounded size from previous segment
+ u32 padding = seg[i]->vAddr - (vAddr + memorySize);
+ memorySize += padding;
+ }
+
+ memorySize += seg[i]->header->sizeInMemory;
+
+ if (IsBss(&seg[i]->sections[seg[i]->sectionNum - 1]))
+ memorySize -= seg[i]->sections[seg[i]->sectionNum - 1].size;
+ }
+
+ // For Check
+#ifdef DEBUG
+ printf("Address: 0x%x\n", vAddr);
+ printf("Size: 0x%x\n", memorySize);
+#endif
+
+ out->address = vAddr;
+ out->size = memorySize;
+ out->maxPageNum = SizeToPage(memorySize, elf);
+ out->data = malloc(memorySize);
+
+ /* Writing Segment to Buffer */
+ for (int i = 0; i < seg_num; i++) {
+
+ for (int j = 0; j < seg[i]->sectionNum; j++) {
+ elf_section_entry *section = &seg[i]->sections[j];
+ if (!IsBss(section)) {
+ u8 *pos = (out->data + (section->address - seg[i]->vAddr));
+ memcpy(pos, section->ptr, section->size);
+ //size += section->size;
+ }
+ }
+ }
+
+ free(seg);
+ return 0;
+}
+
+int CreateExeFsCode(elf_context *elf, ncch_settings *set)
+{
+ /* Getting Code Segments */
+ code_segment text;
+ memset(&text, 0, sizeof(code_segment));
+ code_segment rodata;
+ memset(&rodata, 0, sizeof(code_segment));
+ code_segment rwdata;
+ memset(&rwdata, 0, sizeof(code_segment));
+
+ int result = CreateCodeSegmentFromElf(&text, elf, PF_TEXT);
+ if (result) return result;
+ result = CreateCodeSegmentFromElf(&rodata, elf, PF_RODATA);
+ if (result) return result;
+ result = CreateCodeSegmentFromElf(&rwdata, elf, PF_DATA);
+ if (result) return result;
+
+ /* Checking the existence of essential ELF Segments */
+ if (!text.size) return NOT_FIND_TEXT_SEGMENT;
+ if (!rwdata.size) return NOT_FIND_DATA_SEGMENT;
+
+ /* Allocating Buffer for ExeFs Code */
+ u32 size = (text.maxPageNum + rodata.maxPageNum + rwdata.maxPageNum)*elf->pageSize;
+ u8 *code = calloc(1, size);
+
+ /* Writing Code into Buffer */
+ u8 *textPos = (code + 0);
+ u8 *rodataPos = (code + text.maxPageNum*elf->pageSize);
+ u8 *rwdataPos = (code + (text.maxPageNum + rodata.maxPageNum)*elf->pageSize);
+ if (text.size) memcpy(textPos, text.data, text.size);
+ if (rodata.size) memcpy(rodataPos, rodata.data, rodata.size);
+ if (rwdata.size) memcpy(rwdataPos, rwdata.data, rwdata.size);
+
+
+ /* Compressing If needed */
+ if (set->options.CompressCode) {
+ u32 new_len;
+ set->exefsSections.code.buffer = BLZ_Code(code, size, &new_len, BLZ_NORMAL);
+ set->exefsSections.code.size = new_len;
+ free(code);
+ }
+ else {
+ set->exefsSections.code.size = size;
+ set->exefsSections.code.buffer = code;
+ }
+
+ /* Setting code_segment data and freeing original buffers */
+ set->codeDetails.textAddress = text.address;
+ set->codeDetails.textMaxPages = text.maxPageNum;
+ set->codeDetails.textSize = text.size;
+ if (text.size) free(text.data);
+
+ set->codeDetails.roAddress = rodata.address;
+ set->codeDetails.roMaxPages = rodata.maxPageNum;
+ set->codeDetails.roSize = rodata.size;
+ if (rodata.size) free(rodata.data);
+
+ set->codeDetails.rwAddress = rwdata.address;
+ set->codeDetails.rwMaxPages = rwdata.maxPageNum;
+ set->codeDetails.rwSize = rwdata.size;
+ if (rwdata.size) free(rwdata.data);
+
+ if (set->rsfSet->SystemControlInfo.StackSize)
+ set->codeDetails.stackSize = strtoul(set->rsfSet->SystemControlInfo.StackSize, NULL, 0);
+ else {
+ fprintf(stderr, "[CODE ERROR] RSF Parameter Not Found: \"SystemControlInfo/StackSize\"\n");
+ return 1;
+ }
+
+ /* Return */
+ return 0;
+}
+
+void PrintElfContext(elf_context *elf)
+{
+ printf("[ELF] Program Table Data\n");
+ printf(" Offset: 0x%x\n", elf->programTableOffset);
+ printf(" Size: 0x%x\n", elf->programTableEntrySize);
+ printf(" Count: 0x%x\n", elf->programTableEntryCount);
+ printf("[ELF] Section Table Data\n");
+ printf(" Offset: 0x%x\n", elf->sectionTableOffset);
+ printf(" Size: 0x%x\n", elf->sectionTableEntrySize);
+ printf(" Count: 0x%x\n", elf->sectionTableEntryCount);
+ printf(" Label index: 0x%x\n", elf->sectionHeaderNameEntryIndex);
+ for (int i = 0; i < elf->activeSegments; i++) {
+ printf(" Segment [%d][%s]\n", i, elf->segments[i].name);
+ printf(" > Size : 0x%x\n", elf->segments[i].header->sizeInFile);
+ printf(" > Address : 0x%x\n", elf->segments[i].vAddr);
+ printf(" > Flags: 0x%x\n", elf->segments[i].header->flags);
+ printf(" > Type: 0x%x\n", elf->segments[i].header->type);
+ printf(" > Sections : %d\n", elf->segments[i].sectionNum);
+ for (int j = 0; j < elf->segments[i].sectionNum; j++)
+ printf(" > Section [%d][%s][0x%x][0x%x]\n", j, elf->segments[i].sections[j].name, elf->segments[i].sections[j].flags, elf->segments[i].sections[j].type);
+
+ /*
+ char outpath[100];
+ memset(&outpath,0,100);
+ sprintf(outpath,"%s.bin",elf->sections[i].name);
+ chdir("elfsections");
+ FILE *tmp = fopen(outpath,"wb");
+ WriteBuffer(elf->sections[i].ptr,elf->sections[i].size,0,tmp);
+ fclose(tmp);
+ chdir("..");
+ */
+ }
+
+}
+
+int BuildExeFsCode(ncch_settings *set)
+{
+ int result = 0;
+ if (set->options.IsCfa)
+ return result;
+
+ if (set->componentFilePtrs.plainregion) // Import PlainRegion from file
+ if ((result = ImportPlainRegionFromFile(set))) return result;
+ if (!set->options.IsBuildingCodeSection) // Import ExeFs Code from file and return
+ return ImportExeFsCodeBinaryFromFile(set);
+
+ /* Import ELF */
+ u8 *elfFile = malloc(set->componentFilePtrs.elfSize);
+ if (!elfFile) {
+ fprintf(stderr, "[CODE ERROR] Not enough memory\n");
+ return MEM_ERROR;
+ }
+ ReadFile64(elfFile, set->componentFilePtrs.elfSize, 0, set->componentFilePtrs.elf);
+
+ /* Create ELF Context */
+ elf_context *elf = calloc(1, sizeof(elf_context));
+ if (!elf) {
+ fprintf(stderr, "[CODE ERROR] Not enough memory\n");
+ free(elfFile);
+ return MEM_ERROR;
+ }
+
+ if ((result = GetElfContext(elf, elfFile))) goto finish;
+
+ /* Setting Page Size */
+ elf->pageSize = GetPageSize(set);
+
+ if (!set->componentFilePtrs.plainregion)
+ if ((result = ImportPlainRegionFromElf(elf, set))) goto finish;
+
+ if (set->options.verbose)
+ PrintElfContext(elf);
+
+ if ((result = CreateExeFsCode(elf, set))) goto finish;
+ if ((result = GetBSSFromElf(elf, set))) goto finish;
+
+finish:
+ switch (result) {
+ case (0) :
+ break;
+ case (NOT_ELF_FILE) :
+ fprintf(stderr, "[CODE ERROR] Not ELF File\n");
+ break;
+ case (NOT_CTR_ARM_ELF) :
+ fprintf(stderr, "[CODE ERROR] Not CTR ARM ELF\n");
+ break;
+ case (NON_EXECUTABLE_ELF) :
+ fprintf(stderr, "[CODE ERROR] Not Executeable ELF\n");
+ break;
+ case (NOT_FIND_TEXT_SEGMENT) :
+ fprintf(stderr, "[CODE ERROR] Failed to retrieve text sections from ELF\n");
+ break;
+ case (NOT_FIND_DATA_SEGMENT) :
+ fprintf(stderr, "[CODE ERROR] Failed to retrieve data sections from ELF\n");
+ break;
+ default:
+ fprintf(stderr, "[CODE ERROR] Failed to process ELF file (%d)\n", result);
+ }
+
+ FreeElfContext(elf);
+ free(elfFile);
+ free(elf);
+ return result;
+}
diff --git a/makerom/code.h b/makerom/code.h
new file mode 100644
index 0000000..fdad049
--- /dev/null
+++ b/makerom/code.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int BuildExeFsCode(ncch_settings *ncchset);
\ No newline at end of file
diff --git a/makerom/elf.c b/makerom/elf.c
index aae3539..6aad3ef 100644
--- a/makerom/elf.c
+++ b/makerom/elf.c
@@ -1,430 +1,149 @@
#include "lib.h"
-#include "ncch_build.h"
-#include "exheader_read.h"
-#include "elf_hdr.h"
#include "elf.h"
-#include "blz.h"
-const char *SDK_PLAINREGION_SEGMENT_NAME = ".module_id";
+static const u32 ELF_MAGIC = 0x7f454c46;
-int ImportPlainRegionFromFile(ncch_settings *set);
-int ImportExeFsCodeBinaryFromFile(ncch_settings *set);
+typedef enum elf_bit_format_types
+{
+ elf_32_bit = 1,
+ elf_64_bit = 2,
+} elf_bit_format_types;
-u32 GetPageSize(ncch_settings *set);
-u32 SizeToPage(u32 memorySize, elf_context *elf);
+typedef enum elf_endianness
+{
+ elf_little_endian = 1,
+ elf_big_endian = 2,
+} elf_endianness;
-int GetBSSFromElf(elf_context *elf, u8 *elfFile, ncch_settings *set);
-int ImportPlainRegionFromElf(elf_context *elf, u8 *elfFile, ncch_settings *set);
-int CreateExeFsCode(elf_context *elf, u8 *elfFile, ncch_settings *set);
-int CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u8 *elfFile, u64 segment_flags);
+typedef enum elf_type
+{
+ elf_relocatable = 1,
+ elf_executeable = 2,
+ elf_shared = 3,
+ elf_core = 4,
+} elf_type;
+
+typedef enum elf_target_architecture
+{
+ elf_arm = 0x28,
+} elf_target_architecture;
+
+typedef struct elf_hdr
+{
+ u8 magic[4];
+ u8 bitFormat;
+ u8 endianness;
+ u8 elfVersion;
+ u8 os;
+ u8 padding0[8];
+ u8 type[2];
+ u8 targetArchitecture[2];
+ u8 version[4];
+ u8 entryPoint[4];
+ u8 programHeaderTableOffset[4];
+ u8 sectionHeaderTableOffset[4];
+ u8 flags[4];
+ u8 headerSize[2];
+ u8 programHeaderEntrySize[2];
+ u8 programHeaderEntryCount[2];
+ u8 sectionTableEntrySize[2];
+ u8 sectionHeaderEntryCount[2];
+ u8 sectionHeaderNameEntryIndex[2];
+} elf_hdr;
+
+/* taken from elf specs, will not follow global style */
+
+/* Section header. */
+typedef struct elf_shdr
+{
+ u8 name[4]; /* Section name (string tbl index) */
+ u8 type[4]; /* Section type */
+ u8 flags[4]; /* Section flags */
+ u8 addr[4]; /* Section virtual addr at execution */
+ u8 offset[4]; /* Section file offset */
+ u8 size[4]; /* Section size in bytes */
+ u8 link[4]; /* Link to another section */
+ u8 info[4]; /* Additional section information */
+ u8 addralign[4]; /* Section alignment */
+ u8 entsize[4]; /* Entry size if section holds table */
+} elf_shdr;
+
+/* Program segment header. */
+typedef struct elf_phdr
+{
+ u8 type[4]; /* Segment type */
+ u8 offset[4]; /* Segment file offset */
+ u8 vaddr[4]; /* Segment virtual address */
+ u8 paddr[4]; /* Segment physical address */
+ u8 filesz[4]; /* Segment size in file */
+ u8 memsz[4]; /* Segment size in memory */
+ u8 flags[4]; /* Segment flags */
+ u8 align[4]; /* Segment alignment */
+} elf_phdr;
// ELF Functions
-int GetElfContext(elf_context *elf, u8 *elfFile);
-int GetElfSectionEntries(elf_context *elf, u8 *elfFile);
-int GetElfProgramEntries(elf_context *elf, u8 *elfFile);
-void PrintElfContext(elf_context *elf, u8 *elfFile);
-int ReadElfHdr(elf_context *elf, u8 *elfFile);
+int GetElfSectionEntries(elf_context *elf);
+int GetElfProgramEntries(elf_context *elf);
+void PrintElfContext(elf_context *elf);
+int ReadElfHdr(elf_context *elf);
-int CreateElfSegments(elf_context *elf, u8 *elfFile);
+int CreateElfSegments(elf_context *elf);
bool IsIgnoreSection(elf_section_entry info);
-/* ELF Section Entry Functions */
-u8* GetELFSectionHeader(u16 index, elf_context *elf, u8 *elfFile);
-u8* GetELFSectionEntry(u16 index, elf_context *elf, u8 *elfFile);
-char* GetELFSectionEntryName(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntryType(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntryFlags(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntryAddress(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntryFileOffset(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntrySize(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFSectionEntryAlignment(u16 index, elf_context *elf, u8 *elfFile);
+// ELF Functions
-u16 GetElfSectionIndexFromName(char *name, elf_context *elf, u8 *elfFile);
-
-bool IsBss(elf_section_entry *section);
-bool IsData(elf_section_entry *section);
-bool IsRoData(elf_section_entry *section);
-bool IsText(elf_section_entry *section);
-
-/* ELF Program Entry Functions */
-u8* GetELFProgramHeader(u16 index, elf_context *elf, u8 *elfFile);
-u8* GetELFProgramEntry(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryType(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryFlags(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryFileSize(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryFileOffset(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryMemorySize(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryVAddress(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryPAddress(u16 index, elf_context *elf, u8 *elfFile);
-u64 GetELFProgramEntryAlignment(u16 index, elf_context *elf, u8 *elfFile);
-
-
-int BuildExeFsCode(ncch_settings *set)
+int GetElfContext(elf_context *elf, const u8 *elfFile)
{
- int result = 0;
- if(set->options.IsCfa)
- return result;
- if(set->componentFilePtrs.plainregion){ // Import PlainRegion from file
- result = ImportPlainRegionFromFile(set);
- if(result) return result;
- }
- if(!set->options.IsBuildingCodeSection){ // Import ExeFs Code from file and return
- result = ImportExeFsCodeBinaryFromFile(set);
- return result;
- }
-
- /* Import ELF */
- u8 *elfFile = malloc(set->componentFilePtrs.elfSize);
- if(!elfFile) {
- fprintf(stderr,"[ELF ERROR] Not enough memory\n");
- return MEM_ERROR;
- }
- ReadFile64(elfFile,set->componentFilePtrs.elfSize,0,set->componentFilePtrs.elf);
-
- /* Create ELF Context */
- elf_context *elf = calloc(1,sizeof(elf_context));
- if(!elf) {
- fprintf(stderr,"[ELF ERROR] Not enough memory\n");
- free(elfFile);
- return MEM_ERROR;
- }
+ elf->file = elfFile;
- result = GetElfContext(elf,elfFile);
- if(result) goto finish;
+ int result;
- /* Setting Page Size */
- elf->pageSize = GetPageSize(set);
+ if((result = ReadElfHdr(elf))) return result;
+ if((result = GetElfSectionEntries(elf))) return result;
+ if((result = GetElfProgramEntries(elf))) return result;
+ if((result = CreateElfSegments(elf))) return result;
- if(!set->componentFilePtrs.plainregion){
- result = ImportPlainRegionFromElf(elf,elfFile,set);
- if(result) goto finish;
- }
+ return 0;
+}
- if(set->options.verbose)
- PrintElfContext(elf,elfFile);
-
- result = CreateExeFsCode(elf,elfFile,set);
- if(result) goto finish;
-
- result = GetBSSFromElf(elf,elfFile,set);
- if(result) goto finish;
-
-finish:
- switch (result) {
- case (0) :
- break;
- case (NOT_ELF_FILE) :
- fprintf(stderr, "[ELF ERROR] Not ELF File\n");
- break;
- case (NOT_ARM_ELF) :
- fprintf(stderr, "[ELF ERROR] Not ARM ELF\n");
- break;
- case (NON_EXECUTABLE_ELF) :
- fprintf(stderr, "[ELF ERROR] Not Executeable ELF\n");
- break;
- case (NOT_FIND_TEXT_SEGMENT) :
- fprintf(stderr, "[ELF ERROR] Failed to retrieve text sections from ELF\n");
- break;
- case (NOT_FIND_DATA_SEGMENT) :
- fprintf(stderr, "[ELF ERROR] Failed to retrieve data sections from ELF\n");
- break;
- default:
- fprintf(stderr, "[ELF ERROR] Failed to process ELF file (%d)\n", result);
- }
- for(int i = 0; i < elf->activeSegments; i++)
+void FreeElfContext(elf_context *elf)
+{
+ for (int i = 0; i < elf->activeSegments; i++)
free(elf->segments[i].sections);
- free(elfFile);
free(elf->sections);
free(elf->programHeaders);
free(elf->segments);
- free(elf);
- return result;
}
-int ImportPlainRegionFromFile(ncch_settings *set)
+int ReadElfHdr(elf_context *elf)
{
- set->sections.plainRegion.size = align(set->componentFilePtrs.plainregionSize,set->options.blockSize);
- set->sections.plainRegion.buffer = malloc(set->sections.plainRegion.size);
- if(!set->sections.plainRegion.buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
- ReadFile64(set->sections.plainRegion.buffer,set->componentFilePtrs.plainregionSize,0,set->componentFilePtrs.plainregion);
- return 0;
-}
+ const elf_hdr *hdr = (const elf_hdr*)elf->file;
-int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
-{
- u32 size = set->componentFilePtrs.codeSize;
- u8 *buffer = malloc(size);
- if(!buffer) {
- fprintf(stderr,"[ELF ERROR] Not enough memory\n");
- return MEM_ERROR;
- }
- ReadFile64(buffer,size,0,set->componentFilePtrs.code);
+ if (u8_to_u32(hdr->magic, BE) != ELF_MAGIC)
+ return NOT_ELF_FILE;
+ if (hdr->bitFormat != elf_32_bit)
+ return NOT_CTR_ARM_ELF;
+ if (hdr->endianness != elf_little_endian)
+ return NOT_CTR_ARM_ELF;
+ if (u8_to_u16(hdr->targetArchitecture, LE) != elf_arm)
+ return NOT_CTR_ARM_ELF;
+ if (u8_to_u16(hdr->type, LE) != elf_executeable)
+ return NON_EXECUTABLE_ELF;
- set->exefsSections.code.size = set->componentFilePtrs.codeSize;
- set->exefsSections.code.buffer = malloc(set->exefsSections.code.size);
- if(!set->exefsSections.code.buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
- ReadFile64(set->exefsSections.code.buffer,set->exefsSections.code.size,0,set->componentFilePtrs.code);
- if(set->options.CompressCode){
- u32 new_len;
- set->exefsSections.code.buffer = BLZ_Code(buffer,size,&new_len,BLZ_NORMAL);
- set->exefsSections.code.size = new_len;
- free(buffer);
- }
- else{
- set->exefsSections.code.size = size;
- set->exefsSections.code.buffer = buffer;
- }
-
- size = set->componentFilePtrs.exhdrSize;
- if(size < sizeof(extended_hdr)){
- fprintf(stderr,"[ELF ERROR] Exheader code info template is too small\n");
- return FAILED_TO_IMPORT_FILE;
- }
- extended_hdr *exhdr = malloc(size);
- if(!exhdr) {
- fprintf(stderr,"[ELF ERROR] Not enough memory\n");
- return MEM_ERROR;
- }
- ReadFile64(exhdr,size,0,set->componentFilePtrs.exhdr);
-
- /* Setting code_segment data */
- set->codeDetails.textAddress = u8_to_u32(exhdr->codeSetInfo.text.address,LE);
- set->codeDetails.textMaxPages = u8_to_u32(exhdr->codeSetInfo.text.numMaxPages,LE);
- set->codeDetails.textSize = u8_to_u32(exhdr->codeSetInfo.text.codeSize,LE);
+ elf->programTableOffset = u8_to_u32(hdr->programHeaderTableOffset, LE);
+ elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize, LE);
+ elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount, LE);
- set->codeDetails.roAddress = u8_to_u32(exhdr->codeSetInfo.rodata.address,LE);
- set->codeDetails.roMaxPages = u8_to_u32(exhdr->codeSetInfo.rodata.numMaxPages,LE);
- set->codeDetails.roSize = u8_to_u32(exhdr->codeSetInfo.rodata.codeSize,LE);
+ elf->sectionTableOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE);
+ elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize, LE);
+ elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount, LE);
- set->codeDetails.rwAddress = u8_to_u32(exhdr->codeSetInfo.data.address,LE);
- set->codeDetails.rwMaxPages = u8_to_u32(exhdr->codeSetInfo.data.numMaxPages,LE);
- set->codeDetails.rwSize = u8_to_u32(exhdr->codeSetInfo.data.codeSize,LE);
-
- set->codeDetails.bssSize = u8_to_u32(exhdr->codeSetInfo.bssSize,LE);
-
- free(exhdr);
-
- return 0;
-}
-
-u32 GetPageSize(ncch_settings *set)
-{
- if(set->rsfSet->Option.PageSize)
- return strtoul(set->rsfSet->Option.PageSize,NULL,10);
- return 0x1000;
-}
-
-u32 SizeToPage(u32 memorySize, elf_context *elf)
-{
- return align(memorySize,elf->pageSize)/elf->pageSize;
-}
-
-
-int GetBSSFromElf(elf_context *elf, u8 *elfFile, ncch_settings *set)
-{
- set->codeDetails.bssSize = 0;
-
- for(int i = 0; i < elf->sectionTableEntryCount; i++){
- if(IsBss(&elf->sections[i]))
- set->codeDetails.bssSize = elf->sections[i].size;
- }
-
- return 0;
-}
-
-int ImportPlainRegionFromElf(elf_context *elf, u8 *elfFile, ncch_settings *set) // Doesn't work same as N makerom
-{
- u64 size = 0;
- u64 offset = 0;
- for (u16 i = 0; i < elf->activeSegments; i++) {
- if (strcmp(elf->segments[i].name, SDK_PLAINREGION_SEGMENT_NAME) == 0) {
- size = elf->segments[i].header->sizeInFile;
- offset = elf->segments[i].header->offsetInFile;
- break;
- }
- }
-
-
- if (size > 0) {
- /* Creating Output Buffer */
- set->sections.plainRegion.size = align(size, set->options.blockSize);
- set->sections.plainRegion.buffer = malloc(set->sections.plainRegion.size);
- if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
- memset(set->sections.plainRegion.buffer, 0, set->sections.plainRegion.size);
-
- /* Copy Plain Region */
- memcpy(set->sections.plainRegion.buffer, elfFile+offset, size);
- }
+ elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE);
return 0;
}
-int CreateExeFsCode(elf_context *elf, u8 *elfFile, ncch_settings *set)
-{
- /* Getting Code Segments */
- code_segment text;
- memset(&text,0,sizeof(code_segment));
- code_segment rodata;
- memset(&rodata,0,sizeof(code_segment));
- code_segment rwdata;
- memset(&rwdata,0,sizeof(code_segment));
-
- int result = CreateCodeSegmentFromElf(&text,elf,elfFile,(PF_R|PF_X));
- if(result) return result;
- result = CreateCodeSegmentFromElf(&rodata,elf,elfFile,(PF_R));
- if(result) return result;
- result = CreateCodeSegmentFromElf(&rwdata,elf,elfFile,(PF_R | PF_W));
- if(result) return result;
-
- /* Checking the existence of essential ELF Segments */
- if(!text.size) return NOT_FIND_TEXT_SEGMENT;
- if(!rwdata.size) return NOT_FIND_DATA_SEGMENT;
-
- /* Allocating Buffer for ExeFs Code */
- u32 size = (text.maxPageNum + rodata.maxPageNum + rwdata.maxPageNum)*elf->pageSize;
- u8 *code = calloc(1,size);
-
- /* Writing Code into Buffer */
- u8 *textPos = (code + 0);
- u8 *rodataPos = (code + text.maxPageNum*elf->pageSize);
- u8 *rwdataPos = (code + (text.maxPageNum + rodata.maxPageNum)*elf->pageSize);
- if(text.size) memcpy(textPos,text.data,text.size);
- if(rodata.size) memcpy(rodataPos,rodata.data,rodata.size);
- if(rwdata.size) memcpy(rwdataPos,rwdata.data,rwdata.size);
-
-
- /* Compressing If needed */
- if(set->options.CompressCode){
- u32 new_len;
- set->exefsSections.code.buffer = BLZ_Code(code,size,&new_len,BLZ_NORMAL);
- set->exefsSections.code.size = new_len;
- free(code);
- }
- else{
- set->exefsSections.code.size = size;
- set->exefsSections.code.buffer = code;
- }
-
- /* Setting code_segment data and freeing original buffers */
- set->codeDetails.textAddress = text.address;
- set->codeDetails.textMaxPages = text.maxPageNum;
- set->codeDetails.textSize = text.size;
- if(text.size) free(text.data);
-
- set->codeDetails.roAddress = rodata.address;
- set->codeDetails.roMaxPages = rodata.maxPageNum;
- set->codeDetails.roSize = rodata.size;
- if(rodata.size) free(rodata.data);
-
- set->codeDetails.rwAddress = rwdata.address;
- set->codeDetails.rwMaxPages = rwdata.maxPageNum;
- set->codeDetails.rwSize = rwdata.size;
- if(rwdata.size) free(rwdata.data);
-
- /* Return */
- return 0;
-}
-
-int CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u8 *elfFile, u64 segment_flags)
-{
- memset(out, 0, sizeof(code_segment));
-
- u16 seg_num = 0;
- elf_segment **seg = calloc(elf->activeSegments, sizeof(elf_segment*));
-
- for (u16 i = 0; i < elf->activeSegments; i++) {
- // Skip SDK ELF plain region
- if (strcmp(elf->segments[i].name, SDK_PLAINREGION_SEGMENT_NAME) == 0)
- continue;
-
- //printf("SegName: %s (flags: %x)\n", elf->segments[i].name, elf->segments[i].header->flags);
- if ((elf->segments[i].header->flags & ~PF_CTRSDK) == segment_flags) {
- if (seg_num == 0) {
- seg[seg_num] = &elf->segments[i];
- seg_num++;
- }
- else if (elf->segments[i].vAddr == (u32)align(seg[seg_num - 1]->vAddr, seg[seg_num-1]->header->alignment)) {
- seg[seg_num] = &elf->segments[i];
- seg_num++;
- }
- }
- }
-
- /* Return if there are no applicable segment */
- if (seg_num == 0)
- return 0;
-
- /* Getting Segment Size/Settings */
- u32 vAddr = 0;
- u32 memorySize = 0;
- for (u16 i = 0; i < seg_num; i++) {
- if (i == 0) {
- vAddr = seg[i]->vAddr;
- }
- else { // Add rounded size from previous segment
- u32 padding = seg[i]->vAddr - (vAddr + memorySize);
- memorySize += padding;
- }
-
- memorySize += seg[i]->header->sizeInMemory;
-
- if (IsBss(&seg[i]->sections[seg[i]->sectionNum - 1]))
- memorySize -= seg[i]->sections[seg[i]->sectionNum - 1].size;
- }
-
- // For Check
-#ifdef DEBUG
- printf("Address: 0x%x\n", vAddr);
- printf("Size: 0x%x\n", memorySize);
-#endif
-
- out->address = vAddr;
- out->size = memorySize;
- out->maxPageNum = SizeToPage(memorySize, elf);
- out->data = malloc(memorySize);
-
- /* Writing Segment to Buffer */
- for (int i = 0; i < seg_num; i++) {
-
- for (int j = 0; j < seg[i]->sectionNum; j++) {
- elf_section_entry *section = &seg[i]->sections[j];
- if (!IsBss(section)) {
- u8 *pos = (out->data + (section->address - seg[i]->vAddr));
- memcpy(pos, section->ptr, section->size);
- //size += section->size;
- }
- }
- }
-
- free(seg);
- return 0;
-}
-
-// ELF Functions
-
-int GetElfContext(elf_context *elf, u8 *elfFile)
-{
- if(u8_to_u32(elfFile,BE) != ELF_MAGIC) return NOT_ELF_FILE;
-
- elf->Is64bit = (elfFile[4] == elf_64_bit);
- elf->IsLittleEndian = (elfFile[5] == elf_little_endian);
-
- int result = ReadElfHdr(elf,elfFile);
- if(result) return result;
-
- result = GetElfSectionEntries(elf,elfFile);
- if(result) return result;
-
- result = GetElfProgramEntries(elf,elfFile);
- if(result) return result;
-
- result = CreateElfSegments(elf,elfFile);
- if(result) return result;
-
- return 0;
-}
-
-int GetElfSectionEntries(elf_context *elf, u8 *elfFile)
+int GetElfSectionEntries(elf_context *elf)
{
elf->sections = calloc(elf->sectionTableEntryCount,sizeof(elf_section_entry));
if(!elf->sections) {
@@ -432,20 +151,23 @@ int GetElfSectionEntries(elf_context *elf, u8 *elfFile)
return MEM_ERROR;
}
+ const elf_shdr *shdr = (const elf_shdr *)(elf->file + elf->sectionTableOffset);
+ const char *nameTable = (const char*)(elf->file + u8_to_u32(shdr[elf->sectionHeaderNameEntryIndex].offset, LE));
+
for(int i = 0; i < elf->sectionTableEntryCount; i++){
- elf->sections[i].name = GetELFSectionEntryName(i,elf,elfFile);
- elf->sections[i].type = GetELFSectionEntryType(i,elf,elfFile);
- elf->sections[i].flags = GetELFSectionEntryFlags(i,elf,elfFile);
- elf->sections[i].ptr = GetELFSectionEntry(i,elf,elfFile);
- elf->sections[i].offsetInFile = GetELFSectionEntryFileOffset(i,elf,elfFile);
- elf->sections[i].size = GetELFSectionEntrySize(i,elf,elfFile);
- elf->sections[i].address = GetELFSectionEntryAddress(i,elf,elfFile);
- elf->sections[i].alignment = GetELFSectionEntryAlignment(i,elf,elfFile);
+ elf->sections[i].name = nameTable + u8_to_u32(shdr[i].name, LE);
+ elf->sections[i].type = u8_to_u32(shdr[i].type, LE);
+ elf->sections[i].flags = u8_to_u32(shdr[i].flags, LE);
+ elf->sections[i].offsetInFile = u8_to_u32(shdr[i].offset, LE);
+ elf->sections[i].size = u8_to_u32(shdr[i].size, LE);
+ elf->sections[i].ptr = elf->file + elf->sections[i].offsetInFile;
+ elf->sections[i].address = u8_to_u32(shdr[i].addr, LE);
+ elf->sections[i].alignment = u8_to_u32(shdr[i].addralign, LE);
}
return 0;
}
-int GetElfProgramEntries(elf_context *elf, u8 *elfFile)
+int GetElfProgramEntries(elf_context *elf)
{
elf->programHeaders = calloc(elf->programTableEntryCount,sizeof(elf_program_entry));
if(!elf->programHeaders) {
@@ -453,240 +175,25 @@ int GetElfProgramEntries(elf_context *elf, u8 *elfFile)
return MEM_ERROR;
}
+ const elf_phdr *phdr = (const elf_phdr*)(elf->file + elf->programTableOffset);
+
for(int i = 0; i < elf->programTableEntryCount; i++){
- elf->programHeaders[i].type = GetELFProgramEntryType(i,elf,elfFile);
- elf->programHeaders[i].flags = GetELFProgramEntryFlags(i,elf,elfFile);
- elf->programHeaders[i].ptr = GetELFProgramEntry(i,elf,elfFile);
- elf->programHeaders[i].offsetInFile = GetELFProgramEntryFileOffset(i,elf,elfFile);
- elf->programHeaders[i].sizeInFile = GetELFProgramEntryFileSize(i,elf,elfFile);
- elf->programHeaders[i].physicalAddress = GetELFProgramEntryPAddress(i,elf,elfFile);
- elf->programHeaders[i].virtualAddress = GetELFProgramEntryVAddress(i,elf,elfFile);
- elf->programHeaders[i].sizeInMemory = GetELFProgramEntryMemorySize(i,elf,elfFile);
- elf->programHeaders[i].alignment = GetELFProgramEntryAlignment(i,elf,elfFile);
+ elf->programHeaders[i].type = u8_to_u32(phdr[i].type, LE);
+ elf->programHeaders[i].flags = u8_to_u32(phdr[i].flags, LE);
+ elf->programHeaders[i].offsetInFile = u8_to_u32(phdr[i].offset, LE);
+ elf->programHeaders[i].sizeInFile = u8_to_u32(phdr[i].filesz, LE);
+ elf->programHeaders[i].ptr = elf->file + elf->programHeaders[i].offsetInFile;
+ elf->programHeaders[i].physicalAddress = u8_to_u32(phdr[i].paddr, LE);
+ elf->programHeaders[i].virtualAddress = u8_to_u32(phdr[i].vaddr, LE);
+ elf->programHeaders[i].sizeInMemory = u8_to_u32(phdr[i].memsz, LE);
+ elf->programHeaders[i].alignment = u8_to_u32(phdr[i].align, LE);
}
return 0;
}
-void PrintElfContext(elf_context *elf, u8 *elfFile)
-{
- printf("[ELF] Basic Details\n");
- printf(" Class: %s\n",elf->Is64bit ? "64-bit" : "32-bit");
- printf(" Data: %s\n",elf->IsLittleEndian ? "Little Endian" : "Big Endian");
- printf("[ELF] Program Table Data\n");
- printf(" Offset: 0x%"PRIx64"\n",elf->programTableOffset);
- printf(" Size: 0x%x\n",elf->programTableEntrySize);
- printf(" Count: 0x%x\n",elf->programTableEntryCount);
- printf("[ELF] Section Table Data\n");
- printf(" Offset: 0x%"PRIx64"\n",elf->sectionTableOffset);
- printf(" Size: 0x%x\n",elf->sectionTableEntrySize);
- printf(" Count: 0x%x\n",elf->sectionTableEntryCount);
- printf(" Label index: 0x%x\n",elf->sectionHeaderNameEntryIndex);
- for(int i = 0; i < elf->activeSegments; i++){
- printf(" Segment [%d][%s]\n",i,elf->segments[i].name);
- printf(" > Size : 0x%"PRIx64"\n",elf->segments[i].header->sizeInFile);
- printf(" > Address : 0x%"PRIx64"\n",elf->segments[i].vAddr);
- printf(" > Flags: 0x%"PRIx64"\n", elf->segments[i].header->flags);
- printf(" > Type: 0x%"PRIx64"\n", elf->segments[i].header->type);
- printf(" > Sections : %d\n",elf->segments[i].sectionNum);
- for(int j = 0; j < elf->segments[i].sectionNum; j++)
- printf(" > Section [%d][%s][0x%"PRIx64"][0x%"PRIx64"]\n",j,elf->segments[i].sections[j].name, elf->segments[i].sections[j].flags, elf->segments[i].sections[j].type);
-
- /*
- char outpath[100];
- memset(&outpath,0,100);
- sprintf(outpath,"%s.bin",elf->sections[i].name);
- chdir("elfsections");
- FILE *tmp = fopen(outpath,"wb");
- WriteBuffer(elf->sections[i].ptr,elf->sections[i].size,0,tmp);
- fclose(tmp);
- chdir("..");
- */
- }
-
-}
-
-int ReadElfHdr(elf_context *elf, u8 *elfFile)
-{
- if(elf->Is64bit){
- elf_64_hdr *hdr = (elf_64_hdr*)elfFile;
-
- u16 Architecture = u8_to_u16(hdr->targetArchitecture,elf->IsLittleEndian);
- u16 Type = u8_to_u16(hdr->type,elf->IsLittleEndian);
- if(Architecture != elf_arm) return NOT_ARM_ELF;
- if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
-
- elf->programTableOffset = u8_to_u64(hdr->programHeaderTableOffset,elf->IsLittleEndian);
- elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize,elf->IsLittleEndian);
- elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount,elf->IsLittleEndian);
-
- elf->sectionTableOffset = u8_to_u64(hdr->sectionHeaderTableOffset,elf->IsLittleEndian);
- elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize,elf->IsLittleEndian);
- elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount,elf->IsLittleEndian);
-
- elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex,elf->IsLittleEndian);
- }
- else{
- elf_32_hdr *hdr = (elf_32_hdr*)elfFile;
-
- u16 Architecture = u8_to_u16(hdr->targetArchitecture,elf->IsLittleEndian);
- u16 Type = u8_to_u16(hdr->type,elf->IsLittleEndian);
- if(Architecture != elf_arm) return NOT_ARM_ELF;
- if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
-
- elf->programTableOffset = u8_to_u32(hdr->programHeaderTableOffset,elf->IsLittleEndian);
- elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize,elf->IsLittleEndian);
- elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount,elf->IsLittleEndian);
-
- elf->sectionTableOffset = u8_to_u32(hdr->sectionHeaderTableOffset,elf->IsLittleEndian);
- elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize,elf->IsLittleEndian);
- elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount,elf->IsLittleEndian);
-
- elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex,elf->IsLittleEndian);
- }
- return 0;
-}
-
/* Section Hdr Functions */
-u8* GetELFSectionHeader(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return NULL;
-
- return (elfFile + elf->sectionTableOffset + elf->sectionTableEntrySize*index);
-}
-
-u8* GetELFSectionEntry(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return NULL;
-
- return (u8*) (elfFile + GetELFSectionEntryFileOffset(index,elf,elfFile));
-}
-
-char* GetELFSectionEntryName(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- u64 NameIndex = 0;
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- NameIndex = u8_to_u64(shdr->sh_name,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- NameIndex = u8_to_u32(shdr->sh_name,elf->IsLittleEndian);
- }
-
- u8 *NameTable = GetELFSectionEntry(elf->sectionHeaderNameEntryIndex,elf,elfFile);
-
- return (char*)(NameTable+NameIndex);
-}
-
-u64 GetELFSectionEntryType(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_type,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_type,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFSectionEntryFlags(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_flags,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_flags,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFSectionEntryAddress(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_addr,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_addr,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFSectionEntryFileOffset(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_offset,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_offset,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFSectionEntrySize(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_size,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_size,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFSectionEntryAlignment(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->sectionTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u64(shdr->sh_addralign,elf->IsLittleEndian);
- }
- else{
- elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(index,elf,elfFile);
- return u8_to_u32(shdr->sh_addralign,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-
-u16 GetElfSectionIndexFromName(char *name, elf_context *elf, u8 *elfFile)
-{
- for(int i = 0; i < elf->sectionTableEntryCount; i++){
- if(strcmp(name,elf->sections[i].name) == 0) return i;
- }
- return 0; // Assuming 0 is always empty
-}
-
bool IsBss(elf_section_entry *section)
{
return (section->type == SHT_NOBITS && section->flags == (SHF_WRITE | SHF_ALLOC));
@@ -707,153 +214,7 @@ bool IsText(elf_section_entry *section)
return (section->type == SHT_PROGBITS && section->flags == (SHF_ALLOC | SHF_EXECINSTR));
}
-/* ProgramHeader Functions */
-
-u8* GetELFProgramHeader(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return NULL;
-
- return (elfFile + elf->programTableOffset + elf->programTableEntrySize*index);
-}
-
-u8* GetELFProgramEntry(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return NULL;
-
- return (u8*) (elfFile + GetELFProgramEntryFileOffset(index,elf,elfFile));
-
- return NULL;
-}
-
-u64 GetELFProgramEntryType(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_type,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_type,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryFlags(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_flags,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_flags,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryFileSize(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_filesz,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_filesz,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryFileOffset(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_offset,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_offset,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryMemorySize(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_memsz,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_memsz,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryVAddress(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_vaddr,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_vaddr,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-u64 GetELFProgramEntryPAddress(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_paddr,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_paddr,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
-
-u64 GetELFProgramEntryAlignment(u16 index, elf_context *elf, u8 *elfFile)
-{
- if(index >= elf->programTableEntryCount) return 0;
-
- if(elf->Is64bit){
- elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u64(phdr->p_align,elf->IsLittleEndian);
- }
- else{
- elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(index,elf,elfFile);
- return u8_to_u32(phdr->p_align,elf->IsLittleEndian);
- }
-
- return 0;
-}
-
+/* Program Segment Functions */
void InitSegment(elf_segment *segment)
{
memset(segment, 0, sizeof(elf_segment));
@@ -880,7 +241,12 @@ void AddSegmentSection(elf_segment *segment, elf_section_entry *section)
segment->sectionNum++;
}
-int CreateElfSegments(elf_context *elf, u8 *elfFile)
+bool IsIgnoreSection(elf_section_entry info)
+{
+ return !(info.flags & SHF_ALLOC);//(info.type != SHT_PROGBITS && info.type != SHT_NOBITS && info.type != SHT_INIT_ARRAY && info.type != SHT_FINI_ARRAY && info.type != SHT_ARM_EXIDX);
+}
+
+int CreateElfSegments(elf_context *elf)
{
// Interate through Each Program Header
elf->activeSegments = 0;
@@ -945,9 +311,4 @@ int CreateElfSegments(elf_context *elf, u8 *elfFile)
}
return 0;
-}
-
-bool IsIgnoreSection(elf_section_entry info)
-{
- return (info.type != SHT_PROGBITS && info.type != SHT_NOBITS && info.type != SHT_INIT_ARRAY && info.type != SHT_FINI_ARRAY && info.type != SHT_ARM_EXIDX);
-}
+}
\ No newline at end of file
diff --git a/makerom/elf.h b/makerom/elf.h
index a6b856a..c568a5b 100644
--- a/makerom/elf.h
+++ b/makerom/elf.h
@@ -1,9 +1,9 @@
#pragma once
-typedef enum
+typedef enum elf_errors
{
NOT_ELF_FILE = -10,
- NOT_ARM_ELF = -11,
+ NOT_CTR_ARM_ELF = -11,
NON_EXECUTABLE_ELF = -12,
ELF_SECTION_NOT_FOUND = -13,
NOT_FIND_TEXT_SEGMENT = -14,
@@ -13,35 +13,101 @@ typedef enum
ELF_SEGMENTS_NOT_FOUND = -18,
} elf_errors;
-typedef struct
+typedef enum elf_section_type
{
- char *name;
- u64 type;
- u64 flags;
- u8 *ptr;
- u64 offsetInFile;
- u64 size;
- u64 address;
- u64 alignment;
+ SHT_NULL,
+ SHT_PROGBITS,
+ SHT_SYMTAB,
+ SHT_STRTAB,
+ SHT_RELA,
+ SHT_HASH,
+ SHT_DYNAMIC,
+ SHT_NOTE,
+ SHT_NOBITS,
+ SHT_REL,
+ SHT_SHLIB,
+ SHT_DYNSYM,
+ SHT_UNKNOWN12,
+ SHT_UNKNOWN13,
+ SHT_INIT_ARRAY,
+ SHT_FINI_ARRAY,
+ SHT_PREINIT_ARRAY,
+ SHT_GROUP,
+ SHT_SYMTAB_SHNDX,
+ SHT_NUM,
+ SHT_ARM_EXIDX = 0x70000001,
+ SHT_ARM_PREEMPTMAP,
+ SHT_ARM_ATTRIBUTES,
+ SHT_ARM_DEBUGOVERLAY,
+ SHT_ARM_OVERLAYSECTION
+} elf_section_type;
+
+typedef enum elf_section_flag
+{
+ SHF_WRITE = 0x1,
+ SHF_ALLOC = 0x2,
+ SHF_EXECINSTR = 0x4,
+ SHF_MERGE = 0x10,
+ SHF_STRINGS = 0x20,
+ SHF_INFO_LINK = 0x40,
+ SHF_LINK_ORDER = 0x80,
+ SHF_OS_NONCONFORMING = 0x100,
+ SHF_GROUP = 0x200,
+ SHF_TLS = 0x400
+} elf_section_flag;
+
+typedef struct elf_section_entry
+{
+ const char *name;
+ u32 type;
+ u32 flags;
+ const u8 *ptr;
+ u32 offsetInFile;
+ u32 size;
+ u32 address;
+ u32 alignment;
} elf_section_entry;
-typedef struct
+typedef enum elf_program_type
{
- u64 type;
- u64 flags;
- u8 *ptr;
- u64 offsetInFile;
- u64 sizeInFile;
- u64 virtualAddress;
- u64 physicalAddress;
- u64 sizeInMemory;
- u64 alignment;
+ PT_NULL,
+ PT_LOAD,
+ PT_DYNAMIC,
+ PT_INTERP,
+ PT_NOTE,
+ PT_SHLIB,
+ PT_PHDR,
+} elf_program_type;
+
+typedef enum elf_program_flag
+{
+ PF_X = 0x1,
+ PF_W = 0x2,
+ PF_R = 0x4,
+ PF_CTRSDK = 0x80000000,
+
+ PF_TEXT = (PF_R|PF_X),
+ PF_DATA = (PF_R|PF_W),
+ PF_RODATA = PF_R
+} elf_program_flag;
+
+typedef struct elf_program_entry
+{
+ u32 type;
+ u32 flags;
+ const u8 *ptr;
+ u32 offsetInFile;
+ u32 sizeInFile;
+ u32 virtualAddress;
+ u32 physicalAddress;
+ u32 sizeInMemory;
+ u32 alignment;
} elf_program_entry;
-typedef struct
+typedef struct elf_segment
{
- char *name;
- u64 vAddr;
+ const char *name;
+ u32 vAddr;
elf_program_entry *header;
u32 sectionNum;
@@ -49,25 +115,17 @@ typedef struct
elf_section_entry *sections;
} elf_segment;
-typedef struct
+typedef struct elf_context
{
- u32 address;
- u32 size;
- u32 maxPageNum;
- u8 *data;
-} code_segment;
+ const u8 *file;
-typedef struct
-{
u32 pageSize;
- bool IsLittleEndian;
- bool Is64bit;
- u64 programTableOffset;
+ u32 programTableOffset;
u16 programTableEntrySize;
u16 programTableEntryCount;
- u64 sectionTableOffset;
+ u32 sectionTableOffset;
u16 sectionTableEntrySize;
u16 sectionTableEntryCount;
@@ -78,7 +136,12 @@ typedef struct
u16 activeSegments;
elf_segment *segments;
-
} elf_context;
-int BuildExeFsCode(ncch_settings *ncchset);
\ No newline at end of file
+bool IsBss(elf_section_entry *section);
+bool IsData(elf_section_entry *section);
+bool IsRoData(elf_section_entry *section);
+bool IsText(elf_section_entry *section);
+
+int GetElfContext(elf_context *elf, const u8 *elfFile);
+void FreeElfContext(elf_context *elf);
\ No newline at end of file
diff --git a/makerom/elf_hdr.h b/makerom/elf_hdr.h
deleted file mode 100644
index 4fb772d..0000000
--- a/makerom/elf_hdr.h
+++ /dev/null
@@ -1,192 +0,0 @@
-#pragma once
-
-static const u32 ELF_MAGIC = 0x7f454c46;
-
-typedef enum
-{
- elf_32_bit = 1,
- elf_64_bit = 2,
-} elf_bit_format_types;
-
-typedef enum
-{
- elf_little_endian = 1,
- elf_big_endian = 2,
-} elf_endianness;
-
-typedef enum
-{
- elf_relocatable = 1,
- elf_executeable = 2,
- elf_shared = 3,
- elf_core = 4,
-} elf_type;
-
-typedef enum
-{
- elf_arm = 0x28,
-} elf_target_architecture;
-
-typedef struct
-{
- u8 magic[4];
- u8 bitFormat;
- u8 endianness;
- u8 elfVersion;
- u8 os;
- u8 padding0[8];
- u8 type[2];
- u8 targetArchitecture[2];
- u8 version[4];
- u8 entryPoint[4];
- u8 programHeaderTableOffset[4];
- u8 sectionHeaderTableOffset[4];
- u8 flags[4];
- u8 headerSize[2];
- u8 programHeaderEntrySize[2];
- u8 programHeaderEntryCount[2];
- u8 sectionTableEntrySize[2];
- u8 sectionHeaderEntryCount[2];
- u8 sectionHeaderNameEntryIndex[2];
-} elf_32_hdr;
-
-typedef struct
-{
- u8 magic[4];
- u8 bitFormat;
- u8 endianness;
- u8 elfVersion;
- u8 os;
- u8 padding0[8];
- u8 type[2];
- u8 targetArchitecture[2];
- u8 version[4];
- u8 entryPoint[8];
- u8 programHeaderTableOffset[8];
- u8 sectionHeaderTableOffset[8];
- u8 flags[4];
- u8 headerSize[2];
- u8 programHeaderEntrySize[2];
- u8 programHeaderEntryCount[2];
- u8 sectionTableEntrySize[2];
- u8 sectionHeaderEntryCount[2];
- u8 sectionHeaderNameEntryIndex[2];
-} elf_64_hdr;
-
-/* taken from elf specs, will not follow global style */
-
-/* Section header. */
-
-/* Legal values for sh_type (section type). */
-
-#define SHT_NULL 0 /* Section header table entry unused */
-#define SHT_PROGBITS 1 /* Program data */
-#define SHT_SYMTAB 2 /* Symbol table */
-#define SHT_STRTAB 3 /* String table */
-#define SHT_RELA 4 /* Relocation entries with addends */
-#define SHT_HASH 5 /* Symbol hash table */
-#define SHT_DYNAMIC 6 /* Dynamic linking information */
-#define SHT_NOTE 7 /* Notes */
-#define SHT_NOBITS 8 /* Program space with no data (bss) */
-#define SHT_REL 9 /* Relocation entries, no addends */
-#define SHT_SHLIB 10 /* Reserved */
-#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
-#define SHT_UNKNOWN12 12
-#define SHT_UNKNOWN13 13
-#define SHT_INIT_ARRAY 14
-#define SHT_FINI_ARRAY 15
-#define SHT_PREINIT_ARRAY 16
-#define SHT_GROUP 17
-#define SHT_SYMTAB_SHNDX 18
-#define SHT_NUM 19
-#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table */
-#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map*/
-#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes */
-#define SHT_ARM_DEBUGOVERLAY 0x70000004
-#define SHT_ARM_OVERLAYSECTION 0x70000005
-
-#define SHF_WRITE 0x01 /* sh_flags */
-#define SHF_ALLOC 0x02
-#define SHF_EXECINSTR 0x04
-#define SHF_MERGE 0x10
-#define SHF_STRINGS 0x20
-#define SHF_INFO_LINK 0x40
-#define SHF_LINK_ORDER 0x80
-#define SHF_OS_NONCONFORMING 0x100
-#define SHF_GROUP 0x200
-#define SHF_TLS 0x400
-
-
-typedef struct
-{
- u8 sh_name[4]; /* Section name (string tbl index) */
- u8 sh_type[4]; /* Section type */
- u8 sh_flags[4]; /* Section flags */
- u8 sh_addr[4]; /* Section virtual addr at execution */
- u8 sh_offset[4]; /* Section file offset */
- u8 sh_size[4]; /* Section size in bytes */
- u8 sh_link[4]; /* Link to another section */
- u8 sh_info[4]; /* Additional section information */
- u8 sh_addralign[4]; /* Section alignment */
- u8 sh_entsize[4]; /* Entry size if section holds table */
-} elf_32_shdr;
-
-typedef struct
-{
- u8 sh_name[8]; /* Section name (string tbl index) */
- u8 sh_type[8]; /* Section type */
- u8 sh_flags[8]; /* Section flags */
- u8 sh_addr[8]; /* Section virtual addr at execution */
- u8 sh_offset[8]; /* Section file offset */
- u8 sh_size[8]; /* Section size in bytes */
- u8 sh_link[8]; /* Link to another section */
- u8 sh_info[8]; /* Additional section information */
- u8 sh_addralign[8]; /* Section alignment */
- u8 sh_entsize[8]; /* Entry size if section holds table */
-} elf_64_shdr;
-
-/* Program segment header. */
-
-/* p_type legal values */
-#define PT_NULL 0 /* Program header table entry unused */
-#define PT_LOAD 1 /* Loadable program segment */
-#define PT_DYNAMIC 2 /* Dynamic linking information */
-#define PT_INTERP 3 /* Program interpreter */
-#define PT_NOTE 4 /* Auxiliary information */
-#define PT_SHLIB 5 /* Reserved */
-#define PT_PHDR 6 /* Entry for header table itself */
-#define PT_NUM 7 /* Number of defined types. */
-#define PT_LOOS 0x60000000 /* Start of OS-specific */
-#define PT_HIOS 0x6fffffff /* End of OS-specific */
-#define PT_LOPROC 0x70000000 /* Start of processor-specific */
-#define PT_HIPROC 0x7fffffff /* End of processor-specific */
-
-#define PF_CTRSDK 0x80000000
-#define PF_R 0x4 /* p_flags */
-#define PF_W 0x2
-#define PF_X 0x1
-
-
-typedef struct
-{
- u8 p_type[4]; /* Segment type */
- u8 p_offset[4]; /* Segment file offset */
- u8 p_vaddr[4]; /* Segment virtual address */
- u8 p_paddr[4]; /* Segment physical address */
- u8 p_filesz[4]; /* Segment size in file */
- u8 p_memsz[4]; /* Segment size in memory */
- u8 p_flags[4]; /* Segment flags */
- u8 p_align[4]; /* Segment alignment */
-} elf_32_phdr;
-
-typedef struct
-{
- u8 p_type[8]; /* Segment type */
- u8 p_flags[8]; /* Segment flags */
- u8 p_offset[8]; /* Segment file offset */
- u8 p_vaddr[8]; /* Segment virtual address */
- u8 p_paddr[8]; /* Segment physical address */
- u8 p_filesz[8]; /* Segment size in file */
- u8 p_memsz[8]; /* Segment size in memory */
- u8 p_align[8]; /* Segment alignment */
-} elf_64_phdr;
\ No newline at end of file
diff --git a/makerom/exheader.c b/makerom/exheader.c
index 0d4b0bf..0d8065b 100644
--- a/makerom/exheader.c
+++ b/makerom/exheader.c
@@ -129,8 +129,6 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *
exhdrset->exHdr = (extended_hdr*)ncchset->sections.exhdr.buffer;
exhdrset->acexDesc = (access_descriptor*)ncchset->sections.acexDesc.buffer;
- /* BSS Size */
- u32_to_u8(exhdrset->exHdr->codeSetInfo.bssSize,ncchset->codeDetails.bssSize,LE);
/* Data */
u32_to_u8(exhdrset->exHdr->codeSetInfo.data.address,ncchset->codeDetails.rwAddress,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.data.codeSize,ncchset->codeDetails.rwSize,LE);
@@ -143,12 +141,16 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.address,ncchset->codeDetails.textAddress,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.codeSize,ncchset->codeDetails.textSize,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.numMaxPages,ncchset->codeDetails.textMaxPages,LE);
+ /* BSS Size */
+ u32_to_u8(exhdrset->exHdr->codeSetInfo.bssSize, ncchset->codeDetails.bssSize, LE);
+ /* Stack Size */
+ u32_to_u8(exhdrset->exHdr->codeSetInfo.stackSize, ncchset->codeDetails.stackSize, LE);
/* Set Simple Flags */
if(ncchset->options.CompressCode)
- exhdrset->exHdr->codeSetInfo.flag |= infoflag_COMPRESS_EXEFS_0;
- if(ncchset->options.UseOnSD)
- exhdrset->exHdr->codeSetInfo.flag |= infoflag_SD_APPLICATION;
+ exhdrset->exHdr->codeSetInfo.compressExeFs0 = true;
+ if (ncchset->options.UseOnSD)
+ exhdrset->exHdr->codeSetInfo.useOnSd = true;
if(!ncchset->options.UseRomFS)
exhdrset->exHdr->arm11SystemLocalCapabilities.storageInfo.otherAttributes |= attribute_NOT_USE_ROMFS;
@@ -195,13 +197,6 @@ int get_ExHeaderCodeSetInfo(exhdr_CodeSetInfo *CodeSetInfo, rsf_settings *rsf)
else
strncpy((char*)CodeSetInfo->name, DEFAULT_EXHEADER_NAME, 8);
- /* Stack Size */
- if(rsf->SystemControlInfo.StackSize)
- u32_to_u8(CodeSetInfo->stackSize, strtoul(rsf->SystemControlInfo.StackSize,NULL,0), LE);
- else{
- ErrorParamNotFound("SystemControlInfo/StackSize");
- return EXHDR_BAD_RSF_OPT;
- }
/* Remaster Version */
if(rsf->SystemControlInfo.RemasterVersion)
u16_to_u8(CodeSetInfo->remasterVersion, strtol(rsf->SystemControlInfo.RemasterVersion,NULL,0), LE);
@@ -311,93 +306,87 @@ int SetARM11SystemLocalInfoFlags(exhdr_ARM11SystemLocalCapabilities *arm11, rsf_
return EXHDR_BAD_RSF_OPT;
}
- /* Flag[0] */
- arm11->flag[0] |= rsf->AccessControlInfo.EnableL2Cache;
+ /* Defaults */
+ arm11->enableL2Cache = false;
+ arm11->cpuSpeed = cpuspeed_268MHz;
+ arm11->systemModeExt = sysmode_ext_LEGACY;
+ arm11->affinityMask = 0;
+ arm11->idealProcessor = 0;
+ arm11->systemMode = sysmode_64MB;
+
+ /* flag[0] */
+ arm11->enableL2Cache |= rsf->AccessControlInfo.EnableL2Cache;
if (rsf->AccessControlInfo.CpuSpeed) {
if(strcasecmp(rsf->AccessControlInfo.CpuSpeed, "268mhz") == 0)
- arm11->flag[0] |= cpuspeed_268MHz << 1;
+ arm11->cpuSpeed |= cpuspeed_268MHz;
else if(strcasecmp(rsf->AccessControlInfo.CpuSpeed, "804mhz") == 0)
- arm11->flag[0] |= cpuspeed_804MHz << 1;
+ arm11->cpuSpeed |= cpuspeed_804MHz;
else {
fprintf(stderr, "[EXHEADER ERROR] Invalid cpu speed: 0x%s\n", rsf->AccessControlInfo.CpuSpeed);
return EXHDR_BAD_RSF_OPT;
}
}
- else
- arm11->flag[0] |= cpuspeed_268MHz << 1;
- /* Flag[1] (SystemModeExt) */
+ /* flag[1] (SystemModeExt) */
if (rsf->AccessControlInfo.SystemModeExt) {
if (strcasecmp(rsf->AccessControlInfo.SystemModeExt, "Legacy") == 0)
- arm11->flag[1] = sysmode_ext_LEGACY;
+ arm11->systemModeExt = sysmode_ext_LEGACY;
else if (strcasecmp(rsf->AccessControlInfo.SystemModeExt, "124MB") == 0)
- arm11->flag[1] = sysmode_ext_124MB;
+ arm11->systemModeExt = sysmode_ext_124MB;
else if (strcasecmp(rsf->AccessControlInfo.SystemModeExt, "178MB") == 0)
- arm11->flag[1] = sysmode_ext_178MB;
+ arm11->systemModeExt = sysmode_ext_178MB;
else {
fprintf(stderr, "[EXHEADER ERROR] Unexpected SystemModeExt: %s\n", rsf->AccessControlInfo.SystemModeExt);
return EXHDR_BAD_RSF_OPT;
}
}
- else {
- arm11->flag[1] = sysmode_ext_LEGACY;
- }
- /* Flag[2] */
- u8 affinityMask = 0;
- u8 idealProcessor = 0;
- u8 systemMode = 0;
-
+ /* flag[2] */
if(rsf->AccessControlInfo.AffinityMask){
- affinityMask = strtol(rsf->AccessControlInfo.AffinityMask,NULL,0);
- if(affinityMask > 1){
- fprintf(stderr,"[EXHEADER ERROR] Unexpected AffinityMask: %d. Expected range: 0x0 - 0x1\n",affinityMask);
+ arm11->affinityMask = strtol(rsf->AccessControlInfo.AffinityMask,NULL,0);
+ if(arm11->affinityMask > 1){
+ fprintf(stderr,"[EXHEADER ERROR] Unexpected AffinityMask: %d. Expected range: 0x0 - 0x1\n", arm11->affinityMask);
return EXHDR_BAD_RSF_OPT;
}
}
if(rsf->AccessControlInfo.IdealProcessor){
- idealProcessor = strtol(rsf->AccessControlInfo.IdealProcessor,NULL,0);
- if(idealProcessor > 1){
- fprintf(stderr,"[EXHEADER ERROR] Unexpected IdealProcessor: %d. Expected range: 0x0 - 0x1\n",idealProcessor);
+ arm11->idealProcessor = strtol(rsf->AccessControlInfo.IdealProcessor,NULL,0);
+ if(arm11->idealProcessor > 1){
+ fprintf(stderr,"[EXHEADER ERROR] Unexpected IdealProcessor: %d. Expected range: 0x0 - 0x1\n", arm11->idealProcessor);
return EXHDR_BAD_RSF_OPT;
}
}
if(rsf->AccessControlInfo.SystemMode){
if (strcasecmp(rsf->AccessControlInfo.SystemMode, "64MB") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "prod") == 0)
- systemMode = sysmode_64MB;
+ arm11->systemMode = sysmode_64MB;
//else if (strcasecmp(rsf->AccessControlInfo.SystemMode, "UNK") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "null") == 0)
- // systemMode = sysmode_UNK;
+ // arm11->systemMode = sysmode_UNK;
else if (strcasecmp(rsf->AccessControlInfo.SystemMode, "96MB") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "dev1") == 0)
- systemMode = sysmode_96MB;
+ arm11->systemMode = sysmode_96MB;
else if (strcasecmp(rsf->AccessControlInfo.SystemMode, "80MB") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "dev2") == 0)
- systemMode = sysmode_80MB;
+ arm11->systemMode = sysmode_80MB;
else if (strcasecmp(rsf->AccessControlInfo.SystemMode, "72MB") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "dev3") == 0)
- systemMode = sysmode_72MB;
+ arm11->systemMode = sysmode_72MB;
else if (strcasecmp(rsf->AccessControlInfo.SystemMode, "32MB") == 0 || strcasecmp(rsf->AccessControlInfo.SystemMode, "dev4") == 0)
- systemMode = sysmode_32MB;
+ arm11->systemMode = sysmode_32MB;
else {
fprintf(stderr, "[EXHEADER ERROR] Unexpected SystemMode: %s\n", rsf->AccessControlInfo.SystemMode);
return EXHDR_BAD_RSF_OPT;
}
}
- else {
- systemMode = sysmode_64MB;
- }
- arm11->flag[2] = (u8)(systemMode << 4 | affinityMask << 2 | idealProcessor);
/* flag[3] (Thread Priority) */
if(rsf->AccessControlInfo.Priority){
- u8 priority = strtoul(rsf->AccessControlInfo.Priority,NULL,0);
+ arm11->threadPriority = strtoul(rsf->AccessControlInfo.Priority,NULL,0);
if(GetAppType(rsf) == processtype_APPLICATION)
- priority += 32;
- if(priority > 127){
- fprintf(stderr,"[EXHEADER ERROR] Invalid Priority: %d\n",priority);
+ arm11->threadPriority += 32;
+ if(arm11->threadPriority < 0){
+ fprintf(stderr,"[EXHEADER ERROR] Invalid Priority: %d\n", arm11->threadPriority);
return EXHDR_BAD_RSF_OPT;
}
- arm11->flag[3] = priority;
}
else{
ErrorParamNotFound("AccessControlInfo/Priority");
diff --git a/makerom/exheader.h b/makerom/exheader.h
index 8d91e56..d3ef983 100644
--- a/makerom/exheader.h
+++ b/makerom/exheader.h
@@ -121,7 +121,14 @@ typedef struct
{
u8 name[8];
u8 padding0[5];
- u8 flag;
+ union {
+ u8 flag;
+ struct {
+ u8 compressExeFs0 : 1;
+ u8 useOnSd : 1;
+ };
+ };
+
u8 remasterVersion[2]; // le u16
exhdr_CodeSegmentInfo text;
u8 stackSize[4]; // le u32
@@ -151,7 +158,23 @@ typedef struct
{
u8 programId[8];
u8 coreVersion[4];
- u8 flag[4];
+ union {
+ u8 flag[4];
+ struct {
+ u8 enableL2Cache : 1;
+ u8 cpuSpeed : 1;
+ u8: 6;
+
+ u8 systemModeExt : 4;
+ u8: 4;
+
+ u8 idealProcessor : 2;
+ u8 affinityMask : 2;
+ u8 systemMode : 4;
+
+ s8 threadPriority;
+ };
+ };
u8 resourceLimitDescriptor[16][2];
exhdr_StorageInfo storageInfo;
u8 serviceAccessControl[34][8]; // Those char[8] server names
diff --git a/makerom/makerom.vcxproj b/makerom/makerom.vcxproj
index 472d5b4..ecc931c 100644
--- a/makerom/makerom.vcxproj
+++ b/makerom/makerom.vcxproj
@@ -97,6 +97,7 @@
+
@@ -105,7 +106,6 @@
-
@@ -198,6 +198,7 @@
+
diff --git a/makerom/makerom.vcxproj.filters b/makerom/makerom.vcxproj.filters
index 5fb196a..049b9f8 100644
--- a/makerom/makerom.vcxproj.filters
+++ b/makerom/makerom.vcxproj.filters
@@ -72,9 +72,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -339,6 +336,9 @@
Resource Files\DESC
+
+ Header Files
+
@@ -470,6 +470,9 @@
Source Files\polarssl
+
+ Source Files
+
diff --git a/makerom/ncch.c b/makerom/ncch.c
index 4a8d00e..69621d4 100644
--- a/makerom/ncch.c
+++ b/makerom/ncch.c
@@ -3,7 +3,7 @@
#include "ncch_build.h"
#include "exheader_build.h"
#include "exheader_read.h"
-#include "elf.h"
+#include "code.h"
#include "exefs_build.h"
#include "exefs_read.h"
#include "romfs.h"
diff --git a/makerom/ncch_build.h b/makerom/ncch_build.h
index 96f47c4..d97ab7b 100644
--- a/makerom/ncch_build.h
+++ b/makerom/ncch_build.h
@@ -70,6 +70,7 @@ typedef struct
u32 rwSize;
u32 rwMaxPages;
u32 bssSize;
+ u32 stackSize;
} codeDetails;
struct
diff --git a/makerom/utils.c b/makerom/utils.c
index 5a97fb6..dd08733 100644
--- a/makerom/utils.c
+++ b/makerom/utils.c
@@ -368,7 +368,7 @@ int fseek_64(FILE *fp, u64 file_pos)
}
//Data Size conversion
-u16 u8_to_u16(u8 *value, u8 endianness)
+u16 u8_to_u16(const u8 *value, u8 endianness)
{
u16 new_value;
switch(endianness){
@@ -378,7 +378,7 @@ u16 u8_to_u16(u8 *value, u8 endianness)
return new_value;
}
-u32 u8_to_u32(u8 *value, u8 endianness)
+u32 u8_to_u32(const u8 *value, u8 endianness)
{
u32 new_value;
switch(endianness){
@@ -389,7 +389,7 @@ u32 u8_to_u32(u8 *value, u8 endianness)
}
-u64 u8_to_u64(u8 *value, u8 endianness)
+u64 u8_to_u64(const u8 *value, u8 endianness)
{
u64 ret = 0;
switch(endianness){
diff --git a/makerom/utils.h b/makerom/utils.h
index c479f11..6d30d51 100644
--- a/makerom/utils.h
+++ b/makerom/utils.h
@@ -59,9 +59,9 @@ void ReadFile64(void *outbuff, u64 size, u64 offset, FILE *file);
int fseek_64(FILE *fp, u64 file_pos);
//Data Size conversion
-u16 u8_to_u16(u8 *value, u8 endianness);
-u32 u8_to_u32(u8 *value, u8 endianness);
-u64 u8_to_u64(u8 *value, u8 endianness);
+u16 u8_to_u16(const u8 *value, u8 endianness);
+u32 u8_to_u32(const u8 *value, u8 endianness);
+u64 u8_to_u64(const u8 *value, u8 endianness);
int u16_to_u8(u8 *out_value, u16 in_value, u8 endianness);
int u32_to_u8(u8 *out_value, u32 in_value, u8 endianness);
int u64_to_u8(u8 *out_value, u64 in_value, u8 endianness);