Pass std::string references to section functions

This commit is contained in:
Rangi42
2024-03-18 11:35:55 -04:00
committed by Sylvie
parent 91164ac1b0
commit 7b11c528ef
3 changed files with 79 additions and 55 deletions

View File

@@ -56,10 +56,18 @@ extern Section *currentSection;
Section *sect_FindSectionByName(char const *name); Section *sect_FindSectionByName(char const *name);
void sect_NewSection( void sect_NewSection(
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
); );
void sect_SetLoadSection( void sect_SetLoadSection(
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
); );
void sect_EndLoadSection(); void sect_EndLoadSection();
@@ -84,8 +92,8 @@ void sect_RelBytes(uint32_t n, std::vector<Expression> &exprs);
void sect_RelWord(Expression &expr, uint32_t pcShift); void sect_RelWord(Expression &expr, uint32_t pcShift);
void sect_RelLong(Expression &expr, uint32_t pcShift); void sect_RelLong(Expression &expr, uint32_t pcShift);
void sect_PCRelByte(Expression &expr, uint32_t pcShift); void sect_PCRelByte(Expression &expr, uint32_t pcShift);
void sect_BinaryFile(char const *s, int32_t startPos); void sect_BinaryFile(std::string const &name, int32_t startPos);
void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length); void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t length);
void sect_EndSection(); void sect_EndSection();
void sect_PushSection(); void sect_PushSection();

View File

