Use std::vector's .size() for SDCC sections and symbols

This commit is contained in:
Rangi42
2024-02-28 12:26:27 -05:00
committed by Sylvie
parent c3eb532439
commit e1ac51d7da

View File

@@ -234,7 +234,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
uint16_t writeIndex; uint16_t writeIndex;
}; };
std::vector<struct FileSection> fileSections; std::vector<struct FileSection> fileSections;
size_t nbSections = 0, nbSymbols = 0;
size_t nbBytes = 0; // How many bytes are in `data`, including the ADDR_SIZE "header" bytes size_t nbBytes = 0; // How many bytes are in `data`, including the ADDR_SIZE "header" bytes
size_t dataCapacity = 16 + ADDR_SIZE; // SDCC object files usually contain 16 bytes per T line size_t dataCapacity = 16 + ADDR_SIZE; // SDCC object files usually contain 16 bytes per T line
uint8_t *data = (uint8_t *)malloc(sizeof(*data) * dataCapacity); uint8_t *data = (uint8_t *)malloc(sizeof(*data) * dataCapacity);
@@ -253,27 +252,26 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
break; break;
case 'A': { case 'A': {
if (nbSections == expectedNbAreas) if (fileSections.size() == expectedNbAreas)
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32, warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32,
expectedNbAreas); expectedNbAreas);
fileSections.resize(nbSections + 1);
fileSections[nbSections].writeIndex = 0;
struct Section *curSection = (struct Section *)malloc(sizeof(*curSection)); struct Section *curSection = (struct Section *)malloc(sizeof(*curSection));
if (!curSection) if (!curSection)
fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno)); fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno));
fileSections[nbSections].section = curSection;
getToken(line, "'A' line is too short"); getToken(line, "'A' line is too short");
assert(strlen(token) != 0); // This should be impossible, tokens are non-empty assert(strlen(token) != 0); // This should be impossible, tokens are non-empty
// The following is required for fragment offsets to be reliably predicted // The following is required for fragment offsets to be reliably predicted
for (size_t i = 0; i < nbSections; ++i) { for (struct FileSection &entry : fileSections) {
if (!strcmp(token, fileSections[i].section->name->c_str())) if (!strcmp(token, entry.section->name->c_str()))
fatal(where, lineNo, "Area \"%s\" already defined earlier", fatal(where, lineNo, "Area \"%s\" already defined earlier",
token); token);
} }
char const *sectionName = token; // We'll deal with the section's name depending on type char const *sectionName = token; // We'll deal with the section's name depending on type
fileSections.push_back({ .section = curSection, .writeIndex = 0 });
expectToken("size", 'A'); expectToken("size", 'A');
getToken(NULL, "'A' line is too short"); getToken(NULL, "'A' line is too short");
@@ -355,13 +353,11 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
fatal(where, lineNo, "Failed to alloc new area's symbol list: %s", fatal(where, lineNo, "Failed to alloc new area's symbol list: %s",
strerror(errno)); strerror(errno));
curSection->nextu = NULL; curSection->nextu = NULL;
++nbSections;
break; break;
} }
case 'S': { case 'S': {
if (nbSymbols == expectedNbSymbols) if (fileSymbols.size() == expectedNbSymbols)
warning(where, lineNo, "Got more 'S' lines than the expected %" PRIu32, warning(where, lineNo, "Got more 'S' lines than the expected %" PRIu32,
expectedNbSymbols); expectedNbSymbols);
struct Symbol &symbol = fileSymbols.emplace_back(); struct Symbol &symbol = fileSymbols.emplace_back();
@@ -372,7 +368,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
symbol.lineNo = lineNo; symbol.lineNo = lineNo;
// No need to set the `sectionID`, since we can directly set the pointer // No need to set the `sectionID`, since we can directly set the pointer
symbol.section = nbSections != 0 ? fileSections[nbSections - 1].section : NULL; symbol.section = !fileSections.empty() ? fileSections.back().section : NULL;
getToken(line, "'S' line is too short"); getToken(line, "'S' line is too short");
symbol.name = new(std::nothrow) std::string(token); symbol.name = new(std::nothrow) std::string(token);
@@ -420,12 +416,10 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
if (strncasecmp(&token[1], "ef", 2) != 0) if (strncasecmp(&token[1], "ef", 2) != 0)
fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\""); fatal(where, lineNo, "'S' line is neither \"Def\" nor \"Ref\"");
if (nbSections != 0) if (!fileSections.empty())
fileSections[nbSections - 1].section->symbols->push_back(&symbol); fileSections.back().section->symbols->push_back(&symbol);
expectEol("'S' line is too long"); expectEol("'S' line is too long");
++nbSymbols;
break; break;
} }
@@ -468,9 +462,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
areaIdx = parseByte(where, lineNo, token, numberType); areaIdx = parseByte(where, lineNo, token, numberType);
getToken(NULL, "'R' line is too short"); getToken(NULL, "'R' line is too short");
areaIdx |= (uint16_t)parseByte(where, lineNo, token, numberType) << 8; areaIdx |= (uint16_t)parseByte(where, lineNo, token, numberType) << 8;
if (areaIdx >= nbSections) if (areaIdx >= fileSections.size())
fatal(where, lineNo, "'R' line references area #%" PRIu16 ", but there are only %zu (so far)", fatal(where, lineNo, "'R' line references area #%" PRIu16 ", but there are only %zu (so far)",
areaIdx, nbSections); areaIdx, fileSections.size());
assert(!fileSections.empty()); // There should be at least one, from the above check assert(!fileSections.empty()); // There should be at least one, from the above check
struct Section *section = fileSections[areaIdx].section; struct Section *section = fileSections[areaIdx].section;
uint16_t *writeIndex = &fileSections[areaIdx].writeIndex; uint16_t *writeIndex = &fileSections[areaIdx].writeIndex;
@@ -570,9 +564,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
// Bit 4 specifies signedness, but I don't think that matters? // Bit 4 specifies signedness, but I don't think that matters?
// Generate a RPN expression from the info and flags // Generate a RPN expression from the info and flags
if (flags & 1 << RELOC_ISSYM) { if (flags & 1 << RELOC_ISSYM) {
if (idx >= nbSymbols) if (idx >= fileSymbols.size())
fatal(where, lineNo, "Reloc refers to symbol #%" PRIu16 " out of %zu", fatal(where, lineNo, "Reloc refers to symbol #%" PRIu16 " out of %zu",
idx, nbSymbols); idx, fileSymbols.size());
struct Symbol const &sym = fileSymbols[idx]; struct Symbol const &sym = fileSymbols[idx];
// SDCC has a bunch of "magic symbols" that start with a // SDCC has a bunch of "magic symbols" that start with a
@@ -580,12 +574,12 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
// hacks, this is how SDLD actually works. // hacks, this is how SDLD actually works.
if (sym.name->starts_with("b_")) { if (sym.name->starts_with("b_")) {
// Look for the symbol being referenced, and use its index instead // Look for the symbol being referenced, and use its index instead
for (idx = 0; idx < nbSymbols; ++idx) { for (idx = 0; idx < fileSymbols.size(); ++idx) {
if (sym.name->ends_with(*fileSymbols[idx].name) && if (sym.name->ends_with(*fileSymbols[idx].name) &&
1 + sym.name->length() == fileSymbols[idx].name->length()) 1 + sym.name->length() == fileSymbols[idx].name->length())
break; break;
} }
if (idx == nbSymbols) if (idx == fileSymbols.size())
fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"", fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"",
sym.name->c_str(), &sym.name->c_str()[1]); sym.name->c_str(), &sym.name->c_str()[1]);
patch.rpnExpression.resize(5); patch.rpnExpression.resize(5);
@@ -611,9 +605,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
patch.rpnExpression[4] = idx >> 24; patch.rpnExpression[4] = idx >> 24;
} }
} else { } else {
if (idx >= nbSections) if (idx >= fileSections.size())
fatal(where, lineNo, "Reloc refers to area #%" PRIu16 " out of %zu", fatal(where, lineNo, "Reloc refers to area #%" PRIu16 " out of %zu",
idx, nbSections); idx, fileSections.size());
// It gets funky. If the area is absolute, *actually*, we // It gets funky. If the area is absolute, *actually*, we
// must not add its base address, as the assembler will // must not add its base address, as the assembler will
// already have added it in `baseValue`. // already have added it in `baseValue`.
@@ -722,20 +716,22 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
if (nbBytes != 0) if (nbBytes != 0)
warning(where, lineNo, "Last 'T' line had no 'R' line (ignored)"); warning(where, lineNo, "Last 'T' line had no 'R' line (ignored)");
if (nbSections < expectedNbAreas) if (fileSections.size() < expectedNbAreas)
warning(where, lineNo, "Expected %" PRIu32 " 'A' lines, got only %zu", expectedNbAreas, nbSections); warning(where, lineNo, "Expected %" PRIu32 " 'A' lines, got only %zu", expectedNbAreas,
if (nbSymbols < expectedNbSymbols) fileSections.size());
warning(where, lineNo, "Expected %" PRIu32 " 'S' lines, got only %zu", expectedNbSymbols, nbSymbols); if (fileSymbols.size() < expectedNbSymbols)
warning(where, lineNo, "Expected %" PRIu32 " 'S' lines, got only %zu", expectedNbSymbols,
fileSymbols.size());
nbSectionsToAssign += nbSections; nbSectionsToAssign += fileSections.size();
for (size_t i = 0; i < nbSections; ++i) { for (struct FileSection &entry : fileSections) {
struct Section *section = fileSections[i].section; struct Section *section = entry.section;
// RAM sections can have a size, but don't get any data (they shouldn't have any) // RAM sections can have a size, but don't get any data (they shouldn't have any)
if (fileSections[i].writeIndex != section->size && fileSections[i].writeIndex != 0) if (entry.writeIndex != section->size && entry.writeIndex != 0)
fatal(where, lineNo, "\"%s\" was not fully written (%" PRIu16 " < %" PRIu16 ")", fatal(where, lineNo, "\"%s\" was not fully written (%" PRIu16 " < %" PRIu16 ")",
section->name->c_str(), fileSections[i].writeIndex, section->size); section->name->c_str(), entry.writeIndex, section->size);
// This must be done last, so that `->data` is not NULL anymore // This must be done last, so that `->data` is not NULL anymore
sect_AddSection(section); sect_AddSection(section);