mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use automatic allocation for symbol names
This commit is contained in:
@@ -15,7 +15,7 @@ struct FileStackNode;
|
||||
|
||||
struct Symbol {
|
||||
// Info contained in the object files
|
||||
std::string *name;
|
||||
std::string name;
|
||||
enum ExportLevel type;
|
||||
char const *objFileName;
|
||||
struct FileStackNode const *src;
|
||||
|
||||
@@ -190,23 +190,27 @@ static void readFileStackNode(FILE *file, std::vector<struct FileStackNode> &fil
|
||||
static void readSymbol(FILE *file, struct Symbol *symbol, char const *fileName,
|
||||
std::vector<struct FileStackNode> const &fileNodes)
|
||||
{
|
||||
tryReadstring(symbol->name, file, "%s: Cannot read symbol name: %s", fileName);
|
||||
std::string *name;
|
||||
|
||||
tryReadstring(name, file, "%s: Cannot read symbol name: %s", fileName);
|
||||
symbol->name = *name;
|
||||
delete name;
|
||||
tryGetc(enum ExportLevel, symbol->type, file, "%s: Cannot read \"%s\"'s type: %s",
|
||||
fileName, symbol->name->c_str());
|
||||
fileName, symbol->name.c_str());
|
||||
// If the symbol is defined in this file, read its definition
|
||||
if (symbol->type != SYMTYPE_IMPORT) {
|
||||
symbol->objFileName = fileName;
|
||||
uint32_t nodeID;
|
||||
|
||||
tryReadlong(nodeID, file, "%s: Cannot read \"%s\"'s node ID: %s",
|
||||
fileName, symbol->name->c_str());
|
||||
fileName, symbol->name.c_str());
|
||||
symbol->src = &fileNodes[nodeID];
|
||||
tryReadlong(symbol->lineNo, file, "%s: Cannot read \"%s\"'s line number: %s",
|
||||
fileName, symbol->name->c_str());
|
||||
fileName, symbol->name.c_str());
|
||||
tryReadlong(symbol->sectionID, file, "%s: Cannot read \"%s\"'s section ID: %s",
|
||||
fileName, symbol->name->c_str());
|
||||
fileName, symbol->name.c_str());
|
||||
tryReadlong(symbol->offset, file, "%s: Cannot read \"%s\"'s value: %s",
|
||||
fileName, symbol->name->c_str());
|
||||
fileName, symbol->name.c_str());
|
||||
} else {
|
||||
symbol->sectionID = -1;
|
||||
}
|
||||
@@ -584,11 +588,6 @@ void obj_Cleanup(void)
|
||||
sect_ForEach(freeSection);
|
||||
sect_CleanupSections();
|
||||
|
||||
for (std::vector<struct Symbol> &fileSymbols : symbolLists) {
|
||||
for (struct Symbol &symbol : fileSymbols)
|
||||
delete symbol.name;
|
||||
}
|
||||
|
||||
for (struct Assertion &assert : assertions)
|
||||
delete assert.message;
|
||||
}
|
||||
|
||||
@@ -293,19 +293,19 @@ static int compareSymbols(struct SortedSymbol const &sym1, struct SortedSymbol c
|
||||
if (sym1.addr != sym2.addr)
|
||||
return sym1.addr < sym2.addr ? -1 : 1;
|
||||
|
||||
std::string const *sym1_name = sym1.sym->name;
|
||||
std::string const *sym2_name = sym2.sym->name;
|
||||
bool sym1_local = sym1_name->find(".") != std::string::npos;
|
||||
bool sym2_local = sym2_name->find(".") != std::string::npos;
|
||||
std::string const &sym1_name = sym1.sym->name;
|
||||
std::string const &sym2_name = sym2.sym->name;
|
||||
bool sym1_local = sym1_name.find(".") != std::string::npos;
|
||||
bool sym2_local = sym2_name.find(".") != std::string::npos;
|
||||
|
||||
if (sym1_local != sym2_local) {
|
||||
size_t sym1_len = sym1_name->length();
|
||||
size_t sym2_len = sym2_name->length();
|
||||
size_t sym1_len = sym1_name.length();
|
||||
size_t sym2_len = sym2_name.length();
|
||||
|
||||
// Sort parent labels before their child local labels
|
||||
if (sym2_name->starts_with(*sym1_name) && (*sym2_name)[sym1_len] == '.')
|
||||
if (sym2_name.starts_with(sym1_name) && sym2_name[sym1_len] == '.')
|
||||
return -1;
|
||||
if (sym1_name->starts_with(*sym2_name) && (*sym1_name)[sym2_len] == '.')
|
||||
if (sym1_name.starts_with(sym2_name) && sym1_name[sym2_len] == '.')
|
||||
return 1;
|
||||
// Sort local labels before unrelated global labels
|
||||
return sym1_local ? -1 : 1;
|
||||
@@ -348,7 +348,7 @@ static void writeSymBank(struct SortedSections const &bankSections,
|
||||
forEachSortedSection(sect, {
|
||||
for (struct Symbol const *sym : sect->symbols) {
|
||||
// Don't output symbols that begin with an illegal character
|
||||
if (!sym->name->empty() && canStartSymName((*sym->name)[0]))
|
||||
if (!sym->name.empty() && canStartSymName(sym->name[0]))
|
||||
symList.push_back({ .sym = sym, .addr = (uint16_t)(sym->offset + sect->org) });
|
||||
}
|
||||
});
|
||||
@@ -361,7 +361,7 @@ static void writeSymBank(struct SortedSections const &bankSections,
|
||||
|
||||
for (struct SortedSymbol &sym : symList) {
|
||||
fprintf(symFile, "%02" PRIx32 ":%04" PRIx16 " ", symBank, sym.addr);
|
||||
printSymName(sym.sym->name->c_str());
|
||||
printSymName(sym.sym->name.c_str());
|
||||
putc('\n', symFile);
|
||||
}
|
||||
}
|
||||
@@ -419,7 +419,7 @@ static void writeMapBank(struct SortedSections const §List, enum SectionType
|
||||
for (struct Symbol *sym : sect->symbols)
|
||||
// Space matches "\tSECTION: $xxxx ..."
|
||||
fprintf(mapFile, "\t $%04" PRIx32 " = %s\n",
|
||||
sym->offset + org, sym->name->c_str());
|
||||
sym->offset + org, sym->name.c_str());
|
||||
|
||||
if (sect->nextu) {
|
||||
// Announce the following "piece"
|
||||
|
||||
@@ -63,7 +63,7 @@ static struct Symbol const *getSymbol(std::vector<struct Symbol> const &symbolLi
|
||||
|
||||
// If the symbol is defined elsewhere...
|
||||
if (symbol.type == SYMTYPE_IMPORT)
|
||||
return sym_GetSymbol(*symbol.name);
|
||||
return sym_GetSymbol(symbol.name);
|
||||
|
||||
return &symbol;
|
||||
}
|
||||
@@ -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->c_str());
|
||||
fileSymbols[value].name.c_str());
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else if (!symbol->section) {
|
||||
error(patch->src, patch->lineNo,
|
||||
"Requested BANK() of non-label symbol \"%s\"",
|
||||
fileSymbols[value].name->c_str());
|
||||
fileSymbols[value].name.c_str());
|
||||
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->c_str());
|
||||
"Unknown symbol \"%s\"", fileSymbols[value].name.c_str());
|
||||
isError = true;
|
||||
} else {
|
||||
value = symbol->value;
|
||||
|
||||
@@ -359,9 +359,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
||||
symbol.section = !fileSections.empty() ? fileSections.back().section : NULL;
|
||||
|
||||
getToken(line, "'S' line is too short");
|
||||
symbol.name = new(std::nothrow) std::string(token);
|
||||
if (!symbol.name)
|
||||
fatal(where, lineNo, "Failed to alloc symbol name: %s", strerror(errno));
|
||||
symbol.name = token;
|
||||
|
||||
getToken(NULL, "'S' line is too short");
|
||||
// It might be an `offset`, but both types are the same so type punning is fine
|
||||
@@ -381,7 +379,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
||||
} else {
|
||||
// All symbols are exported
|
||||
symbol.type = SYMTYPE_EXPORT;
|
||||
struct Symbol const *other = sym_GetSymbol(*symbol.name);
|
||||
struct Symbol const *other = sym_GetSymbol(symbol.name);
|
||||
|
||||
if (other) {
|
||||
// The same symbol can only be defined twice if neither
|
||||
@@ -392,7 +390,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
||||
} else if (other->value != symbol.value) {
|
||||
error(where, lineNo,
|
||||
"Definition of \"%s\" conflicts with definition in %s (%" PRId32 " != %" PRId32 ")",
|
||||
symbol.name->c_str(), other->objFileName, symbol.value, other->value);
|
||||
symbol.name.c_str(), other->objFileName, symbol.value, other->value);
|
||||
}
|
||||
} else {
|
||||
// Add a new definition
|
||||
@@ -560,30 +558,30 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
||||
// 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->starts_with("b_")) {
|
||||
if (sym.name.starts_with("b_")) {
|
||||
// Look for the symbol being referenced, and use its index instead
|
||||
for (idx = 0; idx < fileSymbols.size(); ++idx) {
|
||||
if (sym.name->ends_with(*fileSymbols[idx].name) &&
|
||||
1 + sym.name->length() == fileSymbols[idx].name->length())
|
||||
if (sym.name.ends_with(fileSymbols[idx].name) &&
|
||||
1 + sym.name.length() == fileSymbols[idx].name.length())
|
||||
break;
|
||||
}
|
||||
if (idx == fileSymbols.size())
|
||||
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[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->starts_with("l_")) {
|
||||
patch.rpnExpression.resize(1 + sym.name->length() - 2 + 1);
|
||||
} else if (sym.name.starts_with("l_")) {
|
||||
patch.rpnExpression.resize(1 + sym.name.length() - 2 + 1);
|
||||
patch.rpnExpression[0] = RPN_SIZEOF_SECT;
|
||||
memcpy((char *)&patch.rpnExpression[1], &sym.name->c_str()[2], sym.name->length() - 2 + 1);
|
||||
} else if (sym.name->starts_with("s_")) {
|
||||
patch.rpnExpression.resize(1 + sym.name->length() - 2 + 1);
|
||||
memcpy((char *)&patch.rpnExpression[1], &sym.name.c_str()[2], sym.name.length() - 2 + 1);
|
||||
} else if (sym.name.starts_with("s_")) {
|
||||
patch.rpnExpression.resize(1 + sym.name.length() - 2 + 1);
|
||||
patch.rpnExpression[0] = RPN_STARTOF_SECT;
|
||||
memcpy((char *)&patch.rpnExpression[1], &sym.name->c_str()[2], sym.name->length() - 2 + 1);
|
||||
memcpy((char *)&patch.rpnExpression[1], &sym.name.c_str()[2], sym.name.length() - 2 + 1);
|
||||
} else {
|
||||
patch.rpnExpression.resize(5);
|
||||
patch.rpnExpression[0] = RPN_SYM;
|
||||
|
||||
@@ -16,8 +16,8 @@ std::map<std::string, struct Symbol *> symbols;
|
||||
void sym_AddSymbol(struct Symbol *symbol)
|
||||
{
|
||||
// Check if the symbol already exists
|
||||
if (struct Symbol *other = sym_GetSymbol(*symbol->name); other) {
|
||||
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name->c_str(),
|
||||
if (struct Symbol *other = sym_GetSymbol(symbol->name); other) {
|
||||
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name.c_str(),
|
||||
symbol->objFileName);
|
||||
dumpFileStack(symbol->src);
|
||||
fprintf(stderr, "(%" PRIu32 ") and in %s from ",
|
||||
@@ -28,7 +28,7 @@ void sym_AddSymbol(struct Symbol *symbol)
|
||||
}
|
||||
|
||||
// If not, add it
|
||||
symbols[*symbol->name] = symbol;
|
||||
symbols[symbol->name] = symbol;
|
||||
}
|
||||
|
||||
struct Symbol *sym_GetSymbol(std::string const &name)
|
||||
|
||||
Reference in New Issue
Block a user