Switch linkdefs from scattered arrays to an array of structs

The info is better organized this way
This commit is contained in:
ISSOtm
2022-07-19 18:59:51 +02:00
parent ab9945c1ee
commit 9ec8186ac6
8 changed files with 151 additions and 145 deletions

View File

@@ -21,6 +21,7 @@
#include "error.h"
#include "helpers.h"
#include "linkdefs.h"
struct MemoryLocation {
uint16_t address;
@@ -54,8 +55,8 @@ static void initFreeSpace(void)
if (!memory[type][bank].next)
err("Failed to init free space for region %d bank %" PRIu32,
type, bank);
memory[type][bank].next->address = startaddr[type];
memory[type][bank].next->size = maxsize[type];
memory[type][bank].next->address = sectionTypeInfo[type].startAddr;
memory[type][bank].next->size = sectionTypeInfo[type].size;
memory[type][bank].next->next = NULL;
memory[type][bank].next->prev = &memory[type][bank];
}
@@ -140,13 +141,13 @@ static struct FreeSpace *getPlacement(struct Section const *section,
if (curScrambleSRAM > scrambleSRAM)
curScrambleSRAM = 0;
} else {
location->bank = bankranges[section->type][0];
location->bank = sectionTypeInfo[section->type].firstBank;
}
struct FreeSpace *space;
for (;;) {
/* Switch to the beginning of the next bank */
#define BANK_INDEX (location->bank - bankranges[section->type][0])
#define BANK_INDEX (location->bank - sectionTypeInfo[section->type].firstBank)
space = memory[section->type][BANK_INDEX].next;
if (space)
location->address = space->address;
@@ -201,7 +202,7 @@ static struct FreeSpace *getPlacement(struct Section const *section,
/* Try again in the next bank */
location->bank++;
if (location->bank > bankranges[section->type][1])
if (location->bank > sectionTypeInfo[section->type].lastBank)
return NULL;
#undef BANK_INDEX
}
@@ -225,10 +226,10 @@ static void placeSection(struct Section *section)
*/
location.address = section->isAddressFixed
? section->org
: startaddr[section->type];
: sectionTypeInfo[section->type].startAddr;
location.bank = section->isBankFixed
? section->bank
: bankranges[section->type][0];
: sectionTypeInfo[section->type].firstBank;
assignSection(section, &location);
return;
}
@@ -314,16 +315,16 @@ static void placeSection(struct Section *section)
/* If a section failed to go to several places, nothing we can report */
if (!section->isBankFixed || !section->isAddressFixed)
errx("Unable to place \"%s\" (%s section) %s",
section->name, typeNames[section->type], where);
section->name, sectionTypeInfo[section->type].name, where);
/* If the section just can't fit the bank, report that */
else if (section->org + section->size > endaddr(section->type) + 1)
errx("Unable to place \"%s\" (%s section) %s: section runs past end of region ($%04x > $%04x)",
section->name, typeNames[section->type], where,
section->name, sectionTypeInfo[section->type].name, where,
section->org + section->size, endaddr(section->type) + 1);
/* Otherwise there is overlap with another section */
else
errx("Unable to place \"%s\" (%s section) %s: section overlaps with \"%s\"",
section->name, typeNames[section->type], where,
section->name, sectionTypeInfo[section->type].name, where,
out_OverlappingSection(section)->name);
}

View File

@@ -440,13 +440,13 @@ int main(int argc, char *argv[])
/* Patch the size array depending on command-line options */
if (!is32kMode)
maxsize[SECTTYPE_ROM0] = 0x4000;
sectionTypeInfo[SECTTYPE_ROM0].size = 0x4000;
if (!isWRA0Mode)
maxsize[SECTTYPE_WRAM0] = 0x1000;
sectionTypeInfo[SECTTYPE_WRAM0].size = 0x1000;
/* Patch the bank ranges array depending on command-line options */
if (isDmgMode)
bankranges[SECTTYPE_VRAM][1] = BANK_MIN_VRAM;
sectionTypeInfo[SECTTYPE_VRAM].lastBank = 0;
/* Read all object files first, */
for (obj_Setup(argc - curArgIndex); curArgIndex < argc; curArgIndex++)

View File

@@ -72,7 +72,7 @@ void out_AddSection(struct Section const *section)
[SECTTYPE_HRAM] = 1
};
uint32_t targetBank = section->bank - bankranges[section->type][0];
uint32_t targetBank = section->bank - sectionTypeInfo[section->type].firstBank;
uint32_t minNbBanks = targetBank + 1;
if (minNbBanks > maxNbBanks[section->type])
@@ -113,7 +113,7 @@ struct Section const *out_OverlappingSection(struct Section const *section)
{
struct SortedSections *banks = sections[section->type].banks;
struct SortedSection *ptr =
banks[section->bank - bankranges[section->type][0]].sections;
banks[section->bank - sectionTypeInfo[section->type].firstBank].sections;
while (ptr) {
if (ptr->section->org < section->org + section->size
@@ -166,7 +166,7 @@ static uint32_t checkOverlaySize(void)
static void coverOverlayBanks(uint32_t nbOverlayBanks)
{
/* 2 if is32kMode, 1 otherwise */
uint32_t nbRom0Banks = maxsize[SECTTYPE_ROM0] / BANK_SIZE;
uint32_t nbRom0Banks = sectionTypeInfo[SECTTYPE_ROM0].size / BANK_SIZE;
/* Discount ROM0 banks to avoid outputting too much */
uint32_t nbUncoveredBanks = nbOverlayBanks - nbRom0Banks > sections[SECTTYPE_ROMX].nbBanks
? nbOverlayBanks - nbRom0Banks
@@ -247,11 +247,11 @@ static void writeROM(void)
if (outputFile) {
writeBank(sections[SECTTYPE_ROM0].banks ? sections[SECTTYPE_ROM0].banks[0].sections
: NULL,
startaddr[SECTTYPE_ROM0], maxsize[SECTTYPE_ROM0]);
sectionTypeInfo[SECTTYPE_ROM0].startAddr, sectionTypeInfo[SECTTYPE_ROM0].size);
for (uint32_t i = 0 ; i < sections[SECTTYPE_ROMX].nbBanks; i++)
writeBank(sections[SECTTYPE_ROMX].banks[i].sections,
startaddr[SECTTYPE_ROMX], maxsize[SECTTYPE_ROMX]);
sectionTypeInfo[SECTTYPE_ROMX].startAddr, sectionTypeInfo[SECTTYPE_ROMX].size);
}
closeFile(outputFile);
@@ -345,7 +345,7 @@ static void writeSymBank(struct SortedSections const *bankSections,
qsort(symList, nbSymbols, sizeof(*symList), compareSymbols);
uint32_t symBank = bank + bankranges[type][0];
uint32_t symBank = bank + sectionTypeInfo[type].firstBank;
for (uint32_t i = 0; i < nbSymbols; i++) {
struct SortedSymbol *sym = &symList[i];
@@ -371,8 +371,8 @@ static uint16_t writeMapBank(struct SortedSections const *sectList,
struct SortedSection const *section = sectList->sections;
struct SortedSection const *zeroLenSection = sectList->zeroLenSections;
fprintf(mapFile, "%s bank #%" PRIu32 ":\n", typeNames[type],
bank + bankranges[type][0]);
fprintf(mapFile, "%s bank #%" PRIu32 ":\n", sectionTypeInfo[type].name,
bank + sectionTypeInfo[type].firstBank);
uint16_t used = 0;
@@ -413,7 +413,7 @@ static uint16_t writeMapBank(struct SortedSections const *sectList,
if (used == 0) {
fputs(" EMPTY\n\n", mapFile);
} else {
uint16_t slack = maxsize[type] - used;
uint16_t slack = sectionTypeInfo[type].size - used;
fprintf(mapFile, " SLACK: $%04" PRIx16 " byte%s\n\n", slack,
slack == 1 ? "" : "s");
@@ -442,7 +442,7 @@ static void writeMapUsed(uint32_t usedMap[MIN_NB_ELMS(SECTTYPE_INVALID)])
if (sections[type].nbBanks > 0) {
fprintf(mapFile, " %s: $%04" PRIx32 " byte%s in %" PRIu32 " bank%s\n",
typeNames[type], usedMap[type], usedMap[type] == 1 ? "" : "s",
sectionTypeInfo[type].name, usedMap[type], usedMap[type] == 1 ? "" : "s",
sections[type].nbBanks, sections[type].nbBanks == 1 ? "" : "s");
}
}

View File

@@ -18,6 +18,7 @@
#include "link/section.h"
#include "error.h"
#include "linkdefs.h"
FILE *linkerScript;
char *includeFileName;
@@ -299,7 +300,7 @@ static struct LinkerScriptToken *nextToken(void)
if (token.type == TOKEN_INVALID) {
/* Try to match a bank specifier */
for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) {
if (!strcmp(typeNames[type], str)) {
if (!strcmp(sectionTypeInfo[type].name, str)) {
token.type = TOKEN_BANK;
token.attr.secttype = type;
break;
@@ -376,7 +377,7 @@ struct SectionPlacement *script_NextSection(void)
for (enum SectionType i = 0; i < SECTTYPE_INVALID; i++) {
curaddr[i] = malloc(sizeof(*curaddr[i]) * nbbanks(i));
for (uint32_t b = 0; b < nbbanks(i); b++)
curaddr[i][b] = startaddr[i];
curaddr[i][b] = sectionTypeInfo[i].startAddr;
}
placement.type = SECTTYPE_INVALID;
@@ -394,12 +395,12 @@ struct SectionPlacement *script_NextSection(void)
if (placement.type != SECTTYPE_INVALID) {
if (curaddr[placement.type][bankID] > endaddr(placement.type) + 1)
errx("%s(%" PRIu32 "): Sections would extend past the end of %s ($%04" PRIx16 " > $%04" PRIx16 ")",
linkerScriptName, lineNo, typeNames[placement.type],
linkerScriptName, lineNo, sectionTypeInfo[placement.type].name,
curaddr[placement.type][bankID], endaddr(placement.type));
if (curaddr[placement.type][bankID] < startaddr[placement.type])
if (curaddr[placement.type][bankID] < sectionTypeInfo[placement.type].startAddr)
errx("%s(%" PRIu32 "): PC underflowed ($%04" PRIx16 " < $%04" PRIx16 ")",
linkerScriptName, lineNo,
curaddr[placement.type][bankID], startaddr[placement.type]);
curaddr[placement.type][bankID], sectionTypeInfo[placement.type].startAddr);
}
switch (parserState) {
@@ -483,17 +484,17 @@ struct SectionPlacement *script_NextSection(void)
errx("%s(%" PRIu32 "): Didn't specify a bank number",
linkerScriptName, lineNo);
else if (!hasArg)
arg = bankranges[placement.type][0];
else if (arg < bankranges[placement.type][0])
arg = sectionTypeInfo[placement.type].firstBank;
else if (arg < sectionTypeInfo[placement.type].firstBank)
errx("%s(%" PRIu32 "): specified bank number is too low (%" PRIu32 " < %" PRIu32 ")",
linkerScriptName, lineNo,
arg, bankranges[placement.type][0]);
else if (arg > bankranges[placement.type][1])
arg, sectionTypeInfo[placement.type].firstBank);
else if (arg > sectionTypeInfo[placement.type].lastBank)
errx("%s(%" PRIu32 "): specified bank number is too high (%" PRIu32 " > %" PRIu32 ")",
linkerScriptName, lineNo,
arg, bankranges[placement.type][1]);
arg, sectionTypeInfo[placement.type].lastBank);
bank = arg;
bankID = arg - bankranges[placement.type][0];
bankID = arg - sectionTypeInfo[placement.type].firstBank;
}
/* If we read a token we shouldn't have... */

View File

@@ -17,6 +17,7 @@
#include "error.h"
#include "hashmap.h"
#include "linkdefs.h"
HashMap sections;
@@ -133,7 +134,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
if (target->type != other->type)
errx("Section \"%s\" is defined with conflicting types %s and %s",
other->name, typeNames[target->type], typeNames[other->type]);
other->name, sectionTypeInfo[target->type].name, sectionTypeInfo[other->type].name);
if (other->isBankFixed) {
if (!target->isBankFixed) {
@@ -207,7 +208,7 @@ void sect_AddSection(struct Section *section)
mergeSections(other, section, section->modifier);
} else if (section->modifier == SECTION_UNION && sect_HasData(section->type)) {
errx("Section \"%s\" is of type %s, which cannot be unionized",
section->name, typeNames[section->type]);
section->name, sectionTypeInfo[section->type].name);
} else {
/* If not, add it */
hash_AddElement(sections, section->name, section);
@@ -261,11 +262,11 @@ static void doSanityChecks(struct Section *section, void *ptr)
section->isAlignFixed = false;
/* Too large an alignment may not be satisfiable */
if (section->isAlignFixed && (section->alignMask & startaddr[section->type]))
if (section->isAlignFixed && (section->alignMask & sectionTypeInfo[section->type].startAddr))
error(NULL, 0, "%s: %s sections cannot be aligned to $%04x bytes",
section->name, typeNames[section->type], section->alignMask + 1);
section->name, sectionTypeInfo[section->type].name, section->alignMask + 1);
uint32_t minbank = bankranges[section->type][0], maxbank = bankranges[section->type][1];
uint32_t minbank = sectionTypeInfo[section->type].firstBank, maxbank = sectionTypeInfo[section->type].lastBank;
if (section->isBankFixed && section->bank < minbank && section->bank > maxbank)
error(NULL, 0, minbank == maxbank
@@ -274,9 +275,9 @@ static void doSanityChecks(struct Section *section, void *ptr)
section->name, section->bank, minbank, maxbank);
/* Check if section has a chance to be placed */
if (section->size > maxsize[section->type])
if (section->size > sectionTypeInfo[section->type].size)
error(NULL, 0, "Section \"%s\" is bigger than the max size for that type: %#" PRIx16 " > %#" PRIx16,
section->name, section->size, maxsize[section->type]);
section->name, section->size, sectionTypeInfo[section->type].size);
/* Translate loose constraints to strong ones when they're equivalent */
@@ -295,11 +296,11 @@ static void doSanityChecks(struct Section *section, void *ptr)
}
/* Ensure the target address is valid */
if (section->org < startaddr[section->type]
if (section->org < sectionTypeInfo[section->type].startAddr
|| section->org > endaddr(section->type))
error(NULL, 0, "Section \"%s\"'s fixed address %#" PRIx16 " is outside of range [%#"
PRIx16 "; %#" PRIx16 "]", section->name, section->org,
startaddr[section->type], endaddr(section->type));
sectionTypeInfo[section->type].startAddr, endaddr(section->type));
if (section->org + section->size > endaddr(section->type) + 1)
error(NULL, 0, "Section \"%s\"'s end address %#x is greater than last address %#x",