mirror of
https://github.com/gbdev/rgbds.git
synced 2026-09-18 03:37:06 +00:00
Avoid allocating for our linkdef names (#2111)
This reverts a change introduced in fd78a9ae8, though it wasn't that commit's main point
so I'm feeling okay with undoing that.
This feels like an overkill change, using a static string is good enough for this
since we never modify this. I have considered using `string_view` instead, to have
the best of both worlds, but that's not NUL-terminated so our print functions
get a little grumpy.
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
#define RGBDS_LINKDEFS_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "helpers.hpp" // assume
|
||||
|
||||
@@ -99,7 +98,7 @@ static constexpr uint8_t FSTACKNODE_QUIET_BIT = 7;
|
||||
|
||||
// Non-`const` members may be patched in RGBLINK depending on CLI flags
|
||||
struct SectionTypeInfo {
|
||||
std::string const name;
|
||||
char const *name;
|
||||
uint16_t const startAddr;
|
||||
uint16_t size;
|
||||
uint32_t const firstBank;
|
||||
|
||||
+3
-5
@@ -309,7 +309,7 @@ static void mergeSections(
|
||||
sectError(
|
||||
"Section \"%s\" already exists but with type `%s`",
|
||||
sect.name.c_str(),
|
||||
sect.typeInfo().name.c_str()
|
||||
sect.typeInfo().name
|
||||
);
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ static Section *getSection(
|
||||
} else if (bank < typeInfo.firstBank || bank > typeInfo.lastBank) {
|
||||
error(
|
||||
"%s bank value $%04" PRIx32 " out of range ($%04" PRIx32 " to $%04" PRIx32 ")",
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
bank,
|
||||
typeInfo.firstBank,
|
||||
typeInfo.lastBank
|
||||
@@ -478,9 +478,7 @@ static Section *getSection(
|
||||
alignment = 0; // Ignore it if it's satisfied
|
||||
} else if (typeInfo.startAddr & alignMask) {
|
||||
error(
|
||||
"Section \"%s\"'s alignment cannot be attained in %s",
|
||||
name.c_str(),
|
||||
typeInfo.name.c_str()
|
||||
"Section \"%s\"'s alignment cannot be attained in %s", name.c_str(), typeInfo.name
|
||||
);
|
||||
alignment = 0; // Ignore it if it's unattainable
|
||||
org = 0;
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ static std::optional<size_t> getPlacement(Section const §ion, MemoryLocation
|
||||
|| location.bank >= memory[section.type].size() + typeInfo.firstBank) {
|
||||
fatal(
|
||||
"Invalid bank for %s section \"%s\": %" PRIu32,
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
section.name.c_str(),
|
||||
location.bank
|
||||
);
|
||||
|
||||
+10
-10
@@ -47,7 +47,7 @@ void layout_SetFloatingSectionType(SectionType type) {
|
||||
|
||||
void layout_SetSectionType(SectionType type) {
|
||||
if (SectionTypeInfo const &typeInfo = sectionTypeInfo[type]; typeInfo.isBanked()) {
|
||||
scriptError("A bank number must be specified for %s", typeInfo.name.c_str());
|
||||
scriptError("A bank number must be specified for %s", typeInfo.name);
|
||||
// Keep going with a default value for the bank index.
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ void layout_SetSectionType(SectionType type, uint32_t bank) {
|
||||
if (bank < typeInfo.firstBank) {
|
||||
scriptError(
|
||||
"%s bank %" PRIu32 " does not exist (the minimum is %" PRIu32 ")",
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
bank,
|
||||
typeInfo.firstBank
|
||||
);
|
||||
@@ -68,7 +68,7 @@ void layout_SetSectionType(SectionType type, uint32_t bank) {
|
||||
} else if (bank > typeInfo.lastBank) {
|
||||
scriptError(
|
||||
"%s bank %" PRIu32 " does not exist (the maximum is %" PRIu32 ")",
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
bank,
|
||||
typeInfo.lastBank
|
||||
);
|
||||
@@ -96,7 +96,7 @@ void layout_SetAddr(uint32_t addr) {
|
||||
scriptError(
|
||||
"Cannot set the current address to $%04" PRIx32 ": %s ends at $%04" PRIx16,
|
||||
addr,
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
typeInfo.endAddr()
|
||||
);
|
||||
pc = typeInfo.endAddr();
|
||||
@@ -242,7 +242,7 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
scriptError(
|
||||
"\"%s\" is specified to be a %s section, but it contains data",
|
||||
name.c_str(),
|
||||
typeInfo.name.c_str()
|
||||
typeInfo.name
|
||||
);
|
||||
} else if (sectTypeHasData(activeType) && section->data.empty() && section->size != 0) {
|
||||
// A section that lacks data can only be assigned to a type that requires data
|
||||
@@ -250,7 +250,7 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
scriptError(
|
||||
"\"%s\" is specified to be a %s section, but it does not contain data",
|
||||
name.c_str(),
|
||||
typeInfo.name.c_str()
|
||||
typeInfo.name
|
||||
);
|
||||
} else {
|
||||
// SDCC areas don't have a type assigned yet, so the linker script gives them one.
|
||||
@@ -262,8 +262,8 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
scriptError(
|
||||
"\"%s\" is specified to be a %s section, but it is already a %s section",
|
||||
name.c_str(),
|
||||
typeInfo.name.c_str(),
|
||||
section->typeInfo().name.c_str()
|
||||
typeInfo.name,
|
||||
section->typeInfo().name
|
||||
);
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
"The linker script places section \"%s\" in %s bank %" PRIu32
|
||||
", but it was already defined in bank %" PRIu32,
|
||||
name.c_str(),
|
||||
section->typeInfo().name.c_str(),
|
||||
section->typeInfo().name,
|
||||
bank,
|
||||
section->bank
|
||||
);
|
||||
@@ -321,7 +321,7 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
||||
", but then it would overflow %s by %" PRIu16 " byte%s",
|
||||
name.c_str(),
|
||||
org,
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
overflowSize,
|
||||
overflowSize == 1 ? "" : "s"
|
||||
);
|
||||
|
||||
+2
-2
@@ -461,7 +461,7 @@ static void writeMapBank(SortedSections const §List, SectionType type, uint3
|
||||
fprintf(
|
||||
mapFile,
|
||||
"\n%s bank #%" PRIu32 ":\n",
|
||||
sectionTypeInfo[type].name.c_str(),
|
||||
sectionTypeInfo[type].name,
|
||||
bank + sectionTypeInfo[type].firstBank
|
||||
);
|
||||
|
||||
@@ -524,7 +524,7 @@ static void writeMapSummary() {
|
||||
fprintf(
|
||||
mapFile,
|
||||
"\t%s: %" PRIu32 " byte%s used / %zu free",
|
||||
sectionTypeInfo[type].name.c_str(),
|
||||
sectionTypeInfo[type].name,
|
||||
usedTotal,
|
||||
usedTotal == 1 ? "" : "s",
|
||||
static_cast<size_t>(nbBanks) * sectionTypeInfo[type].size - usedTotal
|
||||
|
||||
@@ -865,7 +865,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
||||
"\"%s\" is implicitly defined as a %s section (being at address $%04" PRIx16
|
||||
"), but it has data! (Was a bad `__at()` value used?)",
|
||||
section->name.c_str(),
|
||||
section->typeInfo().name.c_str(),
|
||||
section->typeInfo().name,
|
||||
section->org
|
||||
);
|
||||
}
|
||||
@@ -875,7 +875,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
|
||||
"\"%s\" is implicitly defined as a %s section (being at address $%04" PRIx16
|
||||
"), but it doesn't have any data! (Was a bad `__at()` value used?)",
|
||||
section->name.c_str(),
|
||||
section->typeInfo().name.c_str(),
|
||||
section->typeInfo().name,
|
||||
section->org
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,8 +115,8 @@ static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
|
||||
*other,
|
||||
"Section \"%s\" is defined with type `%s`, but also with type `%s`",
|
||||
target.name.c_str(),
|
||||
target.typeInfo().name.c_str(),
|
||||
other->typeInfo().name.c_str()
|
||||
target.typeInfo().name,
|
||||
other->typeInfo().name
|
||||
);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ void sect_AddSection(std::unique_ptr<Section> &§ion) {
|
||||
fatal(
|
||||
"Section \"%s\" is of type `%s`, which cannot be `UNION`ized",
|
||||
section->name.c_str(),
|
||||
section->typeInfo().name.c_str()
|
||||
section->typeInfo().name
|
||||
);
|
||||
} else {
|
||||
sections.add(section->name, std::move(section));
|
||||
@@ -262,7 +262,7 @@ static void doSanityChecks(Section §ion) {
|
||||
error(
|
||||
"Section \"%s\" has type `%s`, which cannot be aligned to $%04x bytes",
|
||||
section.name.c_str(),
|
||||
typeInfo.name.c_str(),
|
||||
typeInfo.name,
|
||||
section.alignMask + 1
|
||||
);
|
||||
}
|
||||
|
||||
+8
-12
@@ -2,65 +2,61 @@
|
||||
|
||||
#include "linkdefs.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
// The default values are the most lax, as they are used as-is by RGBASM; only RGBLINK has the full
|
||||
// info, so RGBASM's job is only to catch unconditional errors earlier.
|
||||
// clang-format off: nested initializers
|
||||
SectionTypeInfo sectionTypeInfo[SECTTYPE_INVALID] = {
|
||||
{
|
||||
.name = "WRAM0"s,
|
||||
.name = "WRAM0",
|
||||
.startAddr = 0xC000,
|
||||
.size = 0x2000, // Patched to 0x1000 if !isWRAM0Mode
|
||||
.firstBank = 0,
|
||||
.lastBank = 0,
|
||||
},
|
||||
{
|
||||
.name = "VRAM"s,
|
||||
.name = "VRAM",
|
||||
.startAddr = 0x8000,
|
||||
.size = 0x2000,
|
||||
.firstBank = 0,
|
||||
.lastBank = 1, // Patched to 0 if isDmgMode
|
||||
},
|
||||
{
|
||||
.name = "ROMX"s,
|
||||
.name = "ROMX",
|
||||
.startAddr = 0x4000,
|
||||
.size = 0x4000,
|
||||
.firstBank = 1,
|
||||
.lastBank = 65535,
|
||||
},
|
||||
{
|
||||
.name = "ROM0"s,
|
||||
.name = "ROM0",
|
||||
.startAddr = 0x0000,
|
||||
.size = 0x8000, // Patched to 0x4000 if !is32kMode
|
||||
.firstBank = 0,
|
||||
.lastBank = 0,
|
||||
},
|
||||
{
|
||||
.name = "HRAM"s,
|
||||
.name = "HRAM",
|
||||
.startAddr = 0xFF80,
|
||||
.size = 0x007F,
|
||||
.firstBank = 0,
|
||||
.lastBank = 0,
|
||||
},
|
||||
{
|
||||
.name = "WRAMX"s,
|
||||
.name = "WRAMX",
|
||||
.startAddr = 0xD000,
|
||||
.size = 0x1000,
|
||||
.firstBank = 1,
|
||||
.lastBank = 7,
|
||||
},
|
||||
{
|
||||
.name = "SRAM"s,
|
||||
.name = "SRAM",
|
||||
.startAddr = 0xA000,
|
||||
.size = 0x2000,
|
||||
.firstBank = 0,
|
||||
.lastBank = 255,
|
||||
},
|
||||
{
|
||||
.name = "OAM"s,
|
||||
.name = "OAM",
|
||||
.startAddr = 0xFE00,
|
||||
.size = 0x00A0,
|
||||
.firstBank = 0,
|
||||
|
||||
Reference in New Issue
Block a user