@@ -850,7 +850,7 @@ shift:
load: load:
POP_LOAD sectmod string COMMA sectiontype sectorg sectattrs { POP_LOAD sectmod string COMMA sectiontype sectorg sectattrs {
sect_SetLoadSection($3.c_str(), (SectionType)$5, $6, $7, $2); sect_SetLoadSection($3, (SectionType)$5, $6, $7, $2);
} }
| POP_ENDL { | POP_ENDL {
sect_EndLoadSection(); sect_EndLoadSection();
@@ -1123,17 +1123,17 @@ include:
incbin: incbin:
POP_INCBIN string { POP_INCBIN string {
sect_BinaryFile($2.c_str(), 0); sect_BinaryFile($2, 0);
if (failedOnMissingInclude) if (failedOnMissingInclude)
YYACCEPT; YYACCEPT;
} }
| POP_INCBIN string COMMA const { | POP_INCBIN string COMMA const {
sect_BinaryFile($2.c_str(), $4); sect_BinaryFile($2, $4);
if (failedOnMissingInclude) if (failedOnMissingInclude)
YYACCEPT; YYACCEPT;
} }
| POP_INCBIN string COMMA const COMMA const { | POP_INCBIN string COMMA const COMMA const {
sect_BinaryFileSlice($2.c_str(), $4, $6); sect_BinaryFileSlice($2, $4, $6);
if (failedOnMissingInclude) if (failedOnMissingInclude)
YYACCEPT; YYACCEPT;
} }
@@ -1630,7 +1630,7 @@ strfmt_va_args:
section: section:
POP_SECTION sectmod string COMMA sectiontype sectorg sectattrs { POP_SECTION sectmod string COMMA sectiontype sectorg sectattrs {
sect_NewSection($3.c_str(), (SectionType)$5, $6, $7, $2); sect_NewSection($3, (SectionType)$5, $6, $7, $2);
} }
; ;

View File

@@ -289,7 +289,7 @@ static void mergeSections(
// Create a new section, not yet in the list. // Create a new section, not yet in the list.
static Section *createSection( static Section *createSection(
char const *name, std::string const &name,
SectionType type, SectionType type,
uint32_t org, uint32_t org,
uint32_t bank, uint32_t bank,
@@ -321,7 +321,11 @@ static Section *createSection(
// Find a section by name and type. If it doesn't exist, create it. // Find a section by name and type. If it doesn't exist, create it.
static Section *getSection( static Section *getSection(
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
) { ) {
uint32_t bank = attrs.bank; uint32_t bank = attrs.bank;
uint8_t alignment = attrs.alignment; uint8_t alignment = attrs.alignment;
@@ -360,7 +364,7 @@ static Section *getSection(
error( error(
"Section \"%s\"'s fixed address $%04" PRIx32 " is outside of range [$%04" PRIx16 "Section \"%s\"'s fixed address $%04" PRIx32 " is outside of range [$%04" PRIx16
"; $%04" PRIx16 "]\n", "; $%04" PRIx16 "]\n",
name, name.c_str(),
org, org,
sectionTypeInfo[type].startAddr, sectionTypeInfo[type].startAddr,
endaddr(type) endaddr(type)
@@ -377,12 +381,12 @@ static Section *getSection(
if (org != (uint32_t)-1) { if (org != (uint32_t)-1) {
if ((org - alignOffset) & mask) if ((org - alignOffset) & mask)
error("Section \"%s\"'s fixed address doesn't match its alignment\n", name); error("Section \"%s\"'s fixed address doesn't match its alignment\n", name.c_str());
alignment = 0; // Ignore it if it's satisfied alignment = 0; // Ignore it if it's satisfied
} else if (sectionTypeInfo[type].startAddr & mask) { } else if (sectionTypeInfo[type].startAddr & mask) {
error( error(
"Section \"%s\"'s alignment cannot be attained in %s\n", "Section \"%s\"'s alignment cannot be attained in %s\n",
name, name.c_str(),
sectionTypeInfo[type].name.c_str() sectionTypeInfo[type].name.c_str()
); );
alignment = 0; // Ignore it if it's unattainable alignment = 0; // Ignore it if it's unattainable
@@ -397,7 +401,7 @@ static Section *getSection(
// Check if another section exists with the same name; merge if yes, otherwise create one // Check if another section exists with the same name; merge if yes, otherwise create one
Section *sect = sect_FindSectionByName(name); Section *sect = sect_FindSectionByName(name.c_str());
if (sect) { if (sect) {
mergeSections(*sect, type, org, bank, alignment, alignOffset, mod); mergeSections(*sect, type, org, bank, alignment, alignOffset, mod);
@@ -436,14 +440,18 @@ bool Section::isSizeKnown() const {
// Set the current section by name and type // Set the current section by name and type
void sect_NewSection( void sect_NewSection(
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
) { ) {
if (currentLoadSection) if (currentLoadSection)
fatalerror("Cannot change the section within a `LOAD` block\n"); fatalerror("Cannot change the section within a `LOAD` block\n");
for (SectionStackEntry &entry : sectionStack) { for (SectionStackEntry &entry : sectionStack) {
if (entry.section && entry.section->name == name) if (entry.section && entry.section->name == name)
fatalerror("Section '%s' is already on the stack\n", name); fatalerror("Section '%s' is already on the stack\n", name.c_str());
} }
Section *sect = getSection(name, type, org, attrs, mod); Section *sect = getSection(name, type, org, attrs, mod);
@@ -456,7 +464,11 @@ void sect_NewSection(
// Set the current section by name and type // Set the current section by name and type
void sect_SetLoadSection( void sect_SetLoadSection(
char const *name, SectionType type, uint32_t org, SectionSpec const &attrs, SectionModifier mod std::string const &name,
SectionType type,
uint32_t org,
SectionSpec const &attrs,
SectionModifier mod
) { ) {
// Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in // Important info: currently, UNION and LOAD cannot interact, since UNION is prohibited in
// "code" sections, whereas LOAD is restricted to them. // "code" sections, whereas LOAD is restricted to them.
@@ -814,7 +826,7 @@ void sect_PCRelByte(Expression &expr, uint32_t pcShift) {
} }
// Output a binary file // Output a binary file
void sect_BinaryFile(char const *s, int32_t startPos) { void sect_BinaryFile(std::string const &name, int32_t startPos) {
if (startPos < 0) { if (startPos < 0) {
error("Start position cannot be negative (%" PRId32 ")\n", startPos); error("Start position cannot be negative (%" PRId32 ")\n", startPos);
startPos = 0; startPos = 0;
@@ -822,58 +834,60 @@ void sect_BinaryFile(char const *s, int32_t startPos) {
if (!checkcodesection()) if (!checkcodesection())
return; return;
std::optional<std::string> fullPath = fstk_FindFile(s); std::optional<std::string> fullPath = fstk_FindFile(name.c_str());
FILE *f = fullPath ? fopen(fullPath->c_str(), "rb") : nullptr; FILE *file = fullPath ? fopen(fullPath->c_str(), "rb") : nullptr;
if (!f) { if (!file) {
if (generatedMissingIncludes) { if (generatedMissingIncludes) {
if (verbose) if (verbose)
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", s, strerror(errno)); printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
failedOnMissingInclude = true; failedOnMissingInclude = true;
return; return;
} }
error("Error opening INCBIN file '%s': %s\n", s, strerror(errno)); error("Error opening INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
return; return;
} }
int32_t fsize = -1; int32_t fsize = -1;
int byte; int byte;
if (fseek(f, 0, SEEK_END) != -1) { if (fseek(file, 0, SEEK_END) != -1) {
fsize = ftell(f); fsize = ftell(file);
if (startPos > fsize) { if (startPos > fsize) {
error("Specified start position is greater than length of file\n"); error("Specified start position is greater than length of file\n");
goto cleanup; goto cleanup;
} }
fseek(f, startPos, SEEK_SET); fseek(file, startPos, SEEK_SET);
if (!reserveSpace(fsize - startPos)) if (!reserveSpace(fsize - startPos))
goto cleanup; goto cleanup;
} else { } else {
if (errno != ESPIPE) if (errno != ESPIPE)
error("Error determining size of INCBIN file '%s': %s\n", s, strerror(errno)); error(
"Error determining size of INCBIN file '%s': %s\n", name.c_str(), strerror(errno)
);
// The file isn't seekable, so we'll just skip bytes // The file isn't seekable, so we'll just skip bytes
while (startPos--) while (startPos--)
(void)fgetc(f); (void)fgetc(file);
} }
while ((byte = fgetc(f)) != EOF) { while ((byte = fgetc(file)) != EOF) {
if (fsize == -1) if (fsize == -1)
growSection(1); growSection(1);
writebyte(byte); writebyte(byte);
} }
if (ferror(f)) if (ferror(file))
error("Error reading INCBIN file '%s': %s\n", s, strerror(errno)); error("Error reading INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
cleanup: cleanup:
fclose(f); fclose(file);
} }
void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length) { void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t length) {
if (start_pos < 0) { if (startPos < 0) {
error("Start position cannot be negative (%" PRId32 ")\n", start_pos); error("Start position cannot be negative (%" PRId32 ")\n", startPos);
start_pos = 0; startPos = 0;
} }
if (length < 0) { if (length < 0) {
@@ -888,63 +902,65 @@ void sect_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length) {
if (!reserveSpace(length)) if (!reserveSpace(length))
return; return;
std::optional<std::string> fullPath = fstk_FindFile(s); std::optional<std::string> fullPath = fstk_FindFile(name.c_str());
FILE *f = fullPath ? fopen(fullPath->c_str(), "rb") : nullptr; FILE *file = fullPath ? fopen(fullPath->c_str(), "rb") : nullptr;
if (!f) { if (!file) {
if (generatedMissingIncludes) { if (generatedMissingIncludes) {
if (verbose) if (verbose)
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", s, strerror(errno)); printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", name.c_str(), strerror(errno));
failedOnMissingInclude = true; failedOnMissingInclude = true;
} else { } else {
error("Error opening INCBIN file '%s': %s\n", s, strerror(errno)); error("Error opening INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
} }
return; return;
} }
int32_t fsize; int32_t fsize;
if (fseek(f, 0, SEEK_END) != -1) { if (fseek(file, 0, SEEK_END) != -1) {
fsize = ftell(f); fsize = ftell(file);
if (start_pos > fsize) { if (startPos > fsize) {
error("Specified start position is greater than length of file\n"); error("Specified start position is greater than length of file\n");
goto cleanup; goto cleanup;
} }
if ((start_pos + length) > fsize) { if ((startPos + length) > fsize) {
error( error(
"Specified range in INCBIN is out of bounds (%" PRIu32 " + %" PRIu32 " > %" PRIu32 "Specified range in INCBIN is out of bounds (%" PRIu32 " + %" PRIu32 " > %" PRIu32
")\n", ")\n",
start_pos, startPos,
length, length,
fsize fsize
); );
goto cleanup; goto cleanup;
} }
fseek(f, start_pos, SEEK_SET); fseek(file, startPos, SEEK_SET);
} else { } else {
if (errno != ESPIPE) if (errno != ESPIPE)
error("Error determining size of INCBIN file '%s': %s\n", s, strerror(errno)); error(
"Error determining size of INCBIN file '%s': %s\n", name.c_str(), strerror(errno)
);
// The file isn't seekable, so we'll just skip bytes // The file isn't seekable, so we'll just skip bytes
while (start_pos--) while (startPos--)
(void)fgetc(f); (void)fgetc(file);
} }
while (length--) { while (length--) {
int byte = fgetc(f); int byte = fgetc(file);
if (byte != EOF) { if (byte != EOF) {
writebyte(byte); writebyte(byte);
} else if (ferror(f)) { } else if (ferror(file)) {
error("Error reading INCBIN file '%s': %s\n", s, strerror(errno)); error("Error reading INCBIN file '%s': %s\n", name.c_str(), strerror(errno));
} else { } else {
error("Premature end of file (%" PRId32 " bytes left to read)\n", length + 1); error("Premature end of file (%" PRId32 " bytes left to read)\n", length + 1);
} }
} }
cleanup: cleanup:
fclose(f); fclose(file);
} }
// Section stack routines // Section stack routines