We often have to restart the layout computation when some assumption changes such as the number of segments. When this layout re-computation restart happens, sometimes we end up using incorrect symbol values when evaluating some assignments. This can lead to incorrect layout.
Reproducible example:
#!/usr/bin/env bash
cat >1.c <<\EOF
int foo() { return 1; }
int u = 11;
EOF
cat >script.t <<\EOF
SECTIONS {
u = v;
.text.foo : { *(.text.foo) }
v = 0x1000;
.data : { *(.data) }
.comment : { *(.comment) }
v = 0x2000;
}
EOF
LDs=(ld.eld)
SFs=(eld)
clang -o 1.o -target aarch64-unknown-elf 1.c -c -ffunction-sections
for i in "${!SFs[@]}"; do
${LDs[$i]} -o 1.${SFs[$i]}.out 1.o -T script.t
done
llvm-readelf -s 1.eld.out
Outputs:
...
8: 0000000000000000 8 FUNC GLOBAL DEFAULT 1 foo
9: 0000000000001000 4 OBJECT GLOBAL DEFAULT ABS u
...
The value of u should be 0x2000 instead of 0x1000.