mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use automatic allocation for section data
This commit is contained in:
@@ -44,7 +44,7 @@ struct Section {
|
|||||||
bool isAlignFixed;
|
bool isAlignFixed;
|
||||||
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`, or 0 if `type` does not have data
|
||||||
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;
|
||||||
|
|||||||
@@ -304,11 +304,9 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
section->alignOfs = tmp;
|
section->alignOfs = tmp;
|
||||||
|
|
||||||
if (sect_HasData(section->type)) {
|
if (sect_HasData(section->type)) {
|
||||||
section->data = new(std::nothrow) std::vector<uint8_t>(section->size);
|
|
||||||
if (!section->data)
|
|
||||||
err("%s: Unable to read \"%s\"'s data", fileName, section->name.c_str());
|
|
||||||
if (section->size) {
|
if (section->size) {
|
||||||
if (size_t nbRead = fread(&(*section->data)[0], 1, section->size, file);
|
section->data.resize(section->size);
|
||||||
|
if (size_t nbRead = fread(§ion->data[0], 1, section->size, file);
|
||||||
nbRead != section->size)
|
nbRead != section->size)
|
||||||
errx("%s: Cannot read \"%s\"'s data: %s", fileName, section->name.c_str(),
|
errx("%s: Cannot read \"%s\"'s data: %s", fileName, section->name.c_str(),
|
||||||
feof(file) ? "Unexpected end of file" : strerror(errno));
|
feof(file) ? "Unexpected end of file" : strerror(errno));
|
||||||
@@ -324,8 +322,6 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
for (uint32_t i = 0; i < nbPatches; i++)
|
for (uint32_t i = 0; i < nbPatches; i++)
|
||||||
readPatch(file, §ion->patches[i], fileName, section->name, i,
|
readPatch(file, §ion->patches[i], fileName, section->name, i,
|
||||||
fileNodes);
|
fileNodes);
|
||||||
} else {
|
|
||||||
section->data = NULL; // `mergeSections()` expects to be able to always read the ptr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,15 +542,10 @@ void obj_Setup(unsigned int nbFiles)
|
|||||||
|
|
||||||
static void freeSection(struct Section *section)
|
static void freeSection(struct Section *section)
|
||||||
{
|
{
|
||||||
do {
|
for (struct Section *next; section; section = next) {
|
||||||
struct Section *next = section->nextu;
|
next = section->nextu;
|
||||||
|
|
||||||
if (sect_HasData(section->type))
|
|
||||||
delete section->data;
|
|
||||||
delete section;
|
delete section;
|
||||||
|
};
|
||||||
section = next;
|
|
||||||
} while (section);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void obj_Cleanup(void)
|
void obj_Cleanup(void)
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ static void writeBank(std::deque<struct Section const *> *bankSections, uint16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Output the section itself
|
// Output the section itself
|
||||||
fwrite(&(*section->data)[0], 1, section->size, outputFile);
|
fwrite(§ion->data[0], 1, section->size, outputFile);
|
||||||
if (overlayFile) {
|
if (overlayFile) {
|
||||||
// Skip bytes even with pipes
|
// Skip bytes even with pipes
|
||||||
for (uint16_t i = 0; i < section->size; i++)
|
for (uint16_t i = 0; i < section->size; i++)
|
||||||
|
|||||||
@@ -466,7 +466,7 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio
|
|||||||
error(patch.src, patch.lineNo,
|
error(patch.src, patch.lineNo,
|
||||||
"jr target out of reach (expected -129 < %" PRId16 " < 128)",
|
"jr target out of reach (expected -129 < %" PRId16 " < 128)",
|
||||||
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
|
||||||
struct {
|
struct {
|
||||||
@@ -486,7 +486,7 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio
|
|||||||
value, value < 0 ? " (maybe negative?)" : "",
|
value, value < 0 ? " (maybe negative?)" : "",
|
||||||
types[patch.type].size * 8U);
|
types[patch.type].size * 8U);
|
||||||
for (uint8_t i = 0; i < types[patch.type].size; i++) {
|
for (uint8_t i = 0; i < types[patch.type].size; i++) {
|
||||||
(*dataSection->data)[offset + i] = value & 0xFF;
|
dataSection->data[offset + i] = value & 0xFF;
|
||||||
value >>= 8;
|
value >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,8 +337,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
curSection->type = SECTTYPE_INVALID; // This means "indeterminate"
|
curSection->type = SECTTYPE_INVALID; // This means "indeterminate"
|
||||||
}
|
}
|
||||||
curSection->isAlignFixed = false; // No such concept!
|
curSection->isAlignFixed = false; // No such concept!
|
||||||
// The array will be allocated if the section does contain data
|
|
||||||
curSection->data = NULL;
|
|
||||||
curSection->fileSymbols = &fileSymbols; // IDs are instead per-section
|
curSection->fileSymbols = &fileSymbols; // IDs are instead per-section
|
||||||
curSection->nextu = NULL;
|
curSection->nextu = NULL;
|
||||||
break;
|
break;
|
||||||
@@ -469,12 +467,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (addr != *writeIndex)
|
if (addr != *writeIndex)
|
||||||
fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")",
|
fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")",
|
||||||
addr, *writeIndex);
|
addr, *writeIndex);
|
||||||
if (!section->data) {
|
if (section->data.empty()) {
|
||||||
assert(section->size != 0);
|
assert(section->size != 0);
|
||||||
section->data = new(std::nothrow) std::vector<uint8_t>(section->size);
|
section->data.resize(section->size);
|
||||||
if (!section->data)
|
|
||||||
fatal(where, lineNo, "Failed to alloc data for \"%s\": %s",
|
|
||||||
section->name.c_str(), strerror(errno));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +632,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%u > %" PRIu16 ")",
|
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%u > %" PRIu16 ")",
|
||||||
section->name.c_str(), *writeIndex + (offset - writtenOfs), section->size);
|
section->name.c_str(), *writeIndex + (offset - writtenOfs), section->size);
|
||||||
// Copy all bytes up to those (plus the byte that we'll overwrite)
|
// Copy all bytes up to those (plus the byte that we'll overwrite)
|
||||||
memcpy(&(*section->data)[*writeIndex], &data[writtenOfs], offset - writtenOfs + 1);
|
memcpy(§ion->data[*writeIndex], &data[writtenOfs], offset - writtenOfs + 1);
|
||||||
*writeIndex += offset - writtenOfs + 1;
|
*writeIndex += offset - writtenOfs + 1;
|
||||||
writtenOfs = offset + 3; // Skip all three `baseValue` bytes, though
|
writtenOfs = offset + 3; // Skip all three `baseValue` bytes, though
|
||||||
}
|
}
|
||||||
@@ -685,7 +680,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (*writeIndex + (nbBytes - writtenOfs) > section->size)
|
if (*writeIndex + (nbBytes - writtenOfs) > section->size)
|
||||||
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%zu > %" PRIu16 ")",
|
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%zu > %" PRIu16 ")",
|
||||||
section->name.c_str(), *writeIndex + (nbBytes - writtenOfs), section->size);
|
section->name.c_str(), *writeIndex + (nbBytes - writtenOfs), section->size);
|
||||||
memcpy(&(*section->data)[*writeIndex], &data[writtenOfs], nbBytes - writtenOfs);
|
memcpy(§ion->data[*writeIndex], &data[writtenOfs], nbBytes - writtenOfs);
|
||||||
*writeIndex += nbBytes - writtenOfs;
|
*writeIndex += nbBytes - writtenOfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +714,6 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
fatal(where, lineNo, "\"%s\" was not fully written (%" PRIu16 " < %" PRIu16 ")",
|
fatal(where, lineNo, "\"%s\" was not fully written (%" PRIu16 " < %" PRIu16 ")",
|
||||||
section->name.c_str(), entry.writeIndex, section->size);
|
section->name.c_str(), entry.writeIndex, section->size);
|
||||||
|
|
||||||
// This must be done last, so that `->data` is not NULL anymore
|
|
||||||
sect_AddSection(section);
|
sect_AddSection(section);
|
||||||
|
|
||||||
if (section->modifier == SECTION_FRAGMENT) {
|
if (section->modifier == SECTION_FRAGMENT) {
|
||||||
|
|||||||
@@ -141,21 +141,12 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
|
|||||||
other->offset = target->size;
|
other->offset = target->size;
|
||||||
target->size += other->size;
|
target->size += other->size;
|
||||||
// Normally we'd check that `sect_HasData`, but SDCC areas may be `_INVALID` here
|
// Normally we'd check that `sect_HasData`, but SDCC areas may be `_INVALID` here
|
||||||
// Note that if either fragment has data (= a non-NULL `data` pointer), then it's
|
if (!other->data.empty()) {
|
||||||
// assumed that both fragments "have data", and thus should either have a non-NULL
|
target->data.insert(target->data.end(), RANGE(other->data));
|
||||||
// `data` pointer, or a size of 0.
|
|
||||||
if (other->data) {
|
|
||||||
if (target->data) {
|
|
||||||
target->data->insert(target->data->end(), RANGE(*other->data));
|
|
||||||
} else {
|
|
||||||
assert(target->size == other->size); // It has been increased just above
|
|
||||||
target->data = other->data;
|
|
||||||
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.empty()) {
|
||||||
assert(other->size == 0);
|
assert(other->size == 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user