mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Improve linker script align (#1271)
An offset is now supported, and invalid values are no longer silently truncated, aligning behaviour with other instances of the directive.
This commit is contained in:
@@ -68,15 +68,25 @@ and
|
||||
.Ic DS :
|
||||
.Bl -bullet
|
||||
.It
|
||||
.Ic ORG
|
||||
sets the address in which new sections will be placed.
|
||||
.Ic ORG Ar addr
|
||||
sets the address in which new sections will be placed to
|
||||
.Ar addr .
|
||||
It can not be lower than the current address.
|
||||
.It
|
||||
.Ic ALIGN
|
||||
.Ic ALIGN Ar addr
|
||||
or
|
||||
.Ic ALIGN Ar addr , Ar offset
|
||||
will increase the address until it is aligned to the specified boundary
|
||||
.Po it tries to set to 0 the number of bits specified after the directive:
|
||||
.Po it tries to set to
|
||||
.Ar offset
|
||||
the number of bits specified by
|
||||
.Ar align :
|
||||
for example,
|
||||
.Ql ALIGN 8
|
||||
will align to $100
|
||||
will align to $100 ,
|
||||
and
|
||||
.Ql ALIGN 8 , 10
|
||||
will align to $10A
|
||||
.Pc .
|
||||
.It
|
||||
.Ic DS
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
%token YYEOF 0 "end of file"
|
||||
%token newline
|
||||
%token COMMA ","
|
||||
%token ORG "ORG"
|
||||
INCLUDE "INCLUDE"
|
||||
ALIGN "ALIGN"
|
||||
@@ -83,6 +84,7 @@ directive: section_type { setSectionType($1); }
|
||||
| section_type number { setSectionType($1, $2); }
|
||||
| ORG number { setAddr($2); }
|
||||
| ALIGN number { alignTo($2, 0); }
|
||||
| ALIGN number COMMA number { alignTo($2, $4); }
|
||||
| DS number { pad($2); }
|
||||
| string { placeSection($1); }
|
||||
;
|
||||
@@ -197,6 +199,8 @@ try_again: // Can't use a `do {} while(0)` loop, otherwise compilers (wrongly) t
|
||||
} else {
|
||||
return yy::parser::make_YYEOF();
|
||||
}
|
||||
} else if (c == ',') {
|
||||
return yy::parser::make_COMMA();
|
||||
} else if (isNewline(c)) {
|
||||
// Handle CRLF.
|
||||
if (c == '\r' && context.file.sgetc() == '\n') {
|
||||
@@ -372,18 +376,37 @@ static void alignTo(uint32_t alignment, uint32_t alignOfs) {
|
||||
auto const &typeInfo = sectionTypeInfo[activeType];
|
||||
auto &pc = curAddr[activeType][activeBankIdx];
|
||||
|
||||
// TODO: maybe warn if truncating?
|
||||
alignOfs %= 1 << alignment;
|
||||
|
||||
assert(pc >= typeInfo.startAddr);
|
||||
uint16_t length = alignment < 16 ? (uint16_t)(alignOfs - pc) % (1u << alignment)
|
||||
: alignOfs - pc; // Let it wrap around, this'll trip the check.
|
||||
if (uint16_t offset = pc - typeInfo.startAddr; length > typeInfo.size - offset) {
|
||||
scriptError(context, "Cannot align: the next suitable address after $%04" PRIx16 " is $%04" PRIx16 ", past $%04" PRIx16,
|
||||
pc, (uint16_t)(pc + length), (uint16_t)(endaddr(activeType) + 1));
|
||||
} else {
|
||||
pc += length;
|
||||
if (alignment > 16) {
|
||||
scriptError(context, "Cannot align: The alignment (%" PRIu32 ") must be less than 16\n",
|
||||
alignment);
|
||||
return;
|
||||
}
|
||||
|
||||
// Let it wrap around, this'll trip the final check if alignment == 16.
|
||||
uint16_t length = alignOfs - pc;
|
||||
|
||||
if (alignment < 16) {
|
||||
uint32_t alignSize = 1u << alignment;
|
||||
|
||||
if (alignOfs >= alignSize) {
|
||||
scriptError(context, "Cannot align: The alignment offset (%" PRIu32
|
||||
") must be less than alignment size (%" PRIu32 ")\n",
|
||||
alignOfs, 1 << alignment);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pc >= typeInfo.startAddr);
|
||||
length %= alignSize;
|
||||
}
|
||||
|
||||
if (uint16_t offset = pc - typeInfo.startAddr; length > typeInfo.size - offset) {
|
||||
scriptError(context, "Cannot align: the next suitable address after $%04"
|
||||
PRIx16 " is $%04" PRIx16 ", past $%04" PRIx16,
|
||||
pc, (uint16_t)(pc + length), (uint16_t)(endaddr(activeType) + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
pc += length;
|
||||
}
|
||||
|
||||
static void pad(uint32_t length) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: ./section-attributes-mismatch.link(3): The linker script assigns section "sec" to address $0018, but that would be ALIGN[4, 8] instead of the requested ALIGN[4, 0]
|
||||
error: ./section-attributes-mismatch.link(3): The linker script assigns section "sec" to address $0018, but that would be ALIGN[4, 8] instead of the requested ALIGN[4, 2]
|
||||
Linking failed with 1 error
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SECTION "sec",ROM0,ALIGN[4]
|
||||
ds 8, $42
|
||||
SECTION "sec",ROM0,ALIGN[4,2]
|
||||
ds 6, $42
|
||||
SECTION "secfix",ROM0[$20]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
ROM0
|
||||
align 4
|
||||
align 4, 2
|
||||
"sec"
|
||||
ds $18
|
||||
org $20
|
||||
align 5
|
||||
"secfix"
|
||||
|
||||
Reference in New Issue
Block a user