From 83d4a1fcf30d15547080a9a63c80e7d665604bc2 Mon Sep 17 00:00:00 2001 From: jakcron Date: Thu, 17 Dec 2015 16:20:03 +0800 Subject: [PATCH] [makerom] Fixed ELF related code. Addresses #14 --- makerom/code.c | 244 +++++++++++++-------------------------- makerom/elf.c | 250 +++++++++++----------------------------- makerom/elf.h | 65 ++++------- makerom/rsf_settings.c | 4 - makerom/user_settings.h | 3 - 5 files changed, 170 insertions(+), 396 deletions(-) diff --git a/makerom/code.c b/makerom/code.c index 07ee74a..22b64bf 100644 --- a/makerom/code.c +++ b/makerom/code.c @@ -5,32 +5,33 @@ #include "exheader_read.h" #include "code.h" -const char *SDK_PLAINREGION_SEGMENT_NAME = ".module_id"; +const u32 CTR_PAGE_SIZE = 0x1000; +const u32 DEFAULT_STACK_SIZE = 0x4000; // 10KB typedef struct code_segment { u32 address; + u32 memSize; + u32 pageNum; + u32 size; - u32 maxPageNum; u8 *data; } code_segment; -u32 GetPageSize(ncch_settings *set) +u32 SizeToPage(u32 memorySize) { - if (set->rsfSet->Option.PageSize) - return strtoul(set->rsfSet->Option.PageSize, NULL, 10); - return 0x1000; + return align(memorySize, CTR_PAGE_SIZE) / CTR_PAGE_SIZE; } -u32 SizeToPage(u32 memorySize, elf_context *elf) +u32 PageToSize(u32 pageNum) { - return align(memorySize, elf->pageSize) / elf->pageSize; + return pageNum * CTR_PAGE_SIZE; } 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); + set->sections.plainRegion.buffer = calloc(set->sections.plainRegion.size, 1); 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; @@ -99,117 +100,61 @@ int ImportExeFsCodeBinaryFromFile(ncch_settings *set) return 0; } -int GetBSSFromElf(elf_context *elf, ncch_settings *set) +int ImportPlainRegionFromElf(elf_context *elf, ncch_settings *set) { - set->codeDetails.bssSize = 0; + elf_segment segment = elf_GetSegments(elf)[elf_SegmentNum(elf) - 1]; - for (int i = 0; i < elf->sectionTableEntryCount; i++) { - if (IsBss(&elf->sections[i])) - set->codeDetails.bssSize = elf->sections[i].size; + /* Check last segment + If the last segment is RO segment, this must be an SDK .module_id segment */ + if (segment.flags != PF_RODATA) { + /* not a RO segment */ + return 0; } - 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) { + if (segment.fileSize > 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); + set->sections.plainRegion.size = align(segment.fileSize, set->options.blockSize); + set->sections.plainRegion.buffer = calloc(set->sections.plainRegion.size, 1); + if (!set->sections.plainRegion.buffer) { fprintf(stderr, "[CODE ERROR] Not enough memory\n"); return MEM_ERROR; } /* Copy Plain Region */ - memcpy(set->sections.plainRegion.buffer, elf->file + offset, size); + memcpy(set->sections.plainRegion.buffer, segment.ptr, segment.fileSize); } - return 0; } int CreateCodeSegmentFromElf(code_segment *out, elf_context *elf, u64 segment_flags) { - memset(out, 0, sizeof(code_segment)); + u32 segmentNum = elf_SegmentNum(elf); + const elf_segment *segments = elf_GetSegments(elf); - 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) + /* Find segment */ + for (u16 i = 0; i < segmentNum; i++) { + /* Skip SDK ELF plain region + 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; - //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++; - } + /* Found segment */ + if ((segments[i].flags & ~PF_CTRSDK) == segment_flags) { + out->address = segments[i].vAddr; + out->memSize = segments[i].memSize; + out->pageNum = SizeToPage(out->memSize); + out->size = segments[i].fileSize; + out->data = malloc(out->size); + if (!out->data) { fprintf(stderr, "[CODE ERROR] Not enough memory\n"); return MEM_ERROR; } + memcpy(out->data, segments[i].ptr, out->size); + return 0; } } - /* 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); + /* Stub struct data */ + out->address = 0; + out->memSize = 0; + out->pageNum = 0; + out->size = 0; + out->data = NULL; return 0; } @@ -217,37 +162,33 @@ 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; + if (CreateCodeSegmentFromElf(&text, elf, PF_TEXT) == MEM_ERROR || CreateCodeSegmentFromElf(&rodata, elf, PF_RODATA) == MEM_ERROR || CreateCodeSegmentFromElf(&rwdata, elf, PF_DATA) == MEM_ERROR) + return MEM_ERROR; /* Checking the existence of essential ELF Segments */ if (!text.size) return NOT_FIND_TEXT_SEGMENT; if (!rwdata.size) return NOT_FIND_DATA_SEGMENT; + /* Calculateing BSS size */ + set->codeDetails.bssSize = rwdata.memSize - rwdata.size; + /* Allocating Buffer for ExeFs Code */ - u32 size = (text.maxPageNum + rodata.maxPageNum + rwdata.maxPageNum)*elf->pageSize; + u32 size = PageToSize(text.pageNum + rodata.pageNum + rwdata.pageNum); 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); + u8 *textPos = (code + text.address - text.address); + u8 *rodataPos = (code + rodata.address - text.address); + u8 *rwdataPos = (code + rwdata.address - text.address); 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 */ + /* Compressing if needed */ if (set->options.CompressCode) { if (set->options.verbose) printf("[CODE] Compressing code... "); @@ -265,31 +206,32 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set) /* Setting code_segment data and freeing original buffers */ set->codeDetails.textAddress = text.address; - set->codeDetails.textMaxPages = text.maxPageNum; - set->codeDetails.textSize = text.size; + set->codeDetails.textMaxPages = text.pageNum; + set->codeDetails.textSize = text.memSize; if (text.size) free(text.data); set->codeDetails.roAddress = rodata.address; - set->codeDetails.roMaxPages = rodata.maxPageNum; - set->codeDetails.roSize = rodata.size; + set->codeDetails.roMaxPages = rodata.pageNum; + set->codeDetails.roSize = rodata.memSize; if (rodata.size) free(rodata.data); set->codeDetails.rwAddress = rwdata.address; - set->codeDetails.rwMaxPages = rwdata.maxPageNum; - set->codeDetails.rwSize = rwdata.size; + set->codeDetails.rwMaxPages = rwdata.pageNum; + set->codeDetails.rwSize = rwdata.memSize; 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; + set->codeDetails.stackSize = DEFAULT_STACK_SIZE; + fprintf(stderr, "[CODE WARNING] \"SystemControlInfo/StackSize\" not specified, defaulting to 0x%x bytes\n", DEFAULT_STACK_SIZE); } /* Return */ return 0; } +/* void PrintElfContext(elf_context *elf) { printf("[ELF] Program Table Data\n"); @@ -303,27 +245,17 @@ void PrintElfContext(elf_context *elf) 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); + printf(" > Size(Memory): 0x%x\n", elf->segments[i].header->sizeInMemory); + printf(" > Size(File): 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) { @@ -331,10 +263,11 @@ int BuildExeFsCode(ncch_settings *set) 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 + if (!set->options.IsBuildingCodeSection) { // Import ExeFs Code from file and return + if (set->componentFilePtrs.plainregion) // Import PlainRegion from file + if ((result = ImportPlainRegionFromFile(set))) return result; return ImportExeFsCodeBinaryFromFile(set); + } /* Import ELF */ u8 *elfFile = malloc(set->componentFilePtrs.elfSize); @@ -345,26 +278,12 @@ int BuildExeFsCode(ncch_settings *set) 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; - } + elf_context elf; - if ((result = GetElfContext(elf, elfFile))) goto finish; + if ((result = elf_Init(&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; + if ((result = ImportPlainRegionFromElf(&elf, set))) goto finish; + if ((result = CreateExeFsCode(&elf, set))) goto finish; finish: switch (result) { @@ -389,8 +308,7 @@ finish: fprintf(stderr, "[CODE ERROR] Failed to process ELF file (%d)\n", result); } - FreeElfContext(elf); + elf_Free(&elf); free(elfFile); - free(elf); return result; } diff --git a/makerom/elf.c b/makerom/elf.c index 6aad3ef..a934817 100644 --- a/makerom/elf.c +++ b/makerom/elf.c @@ -82,43 +82,12 @@ typedef struct elf_phdr } elf_phdr; // ELF Functions -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); -bool IsIgnoreSection(elf_section_entry info); - -// ELF Functions - -int GetElfContext(elf_context *elf, const u8 *elfFile) -{ - elf->file = elfFile; - - int result; - - if((result = ReadElfHdr(elf))) return result; - if((result = GetElfSectionEntries(elf))) return result; - if((result = GetElfProgramEntries(elf))) return result; - if((result = CreateElfSegments(elf))) return result; - - return 0; -} - -void FreeElfContext(elf_context *elf) -{ - for (int i = 0; i < elf->activeSegments; i++) - free(elf->segments[i].sections); - free(elf->sections); - free(elf->programHeaders); - free(elf->segments); -} - -int ReadElfHdr(elf_context *elf) +int elf_ProcessHeader(elf_context *elf) { const elf_hdr *hdr = (const elf_hdr*)elf->file; + /* Check conditions for valid CTR ELF */ if (u8_to_u32(hdr->magic, BE) != ELF_MAGIC) return NOT_ELF_FILE; if (hdr->bitFormat != elf_32_bit) @@ -130,185 +99,96 @@ int ReadElfHdr(elf_context *elf) if (u8_to_u16(hdr->type, LE) != elf_executeable) return NON_EXECUTABLE_ELF; - elf->programTableOffset = u8_to_u32(hdr->programHeaderTableOffset, LE); - elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize, LE); - elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount, LE); + elf->phdrOffset = u8_to_u32(hdr->programHeaderTableOffset, LE); + elf->segmentNum = u8_to_u16(hdr->programHeaderEntryCount, LE); + elf->segments = calloc(elf->segmentNum, sizeof(elf_segment)); + if (!elf->segments) { + fprintf(stderr, "[ELF ERROR] Not enough memory\n"); + return MEM_ERROR; + } - elf->sectionTableOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE); - elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize, LE); - elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount, LE); - - elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE); + elf->shdrOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE); + elf->shdrNameIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE); + elf->sectionNum = u8_to_u16(hdr->sectionHeaderEntryCount, LE); + elf->sections = calloc(elf->sectionNum, sizeof(elf_section)); + if (!elf->sections) { + fprintf(stderr, "[ELF ERROR] Not enough memory\n"); + return MEM_ERROR; + } return 0; } -int GetElfSectionEntries(elf_context *elf) +void elf_PopulateSections(elf_context *elf) { - elf->sections = calloc(elf->sectionTableEntryCount,sizeof(elf_section_entry)); - if(!elf->sections) { - fprintf(stderr,"[ELF ERROR] Not enough memory\n"); - return MEM_ERROR; - } + const elf_shdr *shdr = (const elf_shdr *)(elf->file + elf->shdrOffset); + const char *nameTable = (const char*)(elf->file + u8_to_u32(shdr[elf->shdrNameIndex].offset, LE)); - 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++){ + for (int i = 0; i < elf->sectionNum; i++) { 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].fileOffset = 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].ptr = elf->file + elf->sections[i].fileOffset; + elf->sections[i].vAddr = u8_to_u32(shdr[i].addr, LE); elf->sections[i].alignment = u8_to_u32(shdr[i].addralign, LE); } +} + +void elf_PopulateSegments(elf_context *elf) +{ + const elf_phdr *phdr = (const elf_phdr *)(elf->file + elf->phdrOffset); + + for (int i = 0; i < elf->segmentNum; i++) { + elf->segments[i].type = u8_to_u32(phdr[i].type, LE); + elf->segments[i].flags = u8_to_u32(phdr[i].flags, LE); + elf->segments[i].fileOffset = u8_to_u32(phdr[i].offset, LE); + elf->segments[i].fileSize = u8_to_u32(phdr[i].filesz, LE); + elf->segments[i].ptr = elf->file + elf->segments[i].fileOffset; + elf->segments[i].pAddr = u8_to_u32(phdr[i].paddr, LE); + elf->segments[i].vAddr = u8_to_u32(phdr[i].vaddr, LE); + elf->segments[i].memSize = u8_to_u32(phdr[i].memsz, LE); + elf->segments[i].alignment = u8_to_u32(phdr[i].align, LE); + } +} + +int elf_Init(elf_context *elf, const u8 *elfFile) +{ + elf->file = elfFile; + + int result; + + if((result = elf_ProcessHeader(elf))) return result; + + elf_PopulateSections(elf); + elf_PopulateSegments(elf); return 0; } -int GetElfProgramEntries(elf_context *elf) +void elf_Free(elf_context *elf) { - elf->programHeaders = calloc(elf->programTableEntryCount,sizeof(elf_program_entry)); - if(!elf->programHeaders) { - fprintf(stderr,"[ELF ERROR] Not enough memory\n"); - 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 = 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; + free(elf->sections); + free(elf->segments); + memset(elf, 0, sizeof(elf_context)); } -/* Section Hdr Functions */ - -bool IsBss(elf_section_entry *section) +u16 elf_SectionNum(elf_context *ctx) { - return (section->type == SHT_NOBITS && section->flags == (SHF_WRITE | SHF_ALLOC)); + return ctx->sectionNum; } -bool IsData(elf_section_entry *section) +const elf_section* elf_GetSections(elf_context *ctx) { - return (section->type == SHT_PROGBITS && section->flags == (SHF_WRITE | SHF_ALLOC)); + return ctx->sections; } -bool IsRoData(elf_section_entry *section) +u16 elf_SegmentNum(elf_context *ctx) { - return (section->type == SHT_PROGBITS && section->flags == SHF_ALLOC); + return ctx->segmentNum; } -bool IsText(elf_section_entry *section) +const elf_segment* elf_GetSegments(elf_context *ctx) { - return (section->type == SHT_PROGBITS && section->flags == (SHF_ALLOC | SHF_EXECINSTR)); + return ctx->segments; } - -/* Program Segment Functions */ -void InitSegment(elf_segment *segment) -{ - memset(segment, 0, sizeof(elf_segment)); - - segment->sectionNumMax = 10; - segment->sectionNum = 0; - segment->sections = calloc(segment->sectionNumMax, sizeof(elf_section_entry)); -} - -void AddSegmentSection(elf_segment *segment, elf_section_entry *section) -{ - if (segment->sectionNum < segment->sectionNumMax) - memcpy(&segment->sections[segment->sectionNum], section, sizeof(elf_section_entry)); - else { - segment->sectionNumMax *= 2; - elf_section_entry *tmp = calloc(segment->sectionNumMax, sizeof(elf_section_entry)); - for (int k = 0; k < segment->sectionNum; k++) - memcpy(&tmp[k], &segment->sections[k], sizeof(elf_section_entry)); - free(segment->sections); - segment->sections = tmp; - memcpy(&segment->sections[segment->sectionNum], section, sizeof(elf_section_entry)); - } - - segment->sectionNum++; -} - -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; - elf->segments = calloc(elf->programTableEntryCount,sizeof(elf_segment)); - - elf_segment segment; - - bool foundFirstSection = false; - int curr, prev; - u32 padding, size, sizeInMemory; - - for (int i = 0; i < elf->programTableEntryCount; i++){ - if (elf->programHeaders[i].sizeInMemory != 0 && elf->programHeaders[i].type == PF_X){ - InitSegment(&segment); - - foundFirstSection = false; - size = 0; - sizeInMemory = elf->programHeaders[i].sizeInMemory; - - // Itterate Through Section Headers - for (curr = 0; curr < elf->sectionTableEntryCount && size != sizeInMemory; curr++){ - // Skip irrelevant sections - if (IsIgnoreSection(elf->sections[curr])) - continue; - - - if (!foundFirstSection) { - if (elf->sections[curr].address != elf->programHeaders[i].virtualAddress) - continue; - - foundFirstSection = true; - segment.vAddr = elf->sections[curr].address; - segment.name = elf->sections[curr].name; - - AddSegmentSection(&segment, &elf->sections[curr]); - size = elf->sections[curr].size; - } - else { - AddSegmentSection(&segment, &elf->sections[curr]); - padding = elf->sections[curr].address - (elf->sections[prev].address + elf->sections[prev].size); - size += padding + elf->sections[curr].size; - } - prev = curr; - - // Catch section parsing fails - if (size > sizeInMemory){ - fprintf(stderr,"[ELF ERROR] Too large section size.\n Segment size = 0x%x\n Section Size = 0x%x\n", sizeInMemory, size); - return ELF_SEGMENT_SECTION_SIZE_MISMATCH; - } - } - if(segment.sectionNum){ - segment.header = &elf->programHeaders[i]; - memcpy(&elf->segments[elf->activeSegments],&segment,sizeof(elf_segment)); - elf->activeSegments++; - } - else{ - free(segment.sections); - fprintf(stderr,"[ELF ERROR] Program Header Has no corresponding Sections, ELF Cannot be proccessed\n"); - return ELF_SEGMENTS_NOT_FOUND; - } - } - } - - return 0; -} \ No newline at end of file diff --git a/makerom/elf.h b/makerom/elf.h index c568a5b..71466f6 100644 --- a/makerom/elf.h +++ b/makerom/elf.h @@ -56,17 +56,17 @@ typedef enum elf_section_flag SHF_TLS = 0x400 } elf_section_flag; -typedef struct elf_section_entry +typedef struct elf_section { const char *name; u32 type; u32 flags; const u8 *ptr; - u32 offsetInFile; + u32 fileOffset; u32 size; - u32 address; + u32 vAddr; u32 alignment; -} elf_section_entry; +} elf_section; typedef enum elf_program_type { @@ -91,57 +91,40 @@ typedef enum elf_program_flag PF_RODATA = PF_R } elf_program_flag; -typedef struct elf_program_entry +typedef struct elf_segment { u32 type; u32 flags; const u8 *ptr; - u32 offsetInFile; - u32 sizeInFile; - u32 virtualAddress; - u32 physicalAddress; - u32 sizeInMemory; - u32 alignment; -} elf_program_entry; - -typedef struct elf_segment -{ - const char *name; + u32 fileOffset; + u32 fileSize; + u32 memSize; u32 vAddr; - - elf_program_entry *header; - u32 sectionNum; - u32 sectionNumMax; - elf_section_entry *sections; + u32 pAddr; + u32 alignment; } elf_segment; typedef struct elf_context { const u8 *file; - u32 pageSize; - - u32 programTableOffset; - u16 programTableEntrySize; - u16 programTableEntryCount; - - u32 sectionTableOffset; - u16 sectionTableEntrySize; - u16 sectionTableEntryCount; - - u16 sectionHeaderNameEntryIndex; + u32 shdrOffset; + u16 shdrNameIndex; + u32 phdrOffset; - elf_section_entry *sections; - elf_program_entry *programHeaders; + u16 sectionNum; + elf_section *sections; - u16 activeSegments; + u16 segmentNum; elf_segment *segments; } elf_context; -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 +int elf_Init(elf_context *ctx, const u8 *fp); +void elf_Free(elf_context *ctx); + +u16 elf_SectionNum(elf_context *ctx); +const elf_section* elf_GetSections(elf_context *ctx); + +u16 elf_SegmentNum(elf_context *ctx); +const elf_segment* elf_GetSegments(elf_context *ctx); \ No newline at end of file diff --git a/makerom/rsf_settings.c b/makerom/rsf_settings.c index 66fcc0f..99c89ef 100644 --- a/makerom/rsf_settings.c +++ b/makerom/rsf_settings.c @@ -64,7 +64,6 @@ void GET_Option(ctr_yaml_context *ctx, rsf_settings *rsf) else if(cmpYamlValue("EnableCompress",ctx)) SetBoolYAMLValue(&rsf->Option.EnableCompress,"EnableCompress",ctx); else if(cmpYamlValue("FreeProductCode",ctx)) SetBoolYAMLValue(&rsf->Option.FreeProductCode,"FreeProductCode",ctx); else if(cmpYamlValue("UseOnSD",ctx)) SetBoolYAMLValue(&rsf->Option.UseOnSD,"UseOnSD",ctx); - else if(cmpYamlValue("PageSize",ctx)) SetSimpleYAMLValue(&rsf->Option.PageSize,"PageSize",ctx,0); else{ fprintf(stderr,"[RSF ERROR] Unrecognised key '%s'\n",GetYamlString(ctx)); ctx->error = YAML_UNKNOWN_KEY; @@ -343,9 +342,6 @@ void GET_CommonHeaderKey(ctr_yaml_context *ctx, rsf_settings *rsf) void free_RsfSettings(rsf_settings *set) { - //Option - free(set->Option.PageSize); - //AccessControlInfo free(set->AccessControlInfo.IdealProcessor); free(set->AccessControlInfo.Priority); diff --git a/makerom/user_settings.h b/makerom/user_settings.h index f06f95f..ea0f008 100644 --- a/makerom/user_settings.h +++ b/makerom/user_settings.h @@ -70,9 +70,6 @@ typedef struct bool EnableCompress; bool FreeProductCode; bool UseOnSD; - - // Strings - char *PageSize; } Option; struct{