File tree Expand file tree Collapse file tree 4 files changed +46
-4
lines changed
Expand file tree Collapse file tree 4 files changed +46
-4
lines changed Original file line number Diff line number Diff line change @@ -1102,12 +1102,21 @@ void LinkerScript::diagnoseMissingSGSectionAddress() const {
11021102// This is roughly the same logic as the loop in assignOffsets() to loop
11031103// through all commands and input sections in an output section to calculate
11041104// the total size.
1105- static uint64_t outputSectionCheriAlignment (Ctx &ctx, OutputSection *sec)
1106- {
1105+ uint64_t LinkerScript::outputSectionCheriAlignment (OutputSection *sec) {
11071106 uint64_t total = 0 ;
11081107
11091108 for (SectionCommand *cmd : sec->commands ) {
1110- if (dyn_cast<SymbolAssignment>(cmd)) {
1109+ if (SymbolAssignment *assign = dyn_cast<SymbolAssignment>(cmd)) {
1110+ if (assign->name == " ." ) {
1111+ // Evaluating an expression like ". += 0x100" will attempt to read
1112+ // the current value of dot, which isn't accurate since we're doing
1113+ // things out of order here. We can fake it by temporarily setting
1114+ // the value of dot and restoring it later.
1115+ auto oldDot = dot;
1116+ dot = total;
1117+ total += assign->expression ().getValue ();
1118+ dot = oldDot;
1119+ }
11111120 continue ;
11121121 }
11131122
@@ -1230,7 +1239,7 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
12301239 // ALIGN is respected. sec->alignment is the max of ALIGN and the maximum of
12311240 // input section alignments.
12321241 if (sec->isCapAligned ) {
1233- uint64_t capAlignment = outputSectionCheriAlignment (ctx, sec);
1242+ uint64_t capAlignment = outputSectionCheriAlignment (sec);
12341243 if (capAlignment > 1 ) {
12351244 sec->addralign = std::max<uint64_t >(capAlignment, sec->addralign );
12361245 }
Original file line number Diff line number Diff line change @@ -340,6 +340,7 @@ class LinkerScript final {
340340 findMemoryRegion (OutputSection *sec, MemoryRegion *hint);
341341
342342 bool assignOffsets (OutputSection *sec);
343+ uint64_t outputSectionCheriAlignment (OutputSection *sec);
343344
344345 // This captures the local AddressState and makes it accessible
345346 // deliberately. This is needed as there are some cases where we cannot just
Original file line number Diff line number Diff line change 1+ SECTIONS {
2+ . = 0x1245 ;
3+ . = ALIGN (8 );
4+ .bar : CAPALIGN {
5+ .bar_start = .;
6+ . += 0x100000 ;
7+ .bar_end = .;
8+ }
9+ }
Original file line number Diff line number Diff line change 1+ // REQUIRES: riscv
2+ // RUN: llvm-mc -triple riscv32-unknown-cheriotrtos -filetype=obj -o %t %s
3+ // RUN: ld.lld %t %S/Inputs/cheriot-capalign.lds -o %t2
4+ // RUN: llvm-readobj --sections %t2 | FileCheck %s
5+
6+ // Verify that CAPALIGN directives in the linker script actually
7+ // force higher alignment on an over-sized section.
8+
9+ // CHECK: Index: 2
10+ // CHECK-NEXT: Name: .bar (7)
11+ // CHECK-NEXT: Type: SHT_PROGBITS (0x1)
12+ // CHECK-NEXT: Flags [ (0x0)
13+ // CHECK-NEXT: ]
14+ // CHECK-NEXT: Address: 0x0
15+ // CHECK-NEXT: Offset: 0x20000
16+ // CHECK-NEXT: Size: 1179648
17+ // CHECK-NEXT: Link: 0
18+ // CHECK-NEXT: Info: 0
19+ // CHECK-NEXT: AddressAlignment: 131072
20+ // CHECK-NEXT: EntrySize: 0
21+
22+ .section .bar
23+ .byte 0
You can’t perform that action at this time.
0 commit comments