Prevent assertions outside sections from crashing

This commit is contained in:
ISSOtm
2020-03-29 12:18:24 +02:00
parent db1eb8fbcb
commit a3d8836671
8 changed files with 25 additions and 9 deletions

View File

@@ -22,6 +22,11 @@ struct Assertion {
// enum AssertionType type; The `patch`'s field is instead re-used // enum AssertionType type; The `patch`'s field is instead re-used
struct Section *section; struct Section *section;
char *message; char *message;
/*
* This would be redundant with `.section->fileSymbols`... but
* `section` is sometimes NULL!
*/
struct Symbol ** fileSymbols;
struct Assertion *next; struct Assertion *next;
}; };

View File

@@ -362,7 +362,7 @@ bool out_CreateAssert(enum AssertionType type, struct Expression const *expr,
static void writeassert(struct Assertion *assert, FILE *f) static void writeassert(struct Assertion *assert, FILE *f)
{ {
writepatch(assert->patch, f); writepatch(assert->patch, f);
fputlong(getsectid(assert->section), f); fputlong(assert->section ? getsectid(assert->section) : -1, f);
fputstring(assert->message, f); fputstring(assert->message, f);
} }

View File

@@ -356,7 +356,7 @@ static void readAssertion(FILE *file, struct Assertion *assert,
readPatch(file, &assert->patch, fileName, assertName, 0); readPatch(file, &assert->patch, fileName, assertName, 0);
tryReadlong(sectionID, file, "%s: Cannot read assertion's section ID: %s", tryReadlong(sectionID, file, "%s: Cannot read assertion's section ID: %s",
fileName); fileName);
assert->section = fileSections[sectionID]; assert->section = sectionID == -1 ? NULL : fileSections[sectionID];
tryReadstr(assert->message, file, "%s: Cannot read assertion's message: %s", tryReadstr(assert->message, file, "%s: Cannot read assertion's message: %s",
fileName); fileName);
} }
@@ -502,6 +502,7 @@ void obj_ReadFile(char const *fileName)
if (!assertion) if (!assertion)
err(1, "%s: Couldn't create new assertion", fileName); err(1, "%s: Couldn't create new assertion", fileName);
readAssertion(file, assertion, fileName, fileSections, i); readAssertion(file, assertion, fileName, fileSections, i);
assertion->fileSymbols = fileSymbols;
assertion->next = assertions; assertion->next = assertions;
assertions = assertion; assertions = assertion;
} }

View File

@@ -117,7 +117,7 @@ static uint32_t getRPNByte(uint8_t const **expression, int32_t *size,
return *(*expression)++; return *(*expression)++;
} }
static struct Symbol const *getSymbol(struct Symbol ** const symbolList, static struct Symbol const *getSymbol(struct Symbol const * const *symbolList,
uint32_t index, char const *fileName) uint32_t index, char const *fileName)
{ {
struct Symbol const *symbol = symbolList[index]; struct Symbol const *symbol = symbolList[index];
@@ -142,7 +142,8 @@ static struct Symbol const *getSymbol(struct Symbol ** const symbolList,
* @return The patch's value * @return The patch's value
*/ */
static int32_t computeRPNExpr(struct Patch const *patch, static int32_t computeRPNExpr(struct Patch const *patch,
struct Section const *section) struct Section const *section,
struct Symbol const * const *fileSymbols)
{ {
/* Small shortcut to avoid a lot of repetition */ /* Small shortcut to avoid a lot of repetition */
#define popRPN() popRPN(patch->fileName) #define popRPN() popRPN(patch->fileName)
@@ -256,7 +257,7 @@ static int32_t computeRPNExpr(struct Patch const *patch,
value |= getRPNByte(&expression, &size, value |= getRPNByte(&expression, &size,
patch->fileName) << shift; patch->fileName) << shift;
value = getSymbol(section->fileSymbols, value, value = getSymbol(fileSymbols, value,
patch->fileName)->section->bank; patch->fileName)->section->bank;
break; break;
@@ -312,8 +313,7 @@ static int32_t computeRPNExpr(struct Patch const *patch,
value |= getRPNByte(&expression, &size, value |= getRPNByte(&expression, &size,
patch->fileName) << shift; patch->fileName) << shift;
symbol = getSymbol(section->fileSymbols, value, symbol = getSymbol(fileSymbols, value, patch->fileName);
patch->fileName);
if (!strcmp(symbol->name, "@")) { if (!strcmp(symbol->name, "@")) {
value = section->org + patch->offset; value = section->org + patch->offset;
@@ -346,7 +346,9 @@ void patch_CheckAssertions(struct Assertion *assert)
uint8_t failures = 0; uint8_t failures = 0;
while (assert) { while (assert) {
if (!computeRPNExpr(&assert->patch, assert->section)) { if (!computeRPNExpr(&assert->patch, assert->section,
(struct Symbol const * const *)
assert->fileSymbols)) {
switch ((enum AssertionType)assert->patch.type) { switch ((enum AssertionType)assert->patch.type) {
case ASSERT_FATAL: case ASSERT_FATAL:
errx(1, "%s: %s", assert->patch.fileName, errx(1, "%s: %s", assert->patch.fileName,
@@ -393,7 +395,9 @@ static void applyFilePatches(struct Section *section)
verbosePrint("Patching section \"%s\"...\n", section->name); verbosePrint("Patching section \"%s\"...\n", section->name);
for (uint32_t patchID = 0; patchID < section->nbPatches; patchID++) { for (uint32_t patchID = 0; patchID < section->nbPatches; patchID++) {
struct Patch *patch = &section->patches[patchID]; struct Patch *patch = &section->patches[patchID];
int32_t value = computeRPNExpr(patch, section); int32_t value = computeRPNExpr(patch, section,
(struct Symbol const * const *)
section->fileSymbols);
/* `jr` is quite unlike the others... */ /* `jr` is quite unlike the others... */
if (patch->type == PATCHTYPE_JR) { if (patch->type == PATCHTYPE_JR) {

View File

@@ -0,0 +1,5 @@
assert Sym
SECTION "test", ROM0
db 69
Sym:

View File

View File

View File

@@ -0,0 +1 @@
E