mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-13 04:39:36 +00:00
git subrepo pull (merge) tools/fado (#1501)
subrepo: subdir: "tools/fado" merged: "8d896ee97" upstream: origin: "git@github.com:EllipticEllipsis/fado.git" branch: "master" commit: "8d896ee97" git-subrepo: version: "0.4.5" origin: "git@github.com:ingydotnet/git-subrepo.git" commit: "dbb99be"
This commit is contained in:
parent
9f0b7bb8a3
commit
d4a6b21d46
11 changed files with 160 additions and 101 deletions
|
@ -6,7 +6,7 @@
|
|||
[subrepo]
|
||||
remote = git@github.com:EllipticEllipsis/fado.git
|
||||
branch = master
|
||||
commit = a0fa828089353ba48e378b281c23100c247b1c92
|
||||
parent = eadc477187888e1ae078d021b4a00b1366f0c9a4
|
||||
commit = 8d896ee97d565508755584803c409fc33bb0c953
|
||||
parent = 9f09505d34619883748a7dab05071883281c14fd
|
||||
method = merge
|
||||
cmdver = 0.4.3
|
||||
cmdver = 0.4.5
|
||||
|
|
|
@ -7,9 +7,9 @@ Contains
|
|||
- **Fado** a program for generating the `.ovl`/relocation section for Zelda64 overlay files
|
||||
- **Mido** an automatic dependency file generator
|
||||
|
||||
Compatible with both IDO and GCC (although [see below](N_B)).
|
||||
Compatible with both IDO and GCC (although [see below](N_B)). Both ordinary MIPS REL sections and RELA sections are now supported.
|
||||
|
||||
Format is the standard "Zelda64" .ovl section, with the relocs divided by section, as used by
|
||||
Output format is the standard "Zelda64" .ovl section, with the relocs divided by section, as used by
|
||||
- *The Legend of Zelda: Ocarina of Time* (all Nintendo 64/Gamecube/iQue releases)
|
||||
- *The Legend of Zelda: Majora's Mask* (all Nintendo 64/Gamecube releases)
|
||||
|
||||
|
|
|
@ -473,6 +473,14 @@ typedef struct {
|
|||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* Relocation table entry with addend (in section of type SHT_RELA). */
|
||||
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset; /* Address */
|
||||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
Elf32_Sword r_addend; /* Addend */
|
||||
} Elf32_Rela;
|
||||
|
||||
/* How to extract and insert information held in the r_info field. */
|
||||
|
||||
#define ELF32_R_SYM(val) ((val) >> 8)
|
||||
|
|
|
@ -105,7 +105,7 @@ bool Fairy_StartsWith(const char* string, const char* initial) {
|
|||
|
||||
FairyFileHeader* Fairy_ReadFileHeader(FairyFileHeader* header, FILE* file) {
|
||||
fseek(file, 0, SEEK_SET);
|
||||
assert(fread(header, 0x34, 1, file) != 0);
|
||||
assert(fread(header, sizeof(char), 0x34, file) == 0x34);
|
||||
|
||||
if (!Fairy_VerifyMagic(header->e_ident)) {
|
||||
fprintf(stderr, "Not a valid ELF file.\n");
|
||||
|
@ -150,7 +150,7 @@ FairySecHeader* Fairy_ReadSectionTable(FairySecHeader* sectionTable, FILE* file,
|
|||
size_t tableSize = number * entrySize;
|
||||
|
||||
fseek(file, tableOffset, SEEK_SET);
|
||||
assert(fread(sectionTable, tableSize, 1, file) != 0);
|
||||
assert(fread(sectionTable, sizeof(char), tableSize, file) == tableSize);
|
||||
|
||||
/* Since the section table happens to only have entries of width 4, we can byteswap it by pretending it is a raw
|
||||
* uint32_t array */
|
||||
|
@ -165,13 +165,21 @@ FairySecHeader* Fairy_ReadSectionTable(FairySecHeader* sectionTable, FILE* file,
|
|||
return sectionTable;
|
||||
}
|
||||
|
||||
FairySym* Fairy_ReadSymbolTable(FairySym* symbolTable, FILE* file, size_t tableOffset, size_t tableSize) {
|
||||
size_t Fairy_ReadSymbolTable(FairySym** symbolTableOut, FILE* file, size_t tableOffset, size_t tableSize) {
|
||||
size_t number = tableSize / sizeof(FairySym);
|
||||
FairySym* symbolTable = malloc(tableSize);
|
||||
|
||||
fseek(file, tableOffset, SEEK_SET);
|
||||
assert(fread(symbolTable, tableSize, 1, file) != 0);
|
||||
*symbolTableOut = NULL;
|
||||
|
||||
/* Reend the variables that are larger than bytes */
|
||||
if (symbolTable == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (fseek(file, tableOffset, SEEK_SET) != 0 || fread(symbolTable, sizeof(char), tableSize, file) != tableSize) {
|
||||
free(symbolTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reend the variables that are wider than bytes */
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < number; i++) {
|
||||
|
@ -182,31 +190,65 @@ FairySym* Fairy_ReadSymbolTable(FairySym* symbolTable, FILE* file, size_t tableO
|
|||
}
|
||||
}
|
||||
|
||||
return symbolTable;
|
||||
*symbolTableOut = symbolTable;
|
||||
return number;
|
||||
}
|
||||
|
||||
/* Can be used for both the section header string table and the strtab */
|
||||
char* Fairy_ReadStringTable(char* stringTable, FILE* file, size_t tableOffset, size_t tableSize) {
|
||||
fseek(file, tableOffset, SEEK_SET);
|
||||
assert(fread(stringTable, tableSize, 1, file) != 0);
|
||||
assert(fread(stringTable, sizeof(char), tableSize, file) == tableSize);
|
||||
return stringTable;
|
||||
}
|
||||
|
||||
/* offset and number are attained from the section table */
|
||||
FairyRel* Fairy_ReadRelocs(FairyRel* relocTable, FILE* file, size_t offset, size_t size) {
|
||||
fseek(file, offset, SEEK_SET);
|
||||
assert(fread(relocTable, size, 1, file) != 0);
|
||||
/* offset and number are attained from the section table, the returned pointer must be freed */
|
||||
size_t Fairy_ReadRelocs(FairyRela** relocsOut, FILE* file, int type, size_t offset, size_t size) {
|
||||
/* Final size of the relocation table, relocations of type SHT_REL need more space for extra addend of 0 */
|
||||
size_t finalSize = (type == SHT_REL) ? ((size * sizeof(FairyRela)) / sizeof(FairyRel)) : size;
|
||||
void* readBuf = malloc(size);
|
||||
FairyRela* relocTable = malloc(finalSize);
|
||||
|
||||
/* Reend the variables that are larger than bytes */
|
||||
*relocsOut = NULL;
|
||||
|
||||
if (readBuf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (relocTable == NULL) {
|
||||
free(readBuf);
|
||||
return 0;
|
||||
}
|
||||
if (fseek(file, offset, SEEK_SET) != 0 || fread(readBuf, sizeof(char), size, file) != size) {
|
||||
free(readBuf);
|
||||
free(relocTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reend the variables that are wider than bytes */
|
||||
{
|
||||
size_t i;
|
||||
uint32_t* data = (uint32_t*)relocTable;
|
||||
uint32_t* data = (uint32_t*)readBuf;
|
||||
for (i = 0; i < size / sizeof(uint32_t); i++) {
|
||||
data[i] = REEND32(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return relocTable;
|
||||
/* Make the relocation table, for SHT_REL sections add an addend of 0 */
|
||||
if (type == SHT_REL) {
|
||||
size_t i;
|
||||
FairyRel* rel = (FairyRel*)readBuf;
|
||||
|
||||
for (i = 0; i < size / sizeof(FairyRel); i++) {
|
||||
relocTable[i].r_info = rel[i].r_info;
|
||||
relocTable[i].r_offset = rel[i].r_offset;
|
||||
relocTable[i].r_addend = 0;
|
||||
}
|
||||
} else {
|
||||
memcpy(relocTable, readBuf, size);
|
||||
}
|
||||
free(readBuf);
|
||||
|
||||
*relocsOut = relocTable;
|
||||
return finalSize / sizeof(FairyRela);
|
||||
}
|
||||
|
||||
char* Fairy_GetSectionName(FairySecHeader* sectionTable, char* shstrtab, size_t index) {
|
||||
|
@ -240,7 +282,8 @@ void Fairy_InitFile(FairyFileInfo* fileInfo, FILE* file) {
|
|||
|
||||
shstrtab = malloc(sectionTable[fileHeader.e_shstrndx].sh_size * sizeof(char));
|
||||
fseek(file, sectionTable[fileHeader.e_shstrndx].sh_offset, SEEK_SET);
|
||||
assert(fread(shstrtab, sectionTable[fileHeader.e_shstrndx].sh_size, 1, file) != 0);
|
||||
assert(fread(shstrtab, sizeof(char), sectionTable[fileHeader.e_shstrndx].sh_size, file) ==
|
||||
sectionTable[fileHeader.e_shstrndx].sh_size);
|
||||
|
||||
/* Search for the sections we need */
|
||||
{
|
||||
|
@ -251,6 +294,8 @@ void Fairy_InitFile(FairyFileInfo* fileInfo, FILE* file) {
|
|||
}
|
||||
|
||||
for (currentIndex = 0; currentIndex < fileHeader.e_shnum; currentIndex++) {
|
||||
size_t off = 0;
|
||||
|
||||
currentSection = sectionTable[currentIndex];
|
||||
|
||||
switch (currentSection.sh_type) {
|
||||
|
@ -299,10 +344,11 @@ void Fairy_InitFile(FairyFileInfo* fileInfo, FILE* file) {
|
|||
|
||||
case SHT_SYMTAB:
|
||||
if (strcmp(&shstrtab[currentSection.sh_name + 1], "symtab") == 0) {
|
||||
fileInfo->symtabInfo.sectionSize = currentSection.sh_size;
|
||||
fileInfo->symtabInfo.sectionData = malloc(currentSection.sh_size);
|
||||
Fairy_ReadSymbolTable(fileInfo->symtabInfo.sectionData, file, currentSection.sh_offset,
|
||||
currentSection.sh_size);
|
||||
fileInfo->symtabInfo.sectionType = SHT_SYMTAB;
|
||||
fileInfo->symtabInfo.sectionEntrySize = sizeof(FairySym);
|
||||
fileInfo->symtabInfo.sectionEntryCount =
|
||||
Fairy_ReadSymbolTable((FairySym**)&fileInfo->symtabInfo.sectionData, file,
|
||||
currentSection.sh_offset, currentSection.sh_size);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -314,30 +360,32 @@ void Fairy_InitFile(FairyFileInfo* fileInfo, FILE* file) {
|
|||
}
|
||||
break;
|
||||
|
||||
case SHT_RELA:
|
||||
off += 1;
|
||||
case SHT_REL:
|
||||
off += 5;
|
||||
/* This assumes only one reloc section of each name */
|
||||
// TODO: is this a problem?
|
||||
{
|
||||
FairySection relocSection = FAIRY_SECTION_OTHER;
|
||||
|
||||
/* Ignore the first 5 chars, which will always be ".rel." */
|
||||
if (strcmp(&shstrtab[currentSection.sh_name + 5], "text") == 0) {
|
||||
/* Ignore the first 5/6 chars, which will always be ".rel."/".rela." */
|
||||
if (strcmp(&shstrtab[currentSection.sh_name + off], "text") == 0) {
|
||||
relocSection = FAIRY_SECTION_TEXT;
|
||||
FAIRY_DEBUG_PRINTF("%s", "Found rel.text section\n");
|
||||
} else if (strcmp(&shstrtab[currentSection.sh_name + 5], "data") == 0) {
|
||||
} else if (strcmp(&shstrtab[currentSection.sh_name + off], "data") == 0) {
|
||||
relocSection = FAIRY_SECTION_DATA;
|
||||
FAIRY_DEBUG_PRINTF("%s", "Found rel.data section\n");
|
||||
} else if (strcmp(&shstrtab[currentSection.sh_name + 5], "rodata") == 0) {
|
||||
} else if (strcmp(&shstrtab[currentSection.sh_name + off], "rodata") == 0) {
|
||||
relocSection = FAIRY_SECTION_RODATA;
|
||||
FAIRY_DEBUG_PRINTF("%s", "Found rel.rodata section\n");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
FAIRY_DEBUG_PRINTF("Found %s section\n", &shstrtab[currentSection.sh_name]);
|
||||
|
||||
fileInfo->relocTablesInfo[relocSection].sectionSize = currentSection.sh_size;
|
||||
fileInfo->relocTablesInfo[relocSection].sectionData = malloc(currentSection.sh_size);
|
||||
Fairy_ReadRelocs(fileInfo->relocTablesInfo[relocSection].sectionData, file,
|
||||
currentSection.sh_offset, currentSection.sh_size);
|
||||
fileInfo->relocTablesInfo[relocSection].sectionType = SHT_RELA;
|
||||
fileInfo->relocTablesInfo[relocSection].sectionEntrySize = sizeof(FairyRela);
|
||||
fileInfo->relocTablesInfo[relocSection].sectionEntryCount =
|
||||
Fairy_ReadRelocs((FairyRela**)&fileInfo->relocTablesInfo[relocSection].sectionData, file,
|
||||
currentSection.sh_type, currentSection.sh_offset, currentSection.sh_size);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ typedef Elf32_Ehdr FairyFileHeader;
|
|||
typedef Elf32_Shdr FairySecHeader;
|
||||
typedef Elf32_Sym FairySym;
|
||||
typedef Elf32_Rel FairyRel;
|
||||
typedef Elf32_Rela FairyRela;
|
||||
|
||||
typedef struct {
|
||||
int define;
|
||||
|
@ -32,7 +33,9 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
void* sectionData;
|
||||
size_t sectionSize;
|
||||
int sectionType;
|
||||
size_t sectionEntryCount;
|
||||
size_t sectionEntrySize;
|
||||
} FairySectionInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -60,9 +63,9 @@ bool Fairy_StartsWith(const char* string, const char* initial);
|
|||
|
||||
FairyFileHeader* Fairy_ReadFileHeader(FairyFileHeader* header, FILE* file);
|
||||
FairySecHeader* Fairy_ReadSectionTable(FairySecHeader* sectionTable, FILE* file, size_t tableOffset, size_t number);
|
||||
FairySym* Fairy_ReadSymbolTable(FairySym* symbolTable, FILE* file, size_t tableOffset, size_t tableSize);
|
||||
char* Fairy_ReadStringTable(char* stringTable, FILE* file, size_t tableOffset, size_t tableSize);
|
||||
FairyRel* Fairy_ReadRelocs(FairyRel* relocTable, FILE* file, size_t offset, size_t number);
|
||||
size_t Fairy_ReadSymbolTable(FairySym** symbolTableOut, FILE* file, size_t tableOffset, size_t tableSize);
|
||||
size_t Fairy_ReadRelocs(FairyRela** relocsOut, FILE* file, int type, size_t offset, size_t size);
|
||||
|
||||
char* Fairy_GetSectionName(FairySecHeader* sectionTable, char* shstrtab, size_t index);
|
||||
char* Fairy_GetSymbolName(FairySym* symtab, char* strtab, size_t index);
|
||||
|
|
|
@ -32,7 +32,7 @@ void Fairy_PrintSymbolTable(FILE* inputFile) {
|
|||
shstrtab = malloc(sectionTable[shstrndx].sh_size * sizeof(char));
|
||||
|
||||
fseek(inputFile, sectionTable[shstrndx].sh_offset, SEEK_SET);
|
||||
assert(fread(shstrtab, sectionTable[shstrndx].sh_size, 1, inputFile) != 0);
|
||||
assert(fread(shstrtab, sizeof(char), sectionTable[shstrndx].sh_size, inputFile) == sectionTable[shstrndx].sh_size);
|
||||
|
||||
{
|
||||
size_t currentIndex;
|
||||
|
@ -44,9 +44,8 @@ void Fairy_PrintSymbolTable(FILE* inputFile) {
|
|||
case SHT_SYMTAB:
|
||||
if (strcmp(&shstrtab[currentHeader.sh_name], ".symtab") == 0) {
|
||||
printf("symtab found\n");
|
||||
symbolTableNum = currentHeader.sh_size / sizeof(FairySym);
|
||||
symbolTable = malloc(currentHeader.sh_size);
|
||||
Fairy_ReadSymbolTable(symbolTable, inputFile, currentHeader.sh_offset, currentHeader.sh_size);
|
||||
symbolTableNum = Fairy_ReadSymbolTable(&symbolTable, inputFile, currentHeader.sh_offset,
|
||||
currentHeader.sh_size);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -74,7 +73,8 @@ void Fairy_PrintSymbolTable(FILE* inputFile) {
|
|||
printf("and mallocked\n");
|
||||
fseek(inputFile, sectionTable[strtabndx].sh_offset, SEEK_SET);
|
||||
printf("file offset sought: %X\n", sectionTable[strtabndx].sh_offset);
|
||||
assert(fread(strtab, sectionTable[strtabndx].sh_size, 1, inputFile) != 0);
|
||||
assert(fread(strtab, sizeof(char), sectionTable[strtabndx].sh_size, inputFile) ==
|
||||
sectionTable[strtabndx].sh_size);
|
||||
printf("file read\n");
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ void Fairy_PrintSymbolTable(FILE* inputFile) {
|
|||
void Fairy_PrintRelocs(FILE* inputFile) {
|
||||
FairyFileHeader fileHeader;
|
||||
FairySecHeader* sectionTable;
|
||||
FairyRel* relocs;
|
||||
FairyRela* relocs;
|
||||
size_t shstrndx;
|
||||
char* shstrtab;
|
||||
size_t currentSection;
|
||||
|
@ -131,29 +131,28 @@ void Fairy_PrintRelocs(FILE* inputFile) {
|
|||
shstrtab = malloc(sectionTable[shstrndx].sh_size * sizeof(char));
|
||||
|
||||
fseek(inputFile, sectionTable[shstrndx].sh_offset, SEEK_SET);
|
||||
assert(fread(shstrtab, sectionTable[shstrndx].sh_size, 1, inputFile) != 0);
|
||||
assert(fread(shstrtab, sizeof(char), sectionTable[shstrndx].sh_size, inputFile) == sectionTable[shstrndx].sh_size);
|
||||
|
||||
for (currentSection = 0; currentSection < fileHeader.e_shnum; currentSection++) {
|
||||
if (sectionTable[currentSection].sh_type != SHT_REL) {
|
||||
size_t nRelocs;
|
||||
|
||||
if (sectionTable[currentSection].sh_type != SHT_REL || sectionTable[currentSection].sh_type != SHT_RELA) {
|
||||
continue;
|
||||
}
|
||||
printf("Section size: %d\n", sectionTable[currentSection].sh_size);
|
||||
|
||||
relocs = malloc(sectionTable[currentSection].sh_size * sizeof(char));
|
||||
|
||||
Fairy_ReadRelocs(relocs, inputFile, sectionTable[currentSection].sh_offset,
|
||||
sectionTable[currentSection].sh_size);
|
||||
nRelocs = Fairy_ReadRelocs(&relocs, inputFile, sectionTable[currentSection].sh_type,
|
||||
sectionTable[currentSection].sh_offset, sectionTable[currentSection].sh_size);
|
||||
|
||||
// fseek(inputFile, sectionTable[currentSection].sh_offset, SEEK_SET);
|
||||
// assert(fread(relocs, sectionTable[currentSection].sh_size, 1, inputFile) != 0);
|
||||
// assert(fread(relocs, sizeof(char), sectionTable[currentSection].sh_size, inputFile) ==
|
||||
// sectionTable[currentSection].sh_size);
|
||||
|
||||
printf("Relocs in section [%2zd]: %s:\n", currentSection, shstrtab + sectionTable[currentSection].sh_name);
|
||||
printf("Offset Info Type Symbol\n");
|
||||
{
|
||||
size_t currentReloc;
|
||||
for (currentReloc = 0; currentReloc < sectionTable[currentSection].sh_size / sizeof(*relocs);
|
||||
currentReloc++) {
|
||||
|
||||
for (currentReloc = 0; currentReloc < nRelocs; currentReloc++) {
|
||||
printf("%08X,%08X ", relocs[currentReloc].r_offset, relocs[currentReloc].r_info);
|
||||
|
||||
switch (ELF32_R_TYPE(relocs[currentReloc].r_info)) {
|
||||
|
@ -212,7 +211,7 @@ void Fairy_PrintSectionTable(FILE* inputFile) {
|
|||
shstrtab = malloc(sectionTable[shstrndx].sh_size * sizeof(char));
|
||||
|
||||
fseek(inputFile, sectionTable[shstrndx].sh_offset, SEEK_SET);
|
||||
assert(fread(shstrtab, sectionTable[shstrndx].sh_size, 1, inputFile) != 0);
|
||||
assert(fread(shstrtab, sizeof(char), sectionTable[shstrndx].sh_size, inputFile) == sectionTable[shstrndx].sh_size);
|
||||
|
||||
printf("[Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n");
|
||||
for (currentSection = 0; currentSection < fileHeader.e_shnum; currentSection++) {
|
||||
|
@ -261,7 +260,7 @@ const char* relSectionStrings[] = {
|
|||
".rodata",
|
||||
};
|
||||
|
||||
static uint32_t Fairy_PackReloc(FairyOverlayRelSection sec, FairyRel rel) {
|
||||
static uint32_t Fairy_PackReloc(FairyOverlayRelSection sec, FairyRela rel) {
|
||||
return (sec << 0x1E) | (ELF32_R_TYPE(rel.r_info) << 0x18) | rel.r_offset;
|
||||
}
|
||||
|
||||
|
@ -290,7 +289,7 @@ void Fairy_PrintSectionSizes(FairySecHeader* sectionTable, FILE* inputFile, size
|
|||
bool strtabFound = false;
|
||||
/* Count the reloc sections */
|
||||
for (currentSection = 0; currentSection < number; currentSection++) {
|
||||
if (sectionTable[currentSection].sh_type == SHT_REL) {
|
||||
if (sectionTable[currentSection].sh_type == SHT_REL || sectionTable[currentSection].sh_type == SHT_RELA) {
|
||||
relocSectionsCount++;
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +300,8 @@ void Fairy_PrintSectionSizes(FairySecHeader* sectionTable, FILE* inputFile, size
|
|||
|
||||
/* Find the section sizes and the reloc sections */
|
||||
for (currentSection = 0; currentSection < number; currentSection++) {
|
||||
size_t off = 0;
|
||||
|
||||
currentHeader = sectionTable[currentSection];
|
||||
sectionName = &shstrtab[currentHeader.sh_name + 1]; /* ignore the initial '.' */
|
||||
switch (currentHeader.sh_type) {
|
||||
|
@ -329,17 +330,19 @@ void Fairy_PrintSectionSizes(FairySecHeader* sectionTable, FILE* inputFile, size
|
|||
}
|
||||
break;
|
||||
|
||||
case SHT_RELA:
|
||||
off += 1;
|
||||
case SHT_REL:
|
||||
relocSectionIndices[currentRelocSection] = currentSection;
|
||||
sectionName += 4; /* ignore the "rel." part */
|
||||
if (Fairy_StartsWith(sectionName, "rodata")) {
|
||||
printf(".rel.rodata\n");
|
||||
off += 4; /* ignore the "rel."/"rela." part */
|
||||
if (Fairy_StartsWith(§ionName[off], "rodata")) {
|
||||
printf("%s\n", sectionName);
|
||||
relocSectionSection[currentRelocSection] = REL_SECTION_RODATA;
|
||||
} else if (Fairy_StartsWith(sectionName, "data")) {
|
||||
printf(".rel.data\n");
|
||||
} else if (Fairy_StartsWith(§ionName[off], "data")) {
|
||||
printf("%s\n", sectionName);
|
||||
relocSectionSection[currentRelocSection] = REL_SECTION_DATA;
|
||||
} else if (Fairy_StartsWith(sectionName, "text")) {
|
||||
printf(".rel.text\n");
|
||||
} else if (Fairy_StartsWith(§ionName[off], "text")) {
|
||||
printf("%s\n", sectionName);
|
||||
relocSectionSection[currentRelocSection] = REL_SECTION_TEXT;
|
||||
}
|
||||
|
||||
|
@ -373,36 +376,34 @@ void Fairy_PrintSectionSizes(FairySecHeader* sectionTable, FILE* inputFile, size
|
|||
printf(".word 0x%08X # .bss size\n\n", bssSize);
|
||||
|
||||
if (!symtabFound) {
|
||||
fprintf(stderr, "Symbol table not found");
|
||||
fprintf(stderr, "Symbol table not found\n");
|
||||
return;
|
||||
}
|
||||
/* Obtain the symbol table */
|
||||
symtab = malloc(symtabHeader.sh_size);
|
||||
|
||||
// TODO: Consider replacing this with a lighter-weight read: sufficient to get the name, shndx
|
||||
Fairy_ReadSymbolTable(symtab, inputFile, symtabHeader.sh_offset, symtabHeader.sh_size);
|
||||
Fairy_ReadSymbolTable(&symtab, inputFile, symtabHeader.sh_offset, symtabHeader.sh_size);
|
||||
|
||||
if (!strtabFound) {
|
||||
fprintf(stderr, "String table not found");
|
||||
fprintf(stderr, "String table not found\n");
|
||||
} else {
|
||||
/* Obtain the string table */
|
||||
strtab = malloc(strtabHeader.sh_size);
|
||||
fseek(inputFile, strtabHeader.sh_offset, SEEK_SET);
|
||||
assert(fread(strtab, strtabHeader.sh_size, 1, inputFile) != 0);
|
||||
assert(fread(strtab, sizeof(char), strtabHeader.sh_size, inputFile) == strtabHeader.sh_size);
|
||||
}
|
||||
|
||||
/* Do single-file relocs */
|
||||
{
|
||||
FairyRel* relocs;
|
||||
FairyRela* relocs;
|
||||
for (currentSection = 0; currentSection < relocSectionsCount; currentSection++) {
|
||||
size_t currentReloc;
|
||||
size_t sectionRelocCount;
|
||||
currentHeader = sectionTable[relocSectionIndices[currentSection]];
|
||||
sectionRelocCount = currentHeader.sh_size / sizeof(FairyRel);
|
||||
relocs = malloc(currentHeader.sh_size);
|
||||
Fairy_ReadRelocs(relocs, inputFile, currentHeader.sh_offset, currentHeader.sh_size);
|
||||
size_t nRelocs;
|
||||
|
||||
for (currentReloc = 0; currentReloc < sectionRelocCount; currentReloc++) {
|
||||
currentHeader = sectionTable[relocSectionIndices[currentSection]];
|
||||
nRelocs = Fairy_ReadRelocs(&relocs, inputFile, currentHeader.sh_type, currentHeader.sh_offset,
|
||||
currentHeader.sh_size);
|
||||
|
||||
for (currentReloc = 0; currentReloc < nRelocs; currentReloc++) {
|
||||
FairySym symbol = symtab[ELF32_R_SYM(relocs[currentReloc].r_info)];
|
||||
if (symbol.st_shndx == SHN_UNDEF) {
|
||||
continue; // TODO: this is where multifile has to look elsewhere
|
||||
|
@ -453,7 +454,7 @@ void PrintZeldaReloc(FILE* inputFile) {
|
|||
shstrtab = malloc(sectionTable[shstrndx].sh_size * sizeof(char));
|
||||
|
||||
fseek(inputFile, sectionTable[shstrndx].sh_offset, SEEK_SET);
|
||||
assert(fread(shstrtab, sectionTable[shstrndx].sh_size, 1, inputFile) != 0);
|
||||
assert(fread(shstrtab, sizeof(char), sectionTable[shstrndx].sh_size, inputFile) == sectionTable[shstrndx].sh_size);
|
||||
|
||||
Fairy_PrintSectionSizes(sectionTable, inputFile, fileHeader.e_shentsize * fileHeader.e_shnum, shstrtab);
|
||||
|
||||
|
|
|
@ -112,15 +112,15 @@ bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2) {
|
|||
return memcmp(vector1->data, vector2->data, size_vector1) == 0;
|
||||
}
|
||||
|
||||
float vc_vector_get_growth_factor() {
|
||||
float vc_vector_get_growth_factor(void) {
|
||||
return GROWTH_FACTOR;
|
||||
}
|
||||
|
||||
size_t vc_vector_get_default_count_of_elements() {
|
||||
size_t vc_vector_get_default_count_of_elements(void) {
|
||||
return DEFAULT_COUNT_OF_ELEMENTS;
|
||||
}
|
||||
|
||||
size_t vc_vector_struct_size() {
|
||||
size_t vc_vector_struct_size(void) {
|
||||
return sizeof(vc_vector);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,13 @@ void vc_vector_release(vc_vector* vector);
|
|||
bool vc_vector_is_equals(vc_vector* vector1, vc_vector* vector2);
|
||||
|
||||
// Returns constant value of the vector growth factor.
|
||||
float vc_vector_get_growth_factor();
|
||||
float vc_vector_get_growth_factor(void);
|
||||
|
||||
// Returns constant value of the vector default count of elements.
|
||||
size_t vc_vector_get_default_count_of_elements();
|
||||
size_t vc_vector_get_default_count_of_elements(void);
|
||||
|
||||
// Returns constant value of the vector struct size.
|
||||
size_t vc_vector_struct_size();
|
||||
size_t vc_vector_struct_size(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Element access
|
||||
|
|
|
@ -40,8 +40,7 @@ void Fado_ConstructStringVectors(vc_vector** stringVectors, FairyFileInfo* fileI
|
|||
stringVectors[currentFile] = vc_vector_create(0x40, sizeof(char**), NULL);
|
||||
|
||||
/* Build a vector of pointers to defined symbols' names */
|
||||
for (currentSym = 0; currentSym < fileInfo[currentFile].symtabInfo.sectionSize / sizeof(FairySym);
|
||||
currentSym++) {
|
||||
for (currentSym = 0; currentSym < fileInfo[currentFile].symtabInfo.sectionEntryCount; currentSym++) {
|
||||
if ((symtab[currentSym].st_shndx != STN_UNDEF) &&
|
||||
Fado_CheckInProgBitsSections(symtab[currentSym].st_shndx, fileInfo[currentFile].progBitsSections)) {
|
||||
/* Have to pass a double pointer so it copies the pointer instead of the start of the string */
|
||||
|
@ -86,7 +85,7 @@ typedef struct {
|
|||
} FadoRelocInfo;
|
||||
|
||||
/* Construct the Zelda64ovl-compatible reloc word from an ELF reloc */
|
||||
FadoRelocInfo Fado_MakeReloc(int file, FairySection section, FairyRel* data) {
|
||||
FadoRelocInfo Fado_MakeReloc(int file, FairySection section, FairyRela* data) {
|
||||
FadoRelocInfo relocInfo = { 0 };
|
||||
uint32_t sectionPrefix = 0;
|
||||
|
||||
|
@ -223,11 +222,10 @@ void Fado_Relocs(FILE* outputFile, int inputFilesCount, FILE** inputFiles, const
|
|||
relocList[section] = vc_vector_create(0x100, sizeof(FadoRelocInfo), NULL);
|
||||
|
||||
for (currentFile = 0; currentFile < inputFilesCount; currentFile++) {
|
||||
FairyRel* relSection = fileInfos[currentFile].relocTablesInfo[section].sectionData;
|
||||
if (relSection != NULL) {
|
||||
FairyRela* relSection = fileInfos[currentFile].relocTablesInfo[section].sectionData;
|
||||
|
||||
for (relocIndex = 0;
|
||||
relocIndex < fileInfos[currentFile].relocTablesInfo[section].sectionSize / sizeof(FairyRel);
|
||||
if (relSection != NULL) {
|
||||
for (relocIndex = 0; relocIndex < fileInfos[currentFile].relocTablesInfo[section].sectionEntryCount;
|
||||
relocIndex++) {
|
||||
FadoRelocInfo currentReloc = Fado_MakeReloc(currentFile, section, &relSection[relocIndex]);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "version.inc"
|
||||
|
||||
void PrintVersion() {
|
||||
void PrintVersion(void) {
|
||||
printf("Fado (Fairy-Assisted relocations for Decompiled Overlays), version %s\n", versionNumber);
|
||||
printf("Copyright (C) 2021 Elliptic Ellipsis\n");
|
||||
printf("%s\n", credits);
|
||||
|
@ -88,7 +88,7 @@ static size_t posArgCount = ARRAY_COUNT(posArgInfo);
|
|||
static size_t optCount = ARRAY_COUNT(optInfo);
|
||||
static struct option longOptions[ARRAY_COUNT(optInfo)];
|
||||
|
||||
void ConstructLongOpts() {
|
||||
void ConstructLongOpts(void) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < optCount; i++) {
|
||||
|
@ -133,14 +133,15 @@ int main(int argc, char** argv) {
|
|||
outputFileName = optarg;
|
||||
outputFile = fopen(optarg, "wb");
|
||||
if (outputFile == NULL) {
|
||||
fprintf(stderr, "error: unable to open output file '%s' for writing", optarg);
|
||||
fprintf(stderr, "error: unable to open output file '%s' for writing\n", optarg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
if (sscanf(optarg, "%u", &gVerbosity) == 0) {
|
||||
fprintf(stderr, "warning: verbosity argument '%s' should be a nonnegative decimal integer", optarg);
|
||||
fprintf(stderr, "warning: verbosity argument '%s' should be a nonnegative decimal integer\n",
|
||||
optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -182,7 +183,7 @@ int main(int argc, char** argv) {
|
|||
FAIRY_INFO_PRINTF("Using input file %s\n", argv[optind + i]);
|
||||
inputFiles[i] = fopen(argv[optind + i], "rb");
|
||||
if (inputFiles[i] == NULL) {
|
||||
fprintf(stderr, "error: unable to open input file '%s' for reading", argv[optind + i]);
|
||||
fprintf(stderr, "error: unable to open input file '%s' for reading\n", argv[optind + i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -214,14 +215,14 @@ int main(int argc, char** argv) {
|
|||
FILE* dependencyFile = fopen(dependencyFileName, "w");
|
||||
|
||||
if (dependencyFile == NULL) {
|
||||
fprintf(stderr, "error: unable to open dependency file '%s' for writing", dependencyFileName);
|
||||
fprintf(stderr, "error: unable to open dependency file '%s' for writing\n", dependencyFileName);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
strcpy(objectFile, outputFileName);
|
||||
extensionStart = strrchr(objectFile, '.');
|
||||
if (extensionStart == objectFile + fileNameLength) {
|
||||
fprintf(stderr, "error: file name should not end in a '.'");
|
||||
fprintf(stderr, "error: file name should not end in a '.'\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
strcpy(extensionStart, ".o");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (C) 2021 Elliptic Ellipsis */
|
||||
/* SPDX-License-Identifier: AGPL-3.0-only */
|
||||
const char versionNumber[] = "1.2.1";
|
||||
const char credits[] = "Written by Elliptic Ellipsis\nand AngheloAlf";
|
||||
const char versionNumber[] = "1.3.1";
|
||||
const char credits[] = "Written by Elliptic Ellipsis\nwith additions from AngheloAlf and Tharo";
|
||||
const char repo[] = "https://github.com/EllipticEllipsis/fado/";
|
||||
|
|
Loading…
Reference in a new issue