From 5075ac888706cb7280dc12ebbe1f97055f82c525 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sat, 24 Feb 2024 12:12:19 -0500 Subject: [PATCH] Use `std::vector` for RPN expressions --- include/link/section.hpp | 3 +- src/link/object.cpp | 21 ++++------- src/link/patch.cpp | 4 +-- src/link/sdas_obj.cpp | 76 +++++++++++++++------------------------- 4 files changed, 39 insertions(+), 65 deletions(-) diff --git a/include/link/section.hpp b/include/link/section.hpp index a8e29fae..41b7200a 100644 --- a/include/link/section.hpp +++ b/include/link/section.hpp @@ -23,8 +23,7 @@ struct Patch { uint32_t pcSectionID; uint32_t pcOffset; enum PatchType type; - uint32_t rpnSize; - uint8_t *rpnExpression; + std::vector rpnExpression; struct Section const *pcSection; }; diff --git a/src/link/object.cpp b/src/link/object.cpp index 1ba1815b..21a76bdd 100644 --- a/src/link/object.cpp +++ b/src/link/object.cpp @@ -248,7 +248,7 @@ static void readSymbol(FILE *file, struct Symbol *symbol, static void readPatch(FILE *file, struct Patch *patch, char const *fileName, char const *sectName, uint32_t i, struct FileStackNode fileNodes[]) { - uint32_t nodeID; + uint32_t nodeID, rpnSize; enum PatchType type; tryReadlong(nodeID, file, @@ -271,18 +271,15 @@ static void readPatch(FILE *file, struct Patch *patch, char const *fileName, cha "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s type: %s", fileName, sectName, i); patch->type = type; - tryReadlong(patch->rpnSize, file, + tryReadlong(rpnSize, file, "%s: Unable to read \"%s\"'s patch #%" PRIu32 "'s RPN size: %s", fileName, sectName, i); - patch->rpnExpression = (uint8_t *)malloc(sizeof(*patch->rpnExpression) * patch->rpnSize); - if (!patch->rpnExpression) - err("%s: Failed to alloc \"%s\"'s patch #%" PRIu32 "'s RPN expression", - fileName, sectName, i); - size_t nbElementsRead = fread(patch->rpnExpression, sizeof(*patch->rpnExpression), - patch->rpnSize, file); + patch->rpnExpression.resize(rpnSize); + size_t nbElementsRead = fread(&patch->rpnExpression[0], sizeof(patch->rpnExpression[0]), + rpnSize, file); - if (nbElementsRead != patch->rpnSize) + if (nbElementsRead != rpnSize) errx("%s: Cannot read \"%s\"'s patch #%" PRIu32 "'s RPN expression: %s", fileName, sectName, i, feof(file) ? "Unexpected end of file" : strerror(errno)); @@ -668,8 +665,6 @@ static void freeSection(struct Section *section) free(section->name); if (sect_HasData(section->type)) { free(section->data); - for (struct Patch &patch : *section->patches) - free(patch.rpnExpression); delete section->patches; } free(section->symbols); @@ -706,8 +701,6 @@ void obj_Cleanup(void) free(list.symbolList); } - for (struct Assertion &assert : assertions) { - free(assert.patch.rpnExpression); + for (struct Assertion &assert : assertions) free(assert.message); - } } diff --git a/src/link/patch.cpp b/src/link/patch.cpp index 257df655..6107fd60 100644 --- a/src/link/patch.cpp +++ b/src/link/patch.cpp @@ -83,8 +83,8 @@ static int32_t computeRPNExpr(struct Patch const *patch, // Small shortcut to avoid a lot of repetition #define popRPN() popRPN(patch->src, patch->lineNo) - uint8_t const *expression = patch->rpnExpression; - int32_t size = patch->rpnSize; + uint8_t const *expression = &patch->rpnExpression[0]; + int32_t size = (int32_t)patch->rpnExpression.size(); rpnStack.clear(); diff --git a/src/link/sdas_obj.cpp b/src/link/sdas_obj.cpp index 512c809a..ccd2352c 100644 --- a/src/link/sdas_obj.cpp +++ b/src/link/sdas_obj.cpp @@ -598,14 +598,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { for (uint8_t i = 0; i < nbBaseBytes; ++i) baseValue = baseValue | data[offset + i] << (8 * i); -// Extra size that must be reserved for additional operators -#define RPN_EXTRA_SIZE (5 + 1 + 5 + 1 + 5 + 1) // >> 8 & $FF, then + -#define allocPatch(size) do { \ - patch.rpnSize = (size); \ - patch.rpnExpression = (uint8_t *)malloc(patch.rpnSize + RPN_EXTRA_SIZE); \ - if (!patch.rpnExpression) \ - fatal(where, lineNo, "Failed to alloc RPN expression: %s", strerror(errno)); \ -} while (0) // Bit 4 specifies signedness, but I don't think that matters? // Generate a RPN expression from the info and flags if (flags & 1 << RELOC_ISSYM) { @@ -626,22 +618,22 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { if (idx == nbSymbols) fatal(where, lineNo, "\"%s\" is missing a reference to \"%s\"", sym->name, &sym->name[1]); - allocPatch(5); + patch.rpnExpression.resize(5); patch.rpnExpression[0] = RPN_BANK_SYM; patch.rpnExpression[1] = idx; patch.rpnExpression[2] = idx >> 8; patch.rpnExpression[3] = idx >> 16; patch.rpnExpression[4] = idx >> 24; } else if (sym->name[0] == 'l' && sym->name[1] == '_') { - allocPatch(1 + strlen(&sym->name[2]) + 1); + patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1); patch.rpnExpression[0] = RPN_SIZEOF_SECT; strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); } else if (sym->name[0] == 's' && sym->name[1] == '_') { - allocPatch(1 + strlen(&sym->name[2]) + 1); + patch.rpnExpression.resize(1 + strlen(&sym->name[2]) + 1); patch.rpnExpression[0] = RPN_STARTOF_SECT; strcpy((char *)&patch.rpnExpression[1], &sym->name[2]); } else { - allocPatch(5); + patch.rpnExpression.resize(5); patch.rpnExpression[0] = RPN_SYM; patch.rpnExpression[1] = idx; patch.rpnExpression[2] = idx >> 8; @@ -674,25 +666,18 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { // current size. if (other) baseValue += other->size; - allocPatch(1 + strlen(name) + 1); - patch.rpnSize = 1 + strlen(name) + 1; - patch.rpnExpression = (uint8_t *)malloc(patch.rpnSize + RPN_EXTRA_SIZE); - if (!patch.rpnExpression) - fatal(where, lineNo, "Failed to alloc RPN expression: %s", - strerror(errno)); + patch.rpnExpression.resize(1 + strlen(name) + 1); patch.rpnExpression[0] = RPN_STARTOF_SECT; // The cast is fine, it's just different signedness strcpy((char *)&patch.rpnExpression[1], name); } -#undef allocPatch - patch.rpnExpression[patch.rpnSize] = RPN_CONST; - patch.rpnExpression[patch.rpnSize + 1] = baseValue; - patch.rpnExpression[patch.rpnSize + 2] = baseValue >> 8; - patch.rpnExpression[patch.rpnSize + 3] = baseValue >> 16; - patch.rpnExpression[patch.rpnSize + 4] = baseValue >> 24; - patch.rpnExpression[patch.rpnSize + 5] = RPN_ADD; - patch.rpnSize += 5 + 1; + patch.rpnExpression.push_back(RPN_CONST); + patch.rpnExpression.push_back(baseValue); + patch.rpnExpression.push_back(baseValue >> 8); + patch.rpnExpression.push_back(baseValue >> 16); + patch.rpnExpression.push_back(baseValue >> 24); + patch.rpnExpression.push_back(RPN_ADD); if (patch.type == PATCHTYPE_BYTE) { // Despite the flag's name, as soon as it is set, 3 bytes @@ -713,30 +698,27 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file) { patch.type = PATCHTYPE_JR; // TODO: check the other flags? } else if (flags & 1 << RELOC_EXPR24 && flags & 1 << RELOC_BANKBYTE) { - patch.rpnExpression[patch.rpnSize] = RPN_CONST; - patch.rpnExpression[patch.rpnSize + 1] = 16; - patch.rpnExpression[patch.rpnSize + 2] = 16 >> 8; - patch.rpnExpression[patch.rpnSize + 3] = 16 >> 16; - patch.rpnExpression[patch.rpnSize + 4] = 16 >> 24; - patch.rpnExpression[patch.rpnSize + 5] = (flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR; - patch.rpnSize += 5 + 1; + patch.rpnExpression.push_back(RPN_CONST); + patch.rpnExpression.push_back(16); + patch.rpnExpression.push_back(16 >> 8); + patch.rpnExpression.push_back(16 >> 16); + patch.rpnExpression.push_back(16 >> 24); + patch.rpnExpression.push_back((flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR); } else { if (flags & 1 << RELOC_EXPR16 && flags & 1 << RELOC_WHICHBYTE) { - patch.rpnExpression[patch.rpnSize] = RPN_CONST; - patch.rpnExpression[patch.rpnSize + 1] = 8; - patch.rpnExpression[patch.rpnSize + 2] = 8 >> 8; - patch.rpnExpression[patch.rpnSize + 3] = 8 >> 16; - patch.rpnExpression[patch.rpnSize + 4] = 8 >> 24; - patch.rpnExpression[patch.rpnSize + 5] = (flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR; - patch.rpnSize += 5 + 1; + patch.rpnExpression.push_back(RPN_CONST); + patch.rpnExpression.push_back(8); + patch.rpnExpression.push_back(8 >> 8); + patch.rpnExpression.push_back(8 >> 16); + patch.rpnExpression.push_back(8 >> 24); + patch.rpnExpression.push_back((flags & 1 << RELOC_SIGNED) ? RPN_SHR : RPN_USHR); } - patch.rpnExpression[patch.rpnSize] = RPN_CONST; - patch.rpnExpression[patch.rpnSize + 1] = 0xFF; - patch.rpnExpression[patch.rpnSize + 2] = 0xFF >> 8; - patch.rpnExpression[patch.rpnSize + 3] = 0xFF >> 16; - patch.rpnExpression[patch.rpnSize + 4] = 0xFF >> 24; - patch.rpnExpression[patch.rpnSize + 5] = RPN_AND; - patch.rpnSize += 5 + 1; + patch.rpnExpression.push_back(RPN_CONST); + patch.rpnExpression.push_back(0xFF); + patch.rpnExpression.push_back(0xFF >> 8); + patch.rpnExpression.push_back(0xFF >> 16); + patch.rpnExpression.push_back(0xFF >> 24); + patch.rpnExpression.push_back(RPN_AND); } } else if (flags & 1 << RELOC_ISPCREL) { assert(patch.type == PATCHTYPE_WORD);