mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-02 16:59:03 +00:00
[makerom] Separated ELF processing from code segment construction. StackSize now read from exheader template.
This commit is contained in:
@@ -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);
|
||||
|
||||
+388
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int BuildExeFsCode(ncch_settings *ncchset);
|
||||
+145
-784
File diff suppressed because it is too large
Load Diff
+101
-38
@@ -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);
|
||||
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);
|
||||
@@ -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;
|
||||
+40
-51
@@ -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");
|
||||
|
||||
+25
-2
@@ -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
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
<ClInclude Include="cia.h" />
|
||||
<ClInclude Include="cia_build.h" />
|
||||
<ClInclude Include="cia_read.h" />
|
||||
<ClInclude Include="code.h" />
|
||||
<ClInclude Include="crr.h" />
|
||||
<ClInclude Include="crypto.h" />
|
||||
<ClInclude Include="ctr_utils.h" />
|
||||
@@ -105,7 +106,6 @@
|
||||
<ClInclude Include="desc\prod_sigdata.h" />
|
||||
<ClInclude Include="dir.h" />
|
||||
<ClInclude Include="elf.h" />
|
||||
<ClInclude Include="elf_hdr.h" />
|
||||
<ClInclude Include="exefs.h" />
|
||||
<ClInclude Include="exefs_build.h" />
|
||||
<ClInclude Include="exefs_read.h" />
|
||||
@@ -198,6 +198,7 @@
|
||||
<ClCompile Include="cardinfo.c" />
|
||||
<ClCompile Include="certs.c" />
|
||||
<ClCompile Include="cia.c" />
|
||||
<ClCompile Include="code.c" />
|
||||
<ClCompile Include="crypto.c" />
|
||||
<ClCompile Include="ctr_utils.c" />
|
||||
<ClCompile Include="dir.c" />
|
||||
|
||||
@@ -72,9 +72,6 @@
|
||||
<ClInclude Include="elf.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elf_hdr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="exefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -339,6 +336,9 @@
|
||||
<ClInclude Include="desc\prod_sigdata.h">
|
||||
<Filter>Resource Files\DESC</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="code.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="accessdesc.c">
|
||||
@@ -470,6 +470,9 @@
|
||||
<ClCompile Include="polarssl\sha4.c">
|
||||
<Filter>Source Files\polarssl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Makefile">
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef struct
|
||||
u32 rwSize;
|
||||
u32 rwMaxPages;
|
||||
u32 bssSize;
|
||||
u32 stackSize;
|
||||
} codeDetails;
|
||||
|
||||
struct
|
||||
|
||||
+3
-3
@@ -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){
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user