From eda8da01f4cbbe16564bb1d71a81cae7176a6bc8 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Fri, 23 Aug 2024 02:55:00 +0200 Subject: [PATCH] Make section size and related variables 16-bit 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 --- include/asm/section.hpp | 12 ++++++------ src/asm/section.cpp | 12 ++++++------ test/asm/section-unsigned-overflow.asm | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/asm/section.hpp b/include/asm/section.hpp index d6754fd41..3a61186ac 100644 --- a/include/asm/section.hpp +++ b/include/asm/section.hpp @@ -30,15 +30,15 @@ struct Patch { struct Section { std::string name; - SectionType type; - SectionModifier modifier; std::shared_ptr 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 patches; std::vector data; @@ -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); diff --git a/src/asm/section.cpp b/src/asm/section.cpp index 705738b88..c020ed696 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -43,11 +43,11 @@ std::stack currentUnionStack; std::deque sectionStack; std::deque
sectionList; std::unordered_map 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 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() { @@ -78,7 +78,7 @@ void sect_CheckSizes() { for (Section const § : 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, @@ -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; } @@ -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) diff --git a/test/asm/section-unsigned-overflow.asm b/test/asm/section-unsigned-overflow.asm index 0817389c4..2b19b2ef9 100644 --- a/test/asm/section-unsigned-overflow.asm +++ b/test/asm/section-unsigned-overflow.asm @@ -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