Skip to content

Commit

Permalink
git subrepo pull (merge) tools/fado (zeldaret#1501)
Browse files Browse the repository at this point in the history
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"
  • Loading branch information
Dragorn421 committed Feb 26, 2023
1 parent 9f0b7bb commit d4a6b21
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 100 deletions.
6 changes: 3 additions & 3 deletions tools/fado/.gitrepo
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions tools/fado/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
8 changes: 8 additions & 0 deletions tools/fado/include/mips_elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
110 changes: 79 additions & 31 deletions tools/fado/lib/fairy/fairy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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 */
Expand All @@ -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;

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 larger than bytes */
/* Reend the variables that are wider than bytes */
{
size_t i;
for (i = 0; i < number; i++) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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 */
{
Expand All @@ -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) {
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down
9 changes: 6 additions & 3 deletions tools/fado/lib/fairy/fairy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,7 +33,9 @@ typedef struct {

typedef struct {
void* sectionData;
size_t sectionSize;
int sectionType;
size_t sectionEntryCount;
size_t sectionEntrySize;
} FairySectionInfo;

typedef struct {
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit d4a6b21

Please sign in to comment.