SIZEOF("Section") and STARTOF("Section") can be known

Fixes #890
This commit is contained in:
Rangi
2021-06-20 16:10:27 -04:00
committed by Eldred Habert
parent 06b57aa1ce
commit a67f5d6e01
7 changed files with 87 additions and 17 deletions

View File

@@ -205,28 +205,40 @@ void rpn_SizeOfSection(struct Expression *expr, char const *sectionName)
{
rpn_Init(expr);
makeUnknown(expr, "Section \"%s\"'s size is not known", sectionName);
struct Section *section = sect_FindSectionByName(sectionName);
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
if (section && sect_IsSizeKnown(section)) {
expr->val = section->size;
} else {
makeUnknown(expr, "Section \"%s\"'s size is not known", sectionName);
expr->rpnPatchSize += nameLen + 1;
*ptr++ = RPN_SIZEOF_SECT;
memcpy(ptr, sectionName, nameLen);
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
expr->rpnPatchSize += nameLen + 1;
*ptr++ = RPN_SIZEOF_SECT;
memcpy(ptr, sectionName, nameLen);
}
}
void rpn_StartOfSection(struct Expression *expr, char const *sectionName)
{
rpn_Init(expr);
makeUnknown(expr, "Section \"%s\"'s start is not known", sectionName);
struct Section *section = sect_FindSectionByName(sectionName);
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
if (section && section->org != (uint32_t)-1) {
expr->val = section->org;
} else {
makeUnknown(expr, "Section \"%s\"'s start is not known", sectionName);
expr->rpnPatchSize += nameLen + 1;
*ptr++ = RPN_STARTOF_SECT;
memcpy(ptr, sectionName, nameLen);
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
expr->rpnPatchSize += nameLen + 1;
*ptr++ = RPN_STARTOF_SECT;
memcpy(ptr, sectionName, nameLen);
}
}
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)

View File

@@ -1016,3 +1016,22 @@ void sect_PopSection(void)
sectionStack = entry->next;
free(entry);
}
bool sect_IsSizeKnown(struct Section const NONNULL(sect))
{
// SECTION UNION and SECTION FRAGMENT can still grow
if (sect->modifier != SECTION_NORMAL)
return false;
// The current section (or current load section if within one) is still growing
if (sect == currentSection || sect == currentLoadSection)
return false;
// Any section on the stack is still growing
for (struct SectionStackEntry *stack = sectionStack; stack; stack = stack->next) {
if (stack->section && !strcmp(sect->name, stack->section->name))
return false;
}
return true;
}