mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 02:32:06 +00:00
Run clang-format on everything (#1332)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "link/patch.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <deque>
|
||||
#include <inttypes.h>
|
||||
@@ -8,17 +10,16 @@
|
||||
#include <string.h>
|
||||
#include <variant>
|
||||
|
||||
#include "link/object.hpp"
|
||||
#include "link/patch.hpp"
|
||||
#include "link/section.hpp"
|
||||
#include "link/symbol.hpp"
|
||||
|
||||
#include "error.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "linkdefs.hpp"
|
||||
#include "opmath.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
#include "link/object.hpp"
|
||||
#include "link/section.hpp"
|
||||
#include "link/symbol.hpp"
|
||||
|
||||
struct RPNStackEntry {
|
||||
int32_t value;
|
||||
bool errorFlag; // Whether the value is a placeholder inserted for error recovery
|
||||
@@ -26,17 +27,15 @@ struct RPNStackEntry {
|
||||
|
||||
std::deque<RPNStackEntry> rpnStack;
|
||||
|
||||
static void pushRPN(int32_t value, bool comesFromError)
|
||||
{
|
||||
rpnStack.push_front({ .value = value, .errorFlag = comesFromError });
|
||||
static void pushRPN(int32_t value, bool comesFromError) {
|
||||
rpnStack.push_front({.value = value, .errorFlag = comesFromError});
|
||||
}
|
||||
|
||||
// This flag tracks whether the RPN op that is currently being evaluated
|
||||
// has popped any values with the error flag set.
|
||||
static bool isError = false;
|
||||
|
||||
static int32_t popRPN(FileStackNode const *node, uint32_t lineNo)
|
||||
{
|
||||
static int32_t popRPN(FileStackNode const *node, uint32_t lineNo) {
|
||||
if (rpnStack.empty())
|
||||
fatal(node, lineNo, "Internal error, RPN stack empty");
|
||||
|
||||
@@ -49,17 +48,16 @@ static int32_t popRPN(FileStackNode const *node, uint32_t lineNo)
|
||||
|
||||
// RPN operators
|
||||
|
||||
static uint32_t getRPNByte(uint8_t const *&expression, int32_t &size,
|
||||
FileStackNode const *node, uint32_t lineNo)
|
||||
{
|
||||
static uint32_t getRPNByte(
|
||||
uint8_t const *&expression, int32_t &size, FileStackNode const *node, uint32_t lineNo
|
||||
) {
|
||||
if (!size--)
|
||||
fatal(node, lineNo, "Internal error, RPN expression overread");
|
||||
|
||||
return *expression++;
|
||||
}
|
||||
|
||||
static Symbol const *getSymbol(std::vector<Symbol> const &symbolList, uint32_t index)
|
||||
{
|
||||
static Symbol const *getSymbol(std::vector<Symbol> const &symbolList, uint32_t index) {
|
||||
assert(index != (uint32_t)-1); // PC needs to be handled specially, not here
|
||||
Symbol const &symbol = symbolList[index];
|
||||
|
||||
@@ -78,8 +76,7 @@ static Symbol const *getSymbol(std::vector<Symbol> const &symbolList, uint32_t i
|
||||
* @return isError Set if an error occurred during evaluation, and further
|
||||
* errors caused by the value should be suppressed.
|
||||
*/
|
||||
static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fileSymbols)
|
||||
{
|
||||
static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fileSymbols) {
|
||||
// Small shortcut to avoid a lot of repetition
|
||||
#define popRPN() popRPN(patch.src, patch.lineNo)
|
||||
|
||||
@@ -89,8 +86,8 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
rpnStack.clear();
|
||||
|
||||
while (size > 0) {
|
||||
enum RPNCommand command = (enum RPNCommand)getRPNByte(expression, size,
|
||||
patch.src, patch.lineNo);
|
||||
enum RPNCommand command =
|
||||
(enum RPNCommand)getRPNByte(expression, size, patch.src, patch.lineNo);
|
||||
int32_t value;
|
||||
|
||||
isError = false;
|
||||
@@ -218,22 +215,27 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
case RPN_BANK_SYM:
|
||||
value = 0;
|
||||
for (uint8_t shift = 0; shift < 32; shift += 8)
|
||||
value |= getRPNByte(expression, size,
|
||||
patch.src, patch.lineNo) << shift;
|
||||
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
|
||||
symbol = getSymbol(fileSymbols, value);
|
||||
|
||||
if (!symbol) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested BANK() of symbol \"%s\", which was not found",
|
||||
fileSymbols[value].name.c_str());
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Requested BANK() of symbol \"%s\", which was not found",
|
||||
fileSymbols[value].name.c_str()
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else if (Label const *label = std::get_if<Label>(&symbol->data); label) {
|
||||
value = label->section->bank;
|
||||
} else {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested BANK() of non-label symbol \"%s\"",
|
||||
fileSymbols[value].name.c_str());
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Requested BANK() of non-label symbol \"%s\"",
|
||||
fileSymbols[value].name.c_str()
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
}
|
||||
@@ -249,9 +251,12 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
sect = sect_GetSection(name);
|
||||
|
||||
if (!sect) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested BANK() of section \"%s\", which was not found",
|
||||
name);
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Requested BANK() of section \"%s\", which was not found",
|
||||
name
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else {
|
||||
@@ -261,8 +266,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
|
||||
case RPN_BANK_SELF:
|
||||
if (!patch.pcSection) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"PC has no bank outside a section");
|
||||
error(patch.src, patch.lineNo, "PC has no bank outside a section");
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else {
|
||||
@@ -279,9 +283,12 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
sect = sect_GetSection(name);
|
||||
|
||||
if (!sect) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested SIZEOF() of section \"%s\", which was not found",
|
||||
name);
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Requested SIZEOF() of section \"%s\", which was not found",
|
||||
name
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else {
|
||||
@@ -299,9 +306,12 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
assert(sect->offset == 0);
|
||||
|
||||
if (!sect) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested STARTOF() of section \"%s\", which was not found",
|
||||
name);
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Requested STARTOF() of section \"%s\", which was not found",
|
||||
name
|
||||
);
|
||||
isError = true;
|
||||
value = 1;
|
||||
} else {
|
||||
@@ -312,8 +322,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
case RPN_SIZEOF_SECTTYPE:
|
||||
value = getRPNByte(expression, size, patch.src, patch.lineNo);
|
||||
if (value < 0 || value >= SECTTYPE_INVALID) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested SIZEOF() an invalid section type");
|
||||
error(patch.src, patch.lineNo, "Requested SIZEOF() an invalid section type");
|
||||
isError = true;
|
||||
value = 0;
|
||||
} else {
|
||||
@@ -324,8 +333,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
case RPN_STARTOF_SECTTYPE:
|
||||
value = getRPNByte(expression, size, patch.src, patch.lineNo);
|
||||
if (value < 0 || value >= SECTTYPE_INVALID) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Requested STARTOF() an invalid section type");
|
||||
error(patch.src, patch.lineNo, "Requested STARTOF() an invalid section type");
|
||||
isError = true;
|
||||
value = 0;
|
||||
} else {
|
||||
@@ -335,11 +343,8 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
|
||||
case RPN_HRAM:
|
||||
value = popRPN();
|
||||
if (!isError && (value < 0
|
||||
|| (value > 0xFF && value < 0xFF00)
|
||||
|| value > 0xFFFF)) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Value %" PRId32 " is not in HRAM range", value);
|
||||
if (!isError && (value < 0 || (value > 0xFF && value < 0xFF00) || value > 0xFFFF)) {
|
||||
error(patch.src, patch.lineNo, "Value %" PRId32 " is not in HRAM range", value);
|
||||
isError = true;
|
||||
}
|
||||
value &= 0xFF;
|
||||
@@ -351,8 +356,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
// They can be easily checked with a bitmask
|
||||
if (value & ~0x38) {
|
||||
if (!isError)
|
||||
error(patch.src, patch.lineNo,
|
||||
"Value %" PRId32 " is not a RST vector", value);
|
||||
error(patch.src, patch.lineNo, "Value %" PRId32 " is not a RST vector", value);
|
||||
isError = true;
|
||||
}
|
||||
value |= 0xC7;
|
||||
@@ -361,20 +365,17 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
case RPN_CONST:
|
||||
value = 0;
|
||||
for (uint8_t shift = 0; shift < 32; shift += 8)
|
||||
value |= getRPNByte(expression, size,
|
||||
patch.src, patch.lineNo) << shift;
|
||||
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
|
||||
break;
|
||||
|
||||
case RPN_SYM:
|
||||
value = 0;
|
||||
for (uint8_t shift = 0; shift < 32; shift += 8)
|
||||
value |= getRPNByte(expression, size,
|
||||
patch.src, patch.lineNo) << shift;
|
||||
value |= getRPNByte(expression, size, patch.src, patch.lineNo) << shift;
|
||||
|
||||
if (value == -1) { // PC
|
||||
if (!patch.pcSection) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"PC has no value outside a section");
|
||||
error(patch.src, patch.lineNo, "PC has no value outside a section");
|
||||
value = 0;
|
||||
isError = true;
|
||||
} else {
|
||||
@@ -384,16 +385,23 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
symbol = getSymbol(fileSymbols, value);
|
||||
|
||||
if (!symbol) {
|
||||
error(patch.src, patch.lineNo,
|
||||
"Unknown symbol \"%s\"", fileSymbols[value].name.c_str());
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Unknown symbol \"%s\"",
|
||||
fileSymbols[value].name.c_str()
|
||||
);
|
||||
isError = true;
|
||||
} else {
|
||||
value = std::visit(Visitor{
|
||||
[](int32_t val) -> int32_t { return val; },
|
||||
[](Label label) -> int32_t {
|
||||
return label.section->org + label.offset;
|
||||
}
|
||||
}, symbol->data);
|
||||
value = std::visit(
|
||||
Visitor{
|
||||
[](int32_t val) -> int32_t { return val; },
|
||||
[](Label label) -> int32_t {
|
||||
return label.section->org + label.offset;
|
||||
},
|
||||
},
|
||||
symbol->data
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -403,8 +411,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
}
|
||||
|
||||
if (rpnStack.size() > 1)
|
||||
error(patch.src, patch.lineNo,
|
||||
"RPN stack has %zu entries on exit, not 1", rpnStack.size());
|
||||
error(patch.src, patch.lineNo, "RPN stack has %zu entries on exit, not 1", rpnStack.size());
|
||||
|
||||
isError = false;
|
||||
return popRPN();
|
||||
@@ -412,8 +419,7 @@ static int32_t computeRPNExpr(Patch const &patch, std::vector<Symbol> const &fil
|
||||
#undef popRPN
|
||||
}
|
||||
|
||||
void patch_CheckAssertions(std::deque<Assertion> &assertions)
|
||||
{
|
||||
void patch_CheckAssertions(std::deque<Assertion> &assertions) {
|
||||
verbosePrint("Checking assertions...\n");
|
||||
|
||||
for (Assertion &assert : assertions) {
|
||||
@@ -423,24 +429,37 @@ void patch_CheckAssertions(std::deque<Assertion> &assertions)
|
||||
if (!isError && !value) {
|
||||
switch (type) {
|
||||
case ASSERT_FATAL:
|
||||
fatal(assert.patch.src, assert.patch.lineNo, "%s",
|
||||
!assert.message.empty() ? assert.message.c_str()
|
||||
: "assert failure");
|
||||
fatal(
|
||||
assert.patch.src,
|
||||
assert.patch.lineNo,
|
||||
"%s",
|
||||
!assert.message.empty() ? assert.message.c_str() : "assert failure"
|
||||
);
|
||||
case ASSERT_ERROR:
|
||||
error(assert.patch.src, assert.patch.lineNo, "%s",
|
||||
!assert.message.empty() ? assert.message.c_str()
|
||||
: "assert failure");
|
||||
error(
|
||||
assert.patch.src,
|
||||
assert.patch.lineNo,
|
||||
"%s",
|
||||
!assert.message.empty() ? assert.message.c_str() : "assert failure"
|
||||
);
|
||||
break;
|
||||
case ASSERT_WARN:
|
||||
warning(assert.patch.src, assert.patch.lineNo, "%s",
|
||||
!assert.message.empty() ? assert.message.c_str()
|
||||
: "assert failure");
|
||||
warning(
|
||||
assert.patch.src,
|
||||
assert.patch.lineNo,
|
||||
"%s",
|
||||
!assert.message.empty() ? assert.message.c_str() : "assert failure"
|
||||
);
|
||||
break;
|
||||
}
|
||||
} else if (isError && type == ASSERT_FATAL) {
|
||||
fatal(assert.patch.src, assert.patch.lineNo,
|
||||
"Failed to evaluate assertion%s%s",
|
||||
!assert.message.empty() ? ": " : "", assert.message.c_str());
|
||||
fatal(
|
||||
assert.patch.src,
|
||||
assert.patch.lineNo,
|
||||
"Failed to evaluate assertion%s%s",
|
||||
!assert.message.empty() ? ": " : "",
|
||||
assert.message.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -450,8 +469,7 @@ void patch_CheckAssertions(std::deque<Assertion> &assertions)
|
||||
* @param section The section component to patch
|
||||
* @param dataSection The section to patch
|
||||
*/
|
||||
static void applyFilePatches(Section §ion, Section &dataSection)
|
||||
{
|
||||
static void applyFilePatches(Section §ion, Section &dataSection) {
|
||||
verbosePrint("Patching section \"%s\"...\n", section.name.c_str());
|
||||
for (Patch &patch : section.patches) {
|
||||
int32_t value = computeRPNExpr(patch, *section.fileSymbols);
|
||||
@@ -465,9 +483,12 @@ static void applyFilePatches(Section §ion, Section &dataSection)
|
||||
int16_t jumpOffset = value - address;
|
||||
|
||||
if (!isError && (jumpOffset < -128 || jumpOffset > 127))
|
||||
error(patch.src, patch.lineNo,
|
||||
"jr target out of reach (expected -129 < %" PRId16 " < 128)",
|
||||
jumpOffset);
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"jr target out of reach (expected -129 < %" PRId16 " < 128)",
|
||||
jumpOffset
|
||||
);
|
||||
dataSection.data[offset] = jumpOffset & 0xFF;
|
||||
} else {
|
||||
// Patch a certain number of bytes
|
||||
@@ -476,17 +497,20 @@ static void applyFilePatches(Section §ion, Section &dataSection)
|
||||
int32_t min;
|
||||
int32_t max;
|
||||
} const types[PATCHTYPE_INVALID] = {
|
||||
{ 1, -128, 255 }, // PATCHTYPE_BYTE
|
||||
{ 2, -32768, 65536 }, // PATCHTYPE_WORD
|
||||
{ 4, INT32_MIN, INT32_MAX }, // PATCHTYPE_LONG
|
||||
{1, -128, 255 }, // PATCHTYPE_BYTE
|
||||
{2, -32768, 65536 }, // PATCHTYPE_WORD
|
||||
{4, INT32_MIN, INT32_MAX}, // PATCHTYPE_LONG
|
||||
};
|
||||
|
||||
if (!isError && (value < types[patch.type].min
|
||||
|| value > types[patch.type].max))
|
||||
error(patch.src, patch.lineNo,
|
||||
"Value %" PRId32 "%s is not %u-bit",
|
||||
value, value < 0 ? " (maybe negative?)" : "",
|
||||
types[patch.type].size * 8U);
|
||||
if (!isError && (value < types[patch.type].min || value > types[patch.type].max))
|
||||
error(
|
||||
patch.src,
|
||||
patch.lineNo,
|
||||
"Value %" PRId32 "%s is not %u-bit",
|
||||
value,
|
||||
value < 0 ? " (maybe negative?)" : "",
|
||||
types[patch.type].size * 8U
|
||||
);
|
||||
for (uint8_t i = 0; i < types[patch.type].size; i++) {
|
||||
dataSection.data[offset + i] = value & 0xFF;
|
||||
value >>= 8;
|
||||
@@ -499,8 +523,7 @@ static void applyFilePatches(Section §ion, Section &dataSection)
|
||||
* Applies all of a section's patches, iterating over "components" of unionized sections
|
||||
* @param section The section to patch
|
||||
*/
|
||||
static void applyPatches(Section §ion)
|
||||
{
|
||||
static void applyPatches(Section §ion) {
|
||||
if (!sect_HasData(section.type))
|
||||
return;
|
||||
|
||||
@@ -508,7 +531,6 @@ static void applyPatches(Section §ion)
|
||||
applyFilePatches(*component, section);
|
||||
}
|
||||
|
||||
void patch_ApplyPatches()
|
||||
{
|
||||
void patch_ApplyPatches() {
|
||||
sect_ForEach(applyPatches);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user