Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

makerom: now supports unstripped ELFs #2

Merged
merged 6 commits into from
Sep 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 87 additions & 91 deletions makerom/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,26 @@ int BuildExeFsCode(ncch_settings *set)
if(result) goto finish;

finish:
if(result){
if(result == NOT_ELF_FILE) fprintf(stderr,"[ELF ERROR] Not ELF File\n");
else if(result == NOT_ARM_ELF) fprintf(stderr,"[ELF ERROR] Not ARM ELF\n");
else if(result == NON_EXECUTABLE_ELF) fprintf(stderr,"[ELF ERROR] Not Executeable ELF\n");
else if(result == NOT_FIND_TEXT_SEGMENT) fprintf(stderr,"[ELF ERROR] Failed to retrieve text sections from ELF\n");
else if(result == NOT_FIND_DATA_SEGMENT) fprintf(stderr,"[ELF ERROR] Failed to retrieve data sections from ELF\n");
else fprintf(stderr,"[ELF ERROR] Failed to process ELF file (%d)\n",result);
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++)
free(elf->segments[i].sections);
Expand Down Expand Up @@ -735,30 +748,22 @@ u16 GetElfSectionIndexFromName(char *name, elf_context *elf, u8 *elfFile)

bool IsBss(elf_section_entry *section)
{
if(section->type == 8 && section->flags == 3)
return true;
return false;
return (section->type == SHT_NOBITS && section->flags == (SHF_WRITE | SHF_ALLOC));
}

bool IsData(elf_section_entry *section)
{
if(section->type == 1 && section->flags == 3)
return true;
return false;
return (section->type == SHT_PROGBITS && section->flags == (SHF_WRITE | SHF_ALLOC));
}

bool IsRoData(elf_section_entry *section)
{
if(section->type == 1 && section->flags == 2)
return true;
return false;
return (section->type == SHT_PROGBITS && section->flags == SHF_ALLOC);
}

bool IsText(elf_section_entry *section)
{
if(section->type == 1 && section->flags == 6)
return true;
return false;
return (section->type == SHT_PROGBITS && section->flags == (SHF_ALLOC | SHF_EXECINSTR));
}

/* ProgramHeader Functions */
Expand Down Expand Up @@ -908,108 +913,99 @@ u64 GetELFProgramEntryAlignment(u16 index, elf_context *elf, u8 *elfFile)
return 0;
}

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++;
}

