mirror of
https://github.com/gbdev/rgbds.git
synced 2026-09-06 13:57:07 +00:00
More guards against invalid object file patch data
This commit is contained in:
+39
-16
@@ -291,7 +291,16 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
isError = true;
|
isError = true;
|
||||||
value = 1;
|
value = 1;
|
||||||
} else if (std::holds_alternative<Label>(symbol->data)) {
|
} else if (std::holds_alternative<Label>(symbol->data)) {
|
||||||
value = std::get<Label>(symbol->data).section->bank;
|
if (Label const &label = std::get<Label>(symbol->data); !label.section) {
|
||||||
|
errorAt(
|
||||||
|
patch,
|
||||||
|
"Requested `BANK()` of label `%s` outside of a section",
|
||||||
|
fileSymbols[symID].name.c_str()
|
||||||
|
);
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value = label.section->bank;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errorAt(
|
errorAt(
|
||||||
patch,
|
patch,
|
||||||
@@ -449,8 +458,16 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
|||||||
value = 0;
|
value = 0;
|
||||||
isError = true;
|
isError = true;
|
||||||
} else if (std::holds_alternative<Label>(symbol->data)) {
|
} else if (std::holds_alternative<Label>(symbol->data)) {
|
||||||
Label const &label = std::get<Label>(symbol->data);
|
if (Label const &label = std::get<Label>(symbol->data); !label.section) {
|
||||||
value = label.section->org + label.offset;
|
errorAt(
|
||||||
|
patch,
|
||||||
|
"Requested value of label `%s` outside of a section",
|
||||||
|
fileSymbols[symID].name.c_str()
|
||||||
|
);
|
||||||
|
value = 0;
|
||||||
|
} else {
|
||||||
|
value = label.section->org + label.offset;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = std::get<int32_t>(symbol->data);
|
value = std::get<int32_t>(symbol->data);
|
||||||
}
|
}
|
||||||
@@ -568,21 +585,27 @@ static void applyFilePatches(Section §ion, Section &dataSection) {
|
|||||||
dataSection.name.c_str(),
|
dataSection.name.c_str(),
|
||||||
dataSection.data.size()
|
dataSection.data.size()
|
||||||
);
|
);
|
||||||
} else if (patch.type == PATCHTYPE_JR) { // `jr` is quite unlike the others...
|
} else if (patch.type == PATCHTYPE_JR) {
|
||||||
// Offset is relative to the byte *after* the operand
|
if (!patch.pcSection) {
|
||||||
// PC as operand to `jr` is lower than reference PC by 2
|
errorAt(patch, "PC has no value outside of a section");
|
||||||
uint16_t address = patch.pcSection->org + patch.pcOffset + 2;
|
dataSection.data[offset] = 0;
|
||||||
int16_t jumpOffset = value - address;
|
isError = true;
|
||||||
|
} else {
|
||||||
|
// Offset is relative to the byte *after* the operand
|
||||||
|
// PC as operand to `jr` is lower than reference PC by 2
|
||||||
|
uint16_t address = patch.pcSection->org + patch.pcOffset + 2;
|
||||||
|
int16_t jumpOffset = value - address;
|
||||||
|
|
||||||
if (jumpOffset < -128 || jumpOffset > 127) {
|
if (jumpOffset < -128 || jumpOffset > 127) {
|
||||||
firstErrorAt(
|
firstErrorAt(
|
||||||
patch,
|
patch,
|
||||||
"`JR` target must be between -128 and 127 bytes away, not %" PRId16
|
"`JR` target must be between -128 and 127 bytes away, not %" PRId16
|
||||||
"; use `JP` instead",
|
"; use `JP` instead",
|
||||||
jumpOffset
|
jumpOffset
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
dataSection.data[offset] = jumpOffset & 0xFF;
|
||||||
}
|
}
|
||||||
dataSection.data[offset] = jumpOffset & 0xFF;
|
|
||||||
} else {
|
} else {
|
||||||
// Patch a certain number of bytes
|
// Patch a certain number of bytes
|
||||||
if (typeSize < sizeof(int)) {
|
if (typeSize < sizeof(int)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user