Skip to content

Commit

Permalink
Make section size and related variables 16-bit
Browse files Browse the repository at this point in the history
This avoids type size inconsistencies which lead to platform-dependent
failures to enforce overflow checks.

Did I mention I *hate* integer promotion, and C(++) more largely? T_T
  • Loading branch information
ISSOtm committed Aug 23, 2024
1 parent 383433d commit eda8da0
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
12 changes: 6 additions & 6 deletions include/asm/section.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ struct Patch {

struct Section {
std::string name;
SectionType type;
SectionModifier modifier;
std::shared_ptr<FileStackNode> src; // Where the section was defined
uint32_t fileLine; // Line where the section was defined
uint32_t size;
uint32_t org;
uint32_t bank;
uint8_t align; // Exactly as specified in `ALIGN[]`
uint16_t size;
uint16_t alignOfs;
uint8_t align; // Exactly as specified in `ALIGN[]`
SectionType type;
SectionModifier modifier;
std::deque<Patch> patches;
std::vector<uint8_t> data;

Expand Down Expand Up @@ -73,8 +73,8 @@ void sect_SetLoadSection(
void sect_EndLoadSection();

Section *sect_GetSymbolSection();
uint32_t sect_GetSymbolOffset();
uint32_t sect_GetOutputOffset();
uint16_t sect_GetSymbolOffset();
uint16_t sect_GetOutputOffset();
uint32_t sect_GetAlignBytes(uint8_t alignment, uint16_t offset);
void sect_AlignPC(uint8_t alignment, uint16_t offset);

Expand Down
12 changes: 6 additions & 6 deletions src/asm/section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ std::stack<UnionStackEntry> currentUnionStack;
std::deque<SectionStackEntry> sectionStack;
std::deque<Section> sectionList;
std::unordered_map<std::string, size_t> sectionMap; // Indexes into `sectionList`
uint32_t curOffset; // Offset into the current section (see sect_GetSymbolOffset)
uint16_t curOffset; // Offset into the current section (see sect_GetSymbolOffset)
Section *currentSection = nullptr;
static Section *currentLoadSection = nullptr;
std::optional<std::string> currentLoadScope = std::nullopt;
int32_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)
int16_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)

// A quick check to see if we have an initialized section
[[nodiscard]] static bool requireSection() {
Expand Down Expand Up @@ -78,7 +78,7 @@ void sect_CheckSizes() {
for (Section const &sect : sectionList) {
if (uint32_t maxSize = sectionTypeInfo[sect.type].size; sect.size > maxSize)
error(
"Section '%s' grew too big (max size = 0x%" PRIX32 " bytes, reached 0x%" PRIX32
"Section '%s' grew too big (max size = 0x%" PRIX32 " bytes, reached 0x%" PRIX16
").\n",
sect.name.c_str(),
maxSize,
Expand Down Expand Up @@ -494,11 +494,11 @@ Section *sect_GetSymbolSection() {
}

// The offset into the section above
uint32_t sect_GetSymbolOffset() {
uint16_t sect_GetSymbolOffset() {
return curOffset;
}

uint32_t sect_GetOutputOffset() {
uint16_t sect_GetOutputOffset() {
return curOffset + loadOffset;
}

Expand Down Expand Up @@ -558,7 +558,7 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset) {
}

static void growSection(uint32_t growth) {
if (curOffset > UINT32_MAX - growth)
if (growth > UINT16_MAX || curOffset > UINT16_MAX - growth)
fatalerror("Section size would overflow internal counter\n");
curOffset += growth;
if (curOffset + loadOffset > currentSection->size)
Expand Down
4 changes: 2 additions & 2 deletions test/asm/section-unsigned-overflow.asm
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
section "overflow", rom0
rept 10
ds $4000_0000
ds $4000
endr

section "moar overflow", romx
rept 10
ds $4000_0000
ds $4000
endr

0 comments on commit eda8da0

Please sign in to comment.