int CreateElfSegments(elf_context *elf, u8 *elfFile)
{
int num = 0;
// Interate through Each Program Header
elf->activeSegments = 0;
elf->segments = calloc(elf->programTableEntryCount,sizeof(elf_segment));
elf_segment *segment = malloc(sizeof(elf_segment)); // Temporary Buffer

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 == 1){
memset(segment,0,sizeof(elf_segment));

bool foundFirstSection = false;
u32 size = 0;
u32 vAddr = elf->programHeaders[i].virtualAddress;
u32 memorySize = elf->programHeaders[i].sizeInMemory;
//printf("Segment Size in memory: 0x%x\n",memorySize);
//printf("Segment Alignment: 0x%x\n",elf->programHeaders[i].alignment);

u16 SectionInfoCapacity = 10;
segment->sectionNum = 0;
segment->sections = calloc(SectionInfoCapacity,sizeof(elf_section_entry));
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 (int j = num; j < elf->sectionTableEntryCount; j++){
if (!foundFirstSection){
if (elf->sections[j].address != vAddr)
continue;

while (j < (int)elf->sections[j].size && elf->sections[j].address == vAddr && !IsIgnoreSection(elf->sections[j]))
j++;
for (curr = 0; curr < elf->sectionTableEntryCount && size != sizeInMemory; curr++){
// Skip irrelevant sections
if (IsIgnoreSection(elf->sections[curr]))
continue;

j--;
if (!foundFirstSection) {
if (elf->sections[curr].address != elf->programHeaders[i].virtualAddress)
continue;

foundFirstSection = true;
segment->vAddr = elf->sections[j].address;
segment->name = elf->sections[j].name;
}

if(segment->sectionNum < SectionInfoCapacity)
memcpy(&segment->sections[segment->sectionNum],&elf->sections[j],sizeof(elf_section_entry));
else{
SectionInfoCapacity = SectionInfoCapacity*2;
elf_section_entry *tmp = calloc(SectionInfoCapacity,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],&elf->sections[j],sizeof(elf_section_entry));
}
segment->sectionNum++;
segment.vAddr = elf->sections[curr].address;
segment.name = elf->sections[curr].name;

if(size == 0)
size += elf->sections[j].size;
else{
u32 padding = elf->sections[j].address - (elf->sections[j-1].address + elf->sections[j-1].size);
size += padding + elf->sections[j].size;
AddSegmentSection(&segment, &elf->sections[curr]);
size = elf->sections[curr].size;
}

//printf("Section name: %s",elf->sections[j].name);
//printf(" 0x%lx",elf->sections[j].size);
//printf(" (Total Size: 0x%x)\n",size);

if (size == memorySize)
break;
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;

if (size > memorySize){
fprintf(stderr,"[ELF ERROR] Too large section size.\n Segment size = 0x%x\n Section Size = 0x%x\n", memorySize, size);
// 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));
if(segment.sectionNum){
segment.header = &elf->programHeaders[i];
memcpy(&elf->segments[elf->activeSegments],&segment,sizeof(elf_segment));
elf->activeSegments++;
}
else{
free(segment->sections);
free(segment);
free(segment.sections);
fprintf(stderr,"[ELF ERROR] Program Header Has no corresponding Sections, ELF Cannot be proccessed\n");
return ELF_SEGMENTS_NOT_FOUND;
}
}
}

free(segment);
return 0;
}

bool IsIgnoreSection(elf_section_entry info)
{
if (info.address)
return false;

if (info.type != 1 && info.type != 0)
return true;

char IgnoreSectionNames[7][20] = { ".debug_abbrev", ".debug_frame", ".debug_info", ".debug_line", ".debug_loc", ".debug_pubnames", ".comment" };
for (int i = 0; i < 7; i++){
if (strcmp(IgnoreSectionNames[i],info.name) == 0)
return true;
}
return false;

return (info.type != SHT_PROGBITS && info.type != SHT_NOBITS && info.type != SHT_INIT_ARRAY && info.type != SHT_FINI_ARRAY);
}
1 change: 1 addition & 0 deletions makerom/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef struct

elf_program_entry *header;
u32 sectionNum;
u32 sectionNumMax;
elf_section_entry *sections;
} elf_segment;

Expand Down
38 changes: 24 additions & 14 deletions makerom/elf_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,25 @@ typedef struct
#define SHT_REL 9 /* Relocation entries, no addends */
#define SHT_SHLIB 10 /* Reserved */
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
#define SHT_NUM 12 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_GNU_verdef 0x6ffffffd /* titleVersion definition section. */
#define SHT_GNU_verneed 0x6ffffffe /* titleVersion needs section. */
#define SHT_GNU_versym 0x6fffffff /* titleVersion symbol table. */
#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
#define SHT_HIOS 0x6fffffff /* End OS-specific type */
#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
#define SHT_LOUSER 0x80000000 /* Start of application-specific */
#define SHT_HIUSER 0x8fffffff /* End of application-specific */
#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 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
Expand Down Expand Up @@ -151,6 +156,11 @@ typedef struct
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
#define PT_HIPROC 0x7fffffff /* End of processor-specific */

#define PF_R 0x4 /* p_flags */
#define PF_W 0x2
#define PF_X 0x1


typedef struct
{
u8 p_type[4]; /* Segment type */
Expand Down
28 changes: 28 additions & 0 deletions makerom/makerom.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makerom", "makerom.vcxproj", "{21926330-F5A5-4643-AD32-D4F167CE226B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{21926330-F5A5-4643-AD32-D4F167CE226B}.Debug|x64.ActiveCfg = Debug|x64
{21926330-F5A5-4643-AD32-D4F167CE226B}.Debug|x64.Build.0 = Debug|x64
{21926330-F5A5-4643-AD32-D4F167CE226B}.Debug|x86.ActiveCfg = Debug|Win32
{21926330-F5A5-4643-AD32-D4F167CE226B}.Debug|x86.Build.0 = Debug|Win32
{21926330-F5A5-4643-AD32-D4F167CE226B}.Release|x64.ActiveCfg = Release|x64
{21926330-F5A5-4643-AD32-D4F167CE226B}.Release|x64.Build.0 = Release|x64
{21926330-F5A5-4643-AD32-D4F167CE226B}.Release|x86.ActiveCfg = Release|Win32
{21926330-F5A5-4643-AD32-D4F167CE226B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Loading