diff --git a/include/link/patch.hpp b/include/link/patch.hpp index 7dafd639..8a31cd64 100644 --- a/include/link/patch.hpp +++ b/include/link/patch.hpp @@ -16,7 +16,7 @@ struct Assertion { struct Patch patch; // Also used for its `.type` char *message; // This would be redundant with `.section->fileSymbols`... but `section` is sometimes NULL! - std::vector *fileSymbols; + std::vector *fileSymbols; }; /* diff --git a/include/link/sdas_obj.hpp b/include/link/sdas_obj.hpp index 9f25809e..b282461b 100644 --- a/include/link/sdas_obj.hpp +++ b/include/link/sdas_obj.hpp @@ -10,6 +10,6 @@ struct FileStackNode; struct Symbol; -void sdobj_ReadFile(struct FileStackNode const *fileName, FILE *file, std::vector &fileSymbols); +void sdobj_ReadFile(struct FileStackNode const *fileName, FILE *file, std::vector &fileSymbols); #endif // RGBDS_LINK_SDAS_OBJ_H diff --git a/include/link/section.hpp b/include/link/section.hpp index 7b31471b..3fbf6b7c 100644 --- a/include/link/section.hpp +++ b/include/link/section.hpp @@ -47,7 +47,7 @@ struct Section { uint8_t *data; // Array of size `size` std::vector *patches; // Extra info computed during linking - std::vector *fileSymbols; + std::vector *fileSymbols; std::vector *symbols; struct Section *nextu; // The next "component" of this unionized sect }; diff --git a/src/link/object.cpp b/src/link/object.cpp index 5762f79e..d68b91ae 100644 --- a/src/link/object.cpp +++ b/src/link/object.cpp @@ -25,7 +25,7 @@ #include "linkdefs.hpp" #include "version.hpp" -static std::deque> symbolLists; +static std::deque> symbolLists; static std::vector> nodes; static std::deque assertions; @@ -385,20 +385,20 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam * @param symbol The symbol to link * @param section The section to link */ -static void linkSymToSect(struct Symbol *symbol, struct Section *section) +static void linkSymToSect(struct Symbol &symbol, struct Section *section) { uint32_t a = 0, b = section->symbols->size(); while (a != b) { uint32_t c = (a + b) / 2; - if ((*section->symbols)[c]->offset > symbol->offset) + if ((*section->symbols)[c]->offset > symbol.offset) b = c; else a = c + 1; } - section->symbols->insert(section->symbols->begin() + a, symbol); + section->symbols->insert(section->symbols->begin() + a, &symbol); } /* @@ -465,7 +465,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) if (!where.name) fatal(NULL, 0, "Failed to duplicate \"%s\"'s name: %s", fileName, strerror(errno)); - std::vector &fileSymbols = symbolLists.emplace_front(); + std::vector &fileSymbols = symbolLists.emplace_front(); sdobj_ReadFile(&where, file, fileSymbols); return; @@ -505,23 +505,20 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) readFileStackNode(file, nodes[fileID], i, fileName); // This file's symbols, kept to link sections to them - std::vector &fileSymbols = symbolLists.emplace_front(nbSymbols); + std::vector &fileSymbols = symbolLists.emplace_front(nbSymbols); std::vector nbSymPerSect(nbSections, 0); verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols); for (uint32_t i = 0; i < nbSymbols; i++) { // Read symbol - struct Symbol *symbol = (struct Symbol *)malloc(sizeof(*symbol)); + struct Symbol &symbol = fileSymbols[i]; - if (!symbol) - err("%s: Failed to create new symbol", fileName); - readSymbol(file, symbol, fileName, nodes[fileID]); + readSymbol(file, &symbol, fileName, nodes[fileID]); - fileSymbols[i] = symbol; - if (symbol->type == SYMTYPE_EXPORT) - sym_AddSymbol(symbol); - if (symbol->sectionID != -1) - nbSymPerSect[symbol->sectionID]++; + if (symbol.type == SYMTYPE_EXPORT) + sym_AddSymbol(&symbol); + if (symbol.sectionID != -1) + nbSymPerSect[symbol.sectionID]++; } // This file's sections, stored in a table to link symbols to them @@ -555,10 +552,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) // Give symbols' section pointers to their sections for (uint32_t i = 0; i < nbSymbols; i++) { - int32_t sectionID = fileSymbols[i]->sectionID; + int32_t sectionID = fileSymbols[i].sectionID; if (sectionID == -1) { - fileSymbols[i]->section = NULL; + fileSymbols[i].section = NULL; } else { struct Section *section = fileSections[sectionID]; @@ -568,10 +565,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) if (section->modifier != SECTION_NORMAL) { if (section->modifier == SECTION_FRAGMENT) // Add the fragment's offset to the symbol's - fileSymbols[i]->offset += section->offset; + fileSymbols[i].offset += section->offset; section = getMainSection(section); } - fileSymbols[i]->section = section; + fileSymbols[i].section = section; } } @@ -630,12 +627,6 @@ static void freeSection(struct Section *section) } while (section); } -static void freeSymbol(struct Symbol *symbol) -{ - free(symbol->name); - free(symbol); -} - void obj_Cleanup(void) { for (std::vector &fileNodes : nodes) { @@ -648,9 +639,9 @@ void obj_Cleanup(void) sect_ForEach(freeSection); sect_CleanupSections(); - for (std::vector &fileSymbols : symbolLists) { - for (struct Symbol *symbol : fileSymbols) - freeSymbol(symbol); + for (std::vector &fileSymbols : symbolLists) { + for (struct Symbol &symbol : fileSymbols) + free(symbol.name); } for (struct Assertion &assert : assertions) diff --git a/src/link/patch.cpp b/src/link/patch.cpp index 0e466feb..39f3883b 100644 --- a/src/link/patch.cpp +++ b/src/link/patch.cpp @@ -56,16 +56,16 @@ static uint32_t getRPNByte(uint8_t const **expression, int32_t *size, return *(*expression)++; } -static struct Symbol const *getSymbol(std::vector const &symbolList, uint32_t index) +static struct Symbol const *getSymbol(std::vector const &symbolList, uint32_t index) { assert(index != (uint32_t)-1); // PC needs to be handled specially, not here - struct Symbol *symbol = symbolList[index]; + struct Symbol const &symbol = symbolList[index]; // If the symbol is defined elsewhere... - if (symbol->type == SYMTYPE_IMPORT) - return sym_GetSymbol(symbol->name); + if (symbol.type == SYMTYPE_IMPORT) + return sym_GetSymbol(symbol.name); - return symbol; + return &symbol; } /* @@ -77,7 +77,7 @@ static struct Symbol const *getSymbol(std::vector const &symbol * errors caused by the value should be suppressed. */ static int32_t computeRPNExpr(struct Patch const *patch, - std::vector const &fileSymbols) + std::vector const &fileSymbols) { // Small shortcut to avoid a lot of repetition #define popRPN() popRPN(patch->src, patch->lineNo) @@ -224,13 +224,13 @@ static int32_t computeRPNExpr(struct Patch const *patch, if (!symbol) { error(patch->src, patch->lineNo, "Requested BANK() of symbol \"%s\", which was not found", - fileSymbols[value]->name); + fileSymbols[value].name); isError = true; value = 1; } else if (!symbol->section) { error(patch->src, patch->lineNo, "Requested BANK() of non-label symbol \"%s\"", - fileSymbols[value]->name); + fileSymbols[value].name); isError = true; value = 1; } else { @@ -385,7 +385,7 @@ static int32_t computeRPNExpr(struct Patch const *patch, if (!symbol) { error(patch->src, patch->lineNo, - "Unknown symbol \"%s\"", fileSymbols[value]->name); + "Unknown symbol \"%s\"", fileSymbols[value].name); isError = true; } else { value = symbol->value; diff --git a/src/link/sdas_obj.cpp b/src/link/sdas_obj.cpp index 5c1eb4fc..c735f0a3 100644 --- a/src/link/sdas_obj.cpp +++ b/src/link/sdas_obj.cpp @@ -144,7 +144,7 @@ enum RelocFlags { | 1 << RELOC_EXPR24 | 1 << RELOC_BANKBYTE, }; -void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector &fileSymbols) { +void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector &fileSymbols) { size_t bufLen = 256; char *line = (char *)malloc(bufLen); char const *token; @@ -369,59 +369,55 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vectorobjFileName = where->name; - symbol->src = where; - symbol->lineNo = lineNo; + symbol.objFileName = where->name; + symbol.src = where; + symbol.lineNo = lineNo; // No need to set the `sectionID`, since we can directly set the pointer - symbol->section = nbSections != 0 ? fileSections[nbSections - 1].section : NULL; + symbol.section = nbSections != 0 ? fileSections[nbSections - 1].section : NULL; getToken(line, "'S' line is too short"); - symbol->name = strdup(token); - if (!symbol->name) + symbol.name = strdup(token); + if (!symbol.name) fatal(where, lineNo, "Failed to alloc symbol name: %s", strerror(errno)); getToken(NULL, "'S' line is too short"); // It might be an `offset`, but both types are the same so type punning is fine - symbol->value = parseNumber(where, lineNo, &token[3], numberType); - if (symbol->section && symbol->section->isAddressFixed) { - assert(symbol->offset >= symbol->section->org); - symbol->offset -= symbol->section->org; - assert(symbol->offset <= symbol->section->size); + symbol.value = parseNumber(where, lineNo, &token[3], numberType); + if (symbol.section && symbol.section->isAddressFixed) { + assert(symbol.offset >= symbol.section->org); + symbol.offset -= symbol.section->org; + assert(symbol.offset <= symbol.section->size); } // Expected format: /[DR]ef[0-9A-F]+/i if (token[0] == 'R' || token[0] == 'r') { - symbol->type = SYMTYPE_IMPORT; + symbol.type = SYMTYPE_IMPORT; // TODO: hard error if the rest is not zero } else if (token[0] != 'D' && token[0] != 'd') { fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\""); } else { // All symbols are exported - symbol->type = SYMTYPE_EXPORT; - struct Symbol const *other = sym_GetSymbol(symbol->name); + symbol.type = SYMTYPE_EXPORT; + struct Symbol const *other = sym_GetSymbol(symbol.name); if (other) { // The same symbol can only be defined twice if neither // definition is in a floating section if ((other->section && !other->section->isAddressFixed) - || (symbol->section && !symbol->section->isAddressFixed)) { - sym_AddSymbol(symbol); // This will error out - } else if (other->value != symbol->value) { + || (symbol.section && !symbol.section->isAddressFixed)) { + sym_AddSymbol(&symbol); // This will error out + } else if (other->value != symbol.value) { error(where, lineNo, "Definition of \"%s\" conflicts with definition in %s (%" PRId32 " != %" PRId32 ")", - symbol->name, other->objFileName, symbol->value, other->value); + symbol.name, other->objFileName, symbol.value, other->value); } } else { // Add a new definition - sym_AddSymbol(symbol); + sym_AddSymbol(&symbol); } // It's fine to keep modifying the symbol after `AddSymbol`, only // the name must not be modified @@ -430,7 +426,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vectorsymbols->push_back(symbol); + fileSections[nbSections - 1].section->symbols->push_back(&symbol); expectEol("'S' line is too long"); @@ -582,34 +578,34 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector= nbSymbols) fatal(where, lineNo, "Reloc refers to symbol #%" PRIu16 " out of %zu", idx, nbSymbols); - struct Symbol const *sym = fileSymbols[idx]; + struct Symbol const &sym = fileSymbols[idx]; // SDCC has a bunch of "magic symbols" that start with a // letter and an underscore. These are not compatibility // hacks, this is how SDLD actually works. - if (sym->name[0] == 'b' && sym->name[1] == '_') { + if (sym.name[0] == 'b' && sym.name[1] == '_') { // Look for the symbol being referenced, and use its index instead for (idx = 0; idx < nbSymbols; ++idx) { - if (strcmp(&sym->name[1], fileSymbols[idx]->name) == 0) + if (strcmp(&sym.name[1], fileSymbols[idx].name) == 0) break; } if (idx == nbSymbols) fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"", - sym->name, &sym->name[1]); + sym.name, &sym.name[1]); patch.rpnExpression.resize(5); patch.rpnExpression[0] = RPN_BANK_SYM; patch.rpnExpression[1] = idx; patch.rpnExpression[2] = idx >> 8; patch.rpnExpression[3] = idx >> 16; patch.rpnExpression[4] = idx >> 24; - } else if (sym->name[0] == 'l' && sym->name[1] == '_') { - patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1); + } else if (sym.name[0] == 'l' && sym.name[1] == '_') { + patch.rpnExpression.resize(1 + strlen(&sym.name[2]) + 1); patch.rpnExpression[0] = RPN_SIZEOF_SECT; - strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); - } else if (sym->name[0] == 's' && sym->name[1] == '_') { - patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1); + strcpy((char *)&patch.rpnExpression[1], &sym.name[2]); + } else if (sym.name[0] == 's' && sym.name[1] == '_') { + patch.rpnExpression.resize(1 + strlen(&sym.name[2]) + 1); patch.rpnExpression[0] = RPN_STARTOF_SECT; - strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); + strcpy((char *)&patch.rpnExpression[1], &sym.name[2]); } else { patch.rpnExpression.resize(5); patch.rpnExpression[0] = RPN_SYM;