Refactor to combine similar functions into one

This commit is contained in:
Rangi
2026-01-06 18:12:29 -05:00
committed by Rangi
parent a91d26192d
commit e738b90c69

View File

@@ -25,91 +25,71 @@ void sect_ForEach(void (*callback)(Section &)) {
} }
} }
static void checkAgainstFixedAddress(Section const &target, Section const &other, uint16_t org) { static void checkPieceCompat(Section &target, Section const &other, size_t delta) {
if (target.isAddressFixed) { assume(other.modifier != SECTION_UNION || delta == 0);
if (target.org != org) {
fatalTwoAt( if (other.isAddressFixed) {
target, uint16_t org = other.org - delta;
other,
"Section \"%s\" is defined with address $%04" PRIx16 if (target.isAddressFixed) {
", but also with address $%04" PRIx16, if (target.org != org) {
target.name.c_str(), fatalTwoAt(
target.org, target,
other.org other,
); "Section \"%s\" is defined with address $%04" PRIx16
", but also with address $%04" PRIx16,
target.name.c_str(),
target.org,
other.org
);
}
} else if (target.isAlignFixed) {
if ((org - target.alignOfs) & target.alignMask) {
fatalTwoAt(
target,
other,
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
"), but also with address $%04" PRIx16,
target.name.c_str(),
target.alignMask + 1,
target.alignOfs,
other.org
);
}
} }
} else if (target.isAlignFixed) {
if ((org - target.alignOfs) & target.alignMask) { target.isAddressFixed = true;
target.org = org;
} else if (other.isAlignFixed) {
uint32_t ofs = (other.alignOfs - delta) & other.alignMask;
if (target.isAddressFixed) {
if ((target.org - ofs) & other.alignMask) {
fatalTwoAt(
target,
other,
"Section \"%s\" is defined with address $%04" PRIx16
", but also with %d-byte alignment (offset %" PRIu16 ")",
target.name.c_str(),
target.org,
other.alignMask + 1,
other.alignOfs
);
}
} else if (target.isAlignFixed
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
fatalTwoAt( fatalTwoAt(
target, target,
other, other,
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16 "Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
"), but also with address $%04" PRIx16, "), but also with %d-byte alignment (offset %" PRIu16 ")",
target.name.c_str(), target.name.c_str(),
target.alignMask + 1, target.alignMask + 1,
target.alignOfs, target.alignOfs,
other.org
);
}
}
}
static bool checkAgainstFixedAlign(Section const &target, Section const &other, uint32_t ofs) {
if (target.isAddressFixed) {
if ((target.org - ofs) & other.alignMask) {
fatalTwoAt(
target,
other,
"Section \"%s\" is defined with address $%04" PRIx16
", but also with %d-byte alignment (offset %" PRIu16 ")",
target.name.c_str(),
target.org,
other.alignMask + 1, other.alignMask + 1,
other.alignOfs other.alignOfs
); );
} } else if (!target.isAlignFixed || other.alignMask > target.alignMask) {
return false;
} else if (target.isAlignFixed
&& (other.alignMask & target.alignOfs) != (target.alignMask & ofs)) {
fatalTwoAt(
target,
other,
"Section \"%s\" is defined with %d-byte alignment (offset %" PRIu16
"), but also with %d-byte alignment (offset %" PRIu16 ")",
target.name.c_str(),
target.alignMask + 1,
target.alignOfs,
other.alignMask + 1,
other.alignOfs
);
} else {
return !target.isAlignFixed || (other.alignMask > target.alignMask);
}
}
static void checkSectUnionCompat(Section &target, Section &other) {
if (other.isAddressFixed) {
checkAgainstFixedAddress(target, other, other.org);
target.isAddressFixed = true;
target.org = other.org;
} else if (other.isAlignFixed) {
if (checkAgainstFixedAlign(target, other, other.alignOfs)) {
target.isAlignFixed = true;
target.alignMask = other.alignMask;
target.alignOfs = other.alignOfs;
}
}
}
static void checkFragmentCompat(Section &target, Section &other) {
if (other.isAddressFixed) {
uint16_t org = other.org - target.size;
checkAgainstFixedAddress(target, other, org);
target.isAddressFixed = true;
target.org = org;
} else if (other.isAlignFixed) {
uint32_t ofs = (other.alignOfs - target.size) & other.alignMask;
if (checkAgainstFixedAlign(target, other, ofs)) {
target.isAlignFixed = true; target.isAlignFixed = true;
target.alignMask = other.alignMask; target.alignMask = other.alignMask;
target.alignOfs = ofs; target.alignOfs = ofs;
@@ -158,14 +138,14 @@ static void mergeSections(Section &target, std::unique_ptr<Section> &&other) {
switch (other->modifier) { switch (other->modifier) {
case SECTION_UNION: case SECTION_UNION:
checkSectUnionCompat(target, *other); checkPieceCompat(target, *other, 0);
if (other->size > target.size) { if (other->size > target.size) {
target.size = other->size; target.size = other->size;
} }
break; break;
case SECTION_FRAGMENT: case SECTION_FRAGMENT:
checkFragmentCompat(target, *other); checkPieceCompat(target, *other, target.size);
// Append `other` to `target` // Append `other` to `target`
other->offset = target.size; other->offset = target.size;
target.size += other->size; target.size += other->size;