From 92ed6ece53d78c63bfb7e791cf17da164903433e Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 20 Aug 2025 09:15:26 -0400 Subject: [PATCH] Support 32-bit addresses ("XL4") as of SDCC 4.4.0 --- src/link/sdas_obj.cpp | 29 +++++++++++++++++------------ test/link/sdcc/good/b.rel | 18 +++++++++--------- test/link/sdcc/good/c.rel | 12 ++++++------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/link/sdas_obj.cpp b/src/link/sdas_obj.cpp index 91a344ea..1c434317 100644 --- a/src/link/sdas_obj.cpp +++ b/src/link/sdas_obj.cpp @@ -181,9 +181,9 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f } while (0) int lineType = nextLine(line, where, file); - NumberType numberType; // The first letter (thus, the line type) identifies the integer type + NumberType numberType; switch (lineType) { case EOF: fatalAt(where, "SDCC object only contains comments and empty lines"); @@ -213,10 +213,15 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f fatalAt(where, "Unknown endianness type '%c'", line[0]); } - // TODO: support 32-bit addresses ("XL4") as of SDCC 4.4.0 - static constexpr uint8_t ADDR_SIZE = 3; - - if (line[1] != '0' + ADDR_SIZE) { + uint8_t addrSize; + switch (line[1]) { + case '3': + addrSize = 3; + break; + case '4': + addrSize = 4; + break; + default: fatalAt(where, "Unknown or unsupported address size '%c'", line[1]); } @@ -264,7 +269,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f switch (lineType) { case 'M': // Module name case 'O': // Assembler flags - // Ignored + // TODO: check the calling convention metadata as of SDCC 4.5.0 break; case 'A': { @@ -462,7 +467,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f data.push_back(parseByte(where, token, numberType)); } - if (data.size() < ADDR_SIZE) { + if (data.size() < addrSize) { fatalAt(where, "'T' line is too short"); } // Importantly, now we know that there is "pending data" in `data` @@ -495,7 +500,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f assume(!fileSections.empty()); // There should be at least one, from the above check Section *section = fileSections[areaIdx].section.get(); uint16_t *writeIndex = &fileSections[areaIdx].writeIndex; - uint8_t writtenOfs = ADDR_SIZE; // Bytes before this have been written to `->data` + uint8_t writtenOfs = addrSize; // Bytes before this have been written to `->data` uint16_t addr = data[0] | data[1] << 8; if (section->isAddressFixed) { @@ -513,7 +518,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f } // Lines are emitted that violate this check but contain no "payload"; // ignore those. "Empty" lines shouldn't trigger allocation, either. - if (data.size() != ADDR_SIZE) { + if (data.size() != addrSize) { if (addr != *writeIndex) { fatalAt( where, @@ -554,12 +559,12 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f getToken(nullptr, "Incomplete relocation"); uint8_t offset = parseByte(where, token, numberType); - if (offset < ADDR_SIZE) { + if (offset < addrSize) { fatalAt( where, "Relocation index cannot point to header (%" PRIu16 " < %u)", offset, - ADDR_SIZE + addrSize ); } if (offset >= data.size()) { @@ -607,7 +612,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f patch.pcOffset = patch.offset - 1; // For `jr`s patch.type = (flags & 1 << RELOC_SIZE) ? PATCHTYPE_BYTE : PATCHTYPE_WORD; - uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? ADDR_SIZE : 2; + uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? addrSize : 2; uint32_t baseValue = 0; assume(offset < data.size()); diff --git a/test/link/sdcc/good/b.rel b/test/link/sdcc/good/b.rel index 0c1b3139..0bb13e61 100644 --- a/test/link/sdcc/good/b.rel +++ b/test/link/sdcc/good/b.rel @@ -1,11 +1,11 @@ -XL3 +XL4 H 9 areas 3 global symbols M b -O -msm83 -S .__.ABS. Def000000 +O -msm83 sdcccall(1) +S .__.ABS. Def00000000 A _CODE size 7 flags 0 addr 0 -S _sm83 Def000005 -S _function0 Def000000 +S _sm83 Def00000005 +S _function0 Def00000000 A _DATA size 0 flags 0 addr 0 A _INITIALIZED size 0 flags 0 addr 0 A _DABS size 0 flags 8 addr 0 @@ -14,11 +14,11 @@ A _GSINIT size 0 flags 0 addr 0 A _GSFINAL size 0 flags 0 addr 0 A _INITIALIZER size 0 flags 0 addr 0 A _CABS size 0 flags 8 addr 0 -T 00 00 00 +T 00 00 00 00 R 00 00 00 00 -T 00 00 00 4B 42 CB C1 C9 +T 00 00 00 00 4B 42 CB C1 C9 R 00 00 00 00 -T 05 00 00 +T 05 00 00 00 R 00 00 00 00 -T 05 00 00 01 00 +T 05 00 00 00 01 00 R 00 00 00 00 diff --git a/test/link/sdcc/good/c.rel b/test/link/sdcc/good/c.rel index ce7165da..6bd1e755 100644 --- a/test/link/sdcc/good/c.rel +++ b/test/link/sdcc/good/c.rel @@ -1,10 +1,10 @@ -XL3 +XL4 H 9 areas 2 global symbols M c -O -msm83 -S .__.ABS. Def000000 +O -msm83 sdcccall(1) +S .__.ABS. Def00000000 A _CODE size 5 flags 0 addr 0 -S _function1 Def000000 +S _function1 Def00000000 A _DATA size 0 flags 0 addr 0 A _INITIALIZED size 0 flags 0 addr 0 A _DABS size 0 flags 8 addr 0 @@ -13,7 +13,7 @@ A _GSINIT size 0 flags 0 addr 0 A _GSFINAL size 0 flags 0 addr 0 A _INITIALIZER size 0 flags 0 addr 0 A _CABS size 0 flags 8 addr 0 -T 00 00 00 +T 00 00 00 00 R 00 00 00 00 -T 00 00 00 4B 42 CB C9 C9 +T 00 00 00 00 4B 42 CB C9 C9 R 00 00 00 00