mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use automatic allocation for patches
This commit is contained in:
@@ -21,12 +21,11 @@ struct Patch {
|
|||||||
struct FileStackNode const *src;
|
struct FileStackNode const *src;
|
||||||
uint32_t lineNo;
|
uint32_t lineNo;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
struct Section const *pcSection;
|
||||||
uint32_t pcSectionID;
|
uint32_t pcSectionID;
|
||||||
uint32_t pcOffset;
|
uint32_t pcOffset;
|
||||||
enum PatchType type;
|
enum PatchType type;
|
||||||
std::vector<uint8_t> rpnExpression;
|
std::vector<uint8_t> rpnExpression;
|
||||||
|
|
||||||
struct Section const *pcSection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Section {
|
struct Section {
|
||||||
@@ -46,7 +45,7 @@ struct Section {
|
|||||||
uint16_t alignMask;
|
uint16_t alignMask;
|
||||||
uint16_t alignOfs;
|
uint16_t alignOfs;
|
||||||
std::vector<uint8_t> *data; // Array of size `size`
|
std::vector<uint8_t> *data; // Array of size `size`
|
||||||
std::vector<struct Patch> *patches;
|
std::vector<struct Patch> patches;
|
||||||
// Extra info computed during linking
|
// Extra info computed during linking
|
||||||
std::vector<struct Symbol> *fileSymbols;
|
std::vector<struct Symbol> *fileSymbols;
|
||||||
std::vector<struct Symbol *> *symbols;
|
std::vector<struct Symbol *> *symbols;
|
||||||
|
|||||||
@@ -337,12 +337,9 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
"%s: Cannot read \"%s\"'s number of patches: %s", fileName,
|
"%s: Cannot read \"%s\"'s number of patches: %s", fileName,
|
||||||
section->name->c_str());
|
section->name->c_str());
|
||||||
|
|
||||||
section->patches = new(std::nothrow) std::vector<struct Patch>();
|
section->patches.resize(nbPatches);
|
||||||
if (!section->patches)
|
|
||||||
err("%s: Unable to read \"%s\"'s patches", fileName, section->name->c_str());
|
|
||||||
section->patches->resize(nbPatches);
|
|
||||||
for (uint32_t i = 0; i < nbPatches; i++)
|
for (uint32_t i = 0; i < nbPatches; i++)
|
||||||
readPatch(file, &(*section->patches)[i], fileName, section->name->c_str(),
|
readPatch(file, §ion->patches[i], fileName, section->name->c_str(),
|
||||||
i, fileNodes);
|
i, fileNodes);
|
||||||
} else {
|
} else {
|
||||||
section->data = NULL; // `mergeSections()` expects to be able to always read the ptr
|
section->data = NULL; // `mergeSections()` expects to be able to always read the ptr
|
||||||
@@ -492,7 +489,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
verbosePrint("Reading %" PRIu32 " sections...\n", nbSections);
|
verbosePrint("Reading %" PRIu32 " sections...\n", nbSections);
|
||||||
for (uint32_t i = 0; i < nbSections; i++) {
|
for (uint32_t i = 0; i < nbSections; i++) {
|
||||||
// Read section
|
// Read section
|
||||||
fileSections[i] = (struct Section *)malloc(sizeof(*fileSections[i]));
|
fileSections[i] = new(std::nothrow) struct Section();
|
||||||
if (!fileSections[i])
|
if (!fileSections[i])
|
||||||
err("%s: Failed to create new section", fileName);
|
err("%s: Failed to create new section", fileName);
|
||||||
|
|
||||||
@@ -510,7 +507,7 @@ void obj_ReadFile(char const *fileName, unsigned int fileID)
|
|||||||
// Give patches' PC section pointers to their sections
|
// Give patches' PC section pointers to their sections
|
||||||
for (uint32_t i = 0; i < nbSections; i++) {
|
for (uint32_t i = 0; i < nbSections; i++) {
|
||||||
if (sect_HasData(fileSections[i]->type)) {
|
if (sect_HasData(fileSections[i]->type)) {
|
||||||
for (struct Patch &patch : *fileSections[i]->patches)
|
for (struct Patch &patch : fileSections[i]->patches)
|
||||||
linkPatchToPCSect(&patch, fileSections);
|
linkPatchToPCSect(&patch, fileSections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,12 +570,10 @@ static void freeSection(struct Section *section)
|
|||||||
struct Section *next = section->nextu;
|
struct Section *next = section->nextu;
|
||||||
|
|
||||||
delete section->name;
|
delete section->name;
|
||||||
if (sect_HasData(section->type)) {
|
if (sect_HasData(section->type))
|
||||||
delete section->data;
|
delete section->data;
|
||||||
delete section->patches;
|
|
||||||
}
|
|
||||||
delete section->symbols;
|
delete section->symbols;
|
||||||
free(section);
|
delete section;
|
||||||
|
|
||||||
section = next;
|
section = next;
|
||||||
} while (section);
|
} while (section);
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ void patch_CheckAssertions(std::deque<struct Assertion> &assertions)
|
|||||||
static void applyFilePatches(struct Section *section, struct Section *dataSection)
|
static void applyFilePatches(struct Section *section, struct Section *dataSection)
|
||||||
{
|
{
|
||||||
verbosePrint("Patching section \"%s\"...\n", section->name->c_str());
|
verbosePrint("Patching section \"%s\"...\n", section->name->c_str());
|
||||||
for (struct Patch &patch : *section->patches) {
|
for (struct Patch &patch : section->patches) {
|
||||||
int32_t value = computeRPNExpr(&patch, *section->fileSymbols);
|
int32_t value = computeRPNExpr(&patch, *section->fileSymbols);
|
||||||
uint16_t offset = patch.offset + section->offset;
|
uint16_t offset = patch.offset + section->offset;
|
||||||
|
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (fileSections.size() == expectedNbAreas)
|
if (fileSections.size() == expectedNbAreas)
|
||||||
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32,
|
warning(where, lineNo, "Got more 'A' lines than the expected %" PRIu32,
|
||||||
expectedNbAreas);
|
expectedNbAreas);
|
||||||
struct Section *curSection = (struct Section *)malloc(sizeof(*curSection));
|
struct Section *curSection = new(std::nothrow) struct Section();
|
||||||
|
|
||||||
if (!curSection)
|
if (!curSection)
|
||||||
fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno));
|
fatal(where, lineNo, "Failed to alloc new area: %s", strerror(errno));
|
||||||
@@ -343,10 +343,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
curSection->isAlignFixed = false; // No such concept!
|
curSection->isAlignFixed = false; // No such concept!
|
||||||
// The array will be allocated if the section does contain data
|
// The array will be allocated if the section does contain data
|
||||||
curSection->data = NULL;
|
curSection->data = NULL;
|
||||||
curSection->patches = new(std::nothrow) std::vector<struct Patch>();
|
|
||||||
if (!curSection->patches)
|
|
||||||
fatal(where, lineNo, "Failed to alloc new area's patches: %s",
|
|
||||||
strerror(errno));
|
|
||||||
curSection->fileSymbols = &fileSymbols; // IDs are instead per-section
|
curSection->fileSymbols = &fileSymbols; // IDs are instead per-section
|
||||||
curSection->symbols = new(std::nothrow) std::vector<struct Symbol *>();
|
curSection->symbols = new(std::nothrow) std::vector<struct Symbol *>();
|
||||||
if (!curSection->symbols)
|
if (!curSection->symbols)
|
||||||
@@ -536,13 +532,13 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
warning(where, lineNo, "Unknown reloc flags 0x%x", flags & ~RELOC_ALL_FLAGS);
|
warning(where, lineNo, "Unknown reloc flags 0x%x", flags & ~RELOC_ALL_FLAGS);
|
||||||
|
|
||||||
// Turn this into a Patch
|
// Turn this into a Patch
|
||||||
struct Patch &patch = section->patches->emplace_back();
|
struct Patch &patch = section->patches.emplace_back();
|
||||||
|
|
||||||
patch.lineNo = lineNo;
|
patch.lineNo = lineNo;
|
||||||
patch.src = where;
|
patch.src = where;
|
||||||
patch.offset = offset - writtenOfs + *writeIndex;
|
patch.offset = offset - writtenOfs + *writeIndex;
|
||||||
if (section->patches->size() > 1) {
|
if (section->patches.size() > 1) {
|
||||||
uint32_t prevOffset = (*section->patches)[section->patches->size() - 2].offset;
|
uint32_t prevOffset = section->patches[section->patches.size() - 2].offset;
|
||||||
if (prevOffset>= patch.offset)
|
if (prevOffset>= patch.offset)
|
||||||
fatal(where, lineNo, "Relocs not sorted by offset are not supported (%" PRIu32 " >= %" PRIu32 ")",
|
fatal(where, lineNo, "Relocs not sorted by offset are not supported (%" PRIu32 " >= %" PRIu32 ")",
|
||||||
prevOffset, patch.offset);
|
prevOffset, patch.offset);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
|
|||||||
other->data = NULL; // Prevent a double `delete`
|
other->data = NULL; // Prevent a double `delete`
|
||||||
}
|
}
|
||||||
// Adjust patches' PC offsets
|
// Adjust patches' PC offsets
|
||||||
for (struct Patch &patch : *other->patches)
|
for (struct Patch &patch : other->patches)
|
||||||
patch.pcOffset += other->offset;
|
patch.pcOffset += other->offset;
|
||||||
} else if (target->data) {
|
} else if (target->data) {
|
||||||
assert(other->size == 0);
|
assert(other->size == 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user