mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Some RGBLINK refactoring
- Consistently refer to `Section` fragments/unions as "pieces" (renaming `.nextu`) - Remove `Symbol`'s `.label()` accessors (use `std::get<Label>`) - Move some `Label`-related logic into `Symbol` methods
This commit is contained in:
@@ -53,11 +53,10 @@ static void initFreeSpace() {
|
||||
static void assignSection(Section §ion, MemoryLocation const &location) {
|
||||
// Propagate the assigned location to all UNIONs/FRAGMENTs
|
||||
// so `jr` patches in them will have the correct offset
|
||||
for (Section *next = §ion; next != nullptr; next = next->nextu.get()) {
|
||||
next->org = location.address;
|
||||
next->bank = location.bank;
|
||||
for (Section *piece = §ion; piece != nullptr; piece = piece->nextPiece.get()) {
|
||||
piece->org = location.address;
|
||||
piece->bank = location.bank;
|
||||
}
|
||||
|
||||
out_AddSection(section);
|
||||
}
|
||||
|
||||
|
||||
@@ -248,10 +248,9 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
typeInfo.name.c_str()
|
||||
);
|
||||
} else {
|
||||
// SDCC areas don't have a type assigned yet, so the linker script is used to give them
|
||||
// one.
|
||||
for (Section *fragment = section; fragment; fragment = fragment->nextu.get()) {
|
||||
fragment->type = activeType;
|
||||
// SDCC areas don't have a type assigned yet, so the linker script gives them one.
|
||||
for (Section *piece = section; piece != nullptr; piece = piece->nextPiece.get()) {
|
||||
piece->type = activeType;
|
||||
}
|
||||
}
|
||||
} else if (section->type != activeType) {
|
||||
|
||||
@@ -390,25 +390,6 @@ static void readSection(
|
||||
}
|
||||
}
|
||||
|
||||
// Links a symbol to a section, keeping the section's symbol list sorted.
|
||||
static void linkSymToSect(Symbol &symbol, Section §ion) {
|
||||
uint32_t a = 0, b = section.symbols.size();
|
||||
int32_t symbolOffset = symbol.label().offset;
|
||||
|
||||
while (a != b) {
|
||||
uint32_t c = (a + b) / 2;
|
||||
int32_t otherOffset = section.symbols[c]->label().offset;
|
||||
|
||||
if (otherOffset > symbolOffset) {
|
||||
b = c;
|
||||
} else {
|
||||
a = c + 1;
|
||||
}
|
||||
}
|
||||
|
||||
section.symbols.insert(section.symbols.begin() + a, &symbol);
|
||||
}
|
||||
|
||||
// Reads an assertion from a file.
|
||||
static void readAssertion(
|
||||
FILE *file,
|
||||
@@ -512,15 +493,11 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
std::vector<uint32_t> nbSymPerSect(nbSections, 0);
|
||||
|
||||
verbosePrint(VERB_INFO, "Reading %" PRIu32 " symbols...\n", nbSymbols);
|
||||
for (uint32_t i = 0; i < nbSymbols; ++i) {
|
||||
// Read symbol
|
||||
Symbol &symbol = fileSymbols[i];
|
||||
|
||||
readSymbol(file, symbol, fileName, nodes[fileID]);
|
||||
|
||||
sym_AddSymbol(symbol);
|
||||
if (std::holds_alternative<Label>(symbol.data)) {
|
||||
++nbSymPerSect[std::get<Label>(symbol.data).sectionID];
|
||||
for (Symbol &sym : fileSymbols) {
|
||||
readSymbol(file, sym, fileName, nodes[fileID]);
|
||||
sym_AddSymbol(sym);
|
||||
if (std::holds_alternative<Label>(sym.data)) {
|
||||
++nbSymPerSect[std::get<Label>(sym.data).sectionID];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,9 +506,8 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
|
||||
verbosePrint(VERB_INFO, "Reading %" PRIu32 " sections...\n", nbSections);
|
||||
for (uint32_t i = 0; i < nbSections; ++i) {
|
||||
// Read section
|
||||
fileSections[i] = std::make_unique<Section>();
|
||||
fileSections[i]->nextu = nullptr;
|
||||
fileSections[i]->nextPiece = nullptr;
|
||||
readSection(file, *fileSections[i], fileName, nodes[fileID]);
|
||||
fileSections[i]->fileSymbols = &fileSymbols;
|
||||
fileSections[i]->symbols.reserve(nbSymPerSect[i]);
|
||||
@@ -549,21 +525,18 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
}
|
||||
|
||||
// Give patches' PC section pointers to their sections
|
||||
for (uint32_t i = 0; i < nbSections; ++i) {
|
||||
if (sectTypeHasData(fileSections[i]->type)) {
|
||||
for (Patch &patch : fileSections[i]->patches) {
|
||||
for (std::unique_ptr<Section> const § : fileSections) {
|
||||
if (sectTypeHasData(sect->type)) {
|
||||
for (Patch &patch : sect->patches) {
|
||||
linkPatchToPCSect(patch, fileSections);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give symbols' section pointers to their sections
|
||||
for (uint32_t i = 0; i < nbSymbols; ++i) {
|
||||
if (std::holds_alternative<Label>(fileSymbols[i].data)) {
|
||||
Label &label = std::get<Label>(fileSymbols[i].data);
|
||||
label.section = fileSections[label.sectionID].get();
|
||||
// Give the section a pointer to the symbol as well
|
||||
linkSymToSect(fileSymbols[i], *label.section);
|
||||
for (Symbol &sym : fileSymbols) {
|
||||
if (std::holds_alternative<Label>(sym.data)) {
|
||||
sym.linkToSection(*fileSections[std::get<Label>(sym.data).sectionID]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,23 +545,11 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
||||
sect_AddSection(std::move(fileSections[i]));
|
||||
}
|
||||
|
||||
// Fix symbols' section pointers to component sections
|
||||
// Fix symbols' section pointers to section "pieces"
|
||||
// This has to run **after** all the `sect_AddSection()` calls,
|
||||
// so that `sect_GetSection()` will work
|
||||
for (uint32_t i = 0; i < nbSymbols; ++i) {
|
||||
if (std::holds_alternative<Label>(fileSymbols[i].data)) {
|
||||
Label &label = std::get<Label>(fileSymbols[i].data);
|
||||
Section *section = label.section;
|
||||
if (section->modifier != SECTION_NORMAL) {
|
||||
// Associate the symbol with the main section, not the "component" one
|
||||
label.section = sect_GetSection(section->name);
|
||||
}
|
||||
if (section->modifier == SECTION_FRAGMENT) {
|
||||
// Add the fragment's offset to the symbol's
|
||||
// (`section->offset` is computed by `sect_AddSection`)
|
||||
label.offset += section->offset;
|
||||
}
|
||||
}
|
||||
for (Symbol &sym : fileSymbols) {
|
||||
sym.fixSectionOffset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -317,12 +317,12 @@ static bool compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) {
|
||||
template<typename F>
|
||||
static void forEachSortedSection(SortedSections const &bankSections, F callback) {
|
||||
for (Section const *sect : bankSections.zeroLenSections) {
|
||||
for (; sect; sect = sect->nextu.get()) {
|
||||
for (; sect != nullptr; sect = sect->nextPiece.get()) {
|
||||
callback(*sect);
|
||||
}
|
||||
}
|
||||
for (Section const *sect : bankSections.sections) {
|
||||
for (; sect; sect = sect->nextu.get()) {
|
||||
for (; sect != nullptr; sect = sect->nextPiece.get()) {
|
||||
callback(*sect);
|
||||
}
|
||||
}
|
||||
@@ -349,13 +349,14 @@ static void writeSymBank(SortedSections const &bankSections, SectionType type, u
|
||||
if (sym->name.empty() || !startsIdentifier(sym->name[0])) {
|
||||
continue;
|
||||
}
|
||||
uint16_t addr = static_cast<uint16_t>(sym->label().offset + sect.org);
|
||||
assume(std::holds_alternative<Label>(sym->data));
|
||||
uint16_t addr = static_cast<uint16_t>(std::get<Label>(sym->data).offset + sect.org);
|
||||
uint16_t parentAddr = addr;
|
||||
if (auto pos = sym->name.find('.'); pos != std::string::npos) {
|
||||
std::string parentName = sym->name.substr(0, pos);
|
||||
if (Symbol const *parentSym = sym_GetSymbol(parentName);
|
||||
parentSym && std::holds_alternative<Label>(parentSym->data)) {
|
||||
Label const &parentLabel = parentSym->label();
|
||||
Label const &parentLabel = std::get<Label>(parentSym->data);
|
||||
Section const &parentSection = *parentLabel.section;
|
||||
parentAddr = static_cast<uint16_t>(parentLabel.offset + parentSection.org);
|
||||
}
|
||||
@@ -435,7 +436,7 @@ uint16_t forEachSection(SortedSections const §List, F callback) {
|
||||
static void writeMapSymbols(Section const *sect) {
|
||||
uint16_t org = sect->org;
|
||||
|
||||
for (bool announced = true; sect; sect = sect->nextu.get(), announced = false) {
|
||||
for (bool announced = true; sect != nullptr; sect = sect->nextPiece.get(), announced = false) {
|
||||
for (Symbol *sym : sect->symbols) {
|
||||
// Don't output symbols that begin with an illegal character
|
||||
if (sym->name.empty() || !startsIdentifier(sym->name[0])) {
|
||||
@@ -450,8 +451,10 @@ static void writeMapSymbols(Section const *sect) {
|
||||
}
|
||||
announced = true;
|
||||
}
|
||||
assume(std::holds_alternative<Label>(sym->data));
|
||||
uint32_t address = std::get<Label>(sym->data).offset + org;
|
||||
// Space matches "\tSECTION: $xxxx ..."
|
||||
fprintf(mapFile, "\t $%04" PRIx32 " = ", sym->label().offset + org);
|
||||
fprintf(mapFile, "\t $%04" PRIx32 " = ", address);
|
||||
writeSymName(sym->name, mapFile);
|
||||
putc('\n', mapFile);
|
||||
}
|
||||
|
||||
@@ -580,14 +580,14 @@ static void applyFilePatches(Section §ion, Section &dataSection) {
|
||||
}
|
||||
}
|
||||
|
||||
// Applies all of a section's patches, iterating over "components" of unionized sections
|
||||
// Applies all of a section's patches, iterating over "pieces" of unionized sections
|
||||
static void applyPatches(Section §ion) {
|
||||
if (!sectTypeHasData(section.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Section *component = §ion; component; component = component->nextu.get()) {
|
||||
applyFilePatches(*component, section);
|
||||
for (Section *piece = §ion; piece != nullptr; piece = piece->nextPiece.get()) {
|
||||
applyFilePatches(*piece, section);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
||||
}
|
||||
curSection->isAlignFixed = false; // No such concept!
|
||||
curSection->fileSymbols = &fileSymbols; // IDs are instead per-section
|
||||
curSection->nextu = nullptr;
|
||||
curSection->nextPiece = nullptr;
|
||||
|
||||
fileSections.push_back({.section = std::move(curSection), .writeIndex = 0});
|
||||
break;
|
||||
@@ -902,21 +902,10 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
||||
sect_AddSection(std::move(section));
|
||||
}
|
||||
|
||||
// Fix symbols' section pointers to component sections
|
||||
// Fix symbols' section pointers to section "pieces"
|
||||
// This has to run **after** all the `sect_AddSection()` calls,
|
||||
// so that `sect_GetSection()` will work
|
||||
for (Symbol &sym : fileSymbols) {
|
||||
if (std::holds_alternative<Label>(sym.data)) {
|
||||
Label &label = std::get<Label>(sym.data);
|
||||
if (Section *section = label.section; section->modifier != SECTION_NORMAL) {
|
||||
if (section->modifier == SECTION_FRAGMENT) {
|
||||
// Add the fragment's offset to the symbol's
|
||||
// (`section->offset` is computed by `sect_AddSection`)
|
||||
label.offset += section->offset;
|
||||
}
|
||||
// Associate the symbol with the main section, not the "component" one
|
||||
label.section = sect_GetSection(section->name);
|
||||
}
|
||||
}
|
||||
sym.fixSectionOffset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,10 +189,10 @@ static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// Note that the order in which fragments are stored in the `nextu` list does not
|
||||
// Note that the order in which fragments are stored in the `nextPiece` list does not
|
||||
// really matter, only that offsets were properly computed above
|
||||
other->nextu = std::move(target.nextu);
|
||||
target.nextu = std::move(other);
|
||||
other->nextPiece = std::move(target.nextPiece);
|
||||
target.nextPiece = std::move(other);
|
||||
}
|
||||
|
||||
void sect_AddSection(std::unique_ptr<Section> &§ion) {
|
||||
|
||||
@@ -90,3 +90,43 @@ void sym_TraceLocalAliasedSymbols(std::string const &name) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Symbol::linkToSection(Section §ion) {
|
||||
assume(std::holds_alternative<Label>(data));
|
||||
Label &label = std::get<Label>(data);
|
||||
// Link the symbol to the section
|
||||
label.section = §ion;
|
||||
// Link the section to the symbol, keeping the section's symbol list sorted
|
||||
uint32_t a = 0, b = section.symbols.size();
|
||||
while (a != b) {
|
||||
uint32_t c = (a + b) / 2;
|
||||
assume(std::holds_alternative<Label>(section.symbols[c]->data));
|
||||
Label const &other = std::get<Label>(section.symbols[c]->data);
|
||||
if (other.offset > label.offset) {
|
||||
b = c;
|
||||
} else {
|
||||
a = c + 1;
|
||||
}
|
||||
}
|
||||
section.symbols.insert(section.symbols.begin() + a, this);
|
||||
}
|
||||
|
||||
void Symbol::fixSectionOffset() {
|
||||
if (!std::holds_alternative<Label>(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Label &label = std::get<Label>(data);
|
||||
Section *section = label.section;
|
||||
assume(section);
|
||||
|
||||
if (section->modifier != SECTION_NORMAL) {
|
||||
// Associate the symbol with the main section, not the "piece"
|
||||
label.section = sect_GetSection(section->name);
|
||||
}
|
||||
if (section->modifier == SECTION_FRAGMENT) {
|
||||
// Add the fragment's offset to the symbol's
|
||||
// (`section->offset` is computed by `sect_AddSection`)
|
||||
label.offset += section->offset;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user