After applying D29332 and trying to link linux kernel I found next issue.
We still produced symbols value wrong.
Having the next script:
vvar_start = . - 2 * (1 << 12); vvar_page = vvar_start; vvar_vsyscall_gtod_data = vvar_page + 128; pvclock_page = vvar_start + PAGE_SIZE; . = SIZEOF_HEADERS; .hash : { *(.hash) } :text ...
LLD output was:
Section Headers: [Nr] Name Type Address Offset [ 1] .hash HASH 0000000000000120 00000120 0000000000000050 0000000000000004 A 3 0 4 Symbol table '.symtab' contains 18 entries: Num: Value Size Type Bind Vis Ndx Name 3: ffffffffffffe1a0 0 NOTYPE LOCAL HIDDEN 1 vvar_vsyscall_gtod_data 5: ffffffffffffe120 0 NOTYPE LOCAL DEFAULT 1 vvar_start 6: ffffffffffffe120 0 NOTYPE LOCAL DEFAULT 1 vvar_page
BFD was:
28: ffffffffffffe000 0 NOTYPE LOCAL DEFAULT ABS vvar_page 33: ffffffffffffe000 0 NOTYPE LOCAL DEFAULT 1 vvar_start 35: ffffffffffffe080 0 NOTYPE LOCAL DEFAULT ABS vvar_vsyscall_gtod_data
GOLD was:
6: ffffffffffffe000 0 NOTYPE LOCAL DEFAULT ABS vvar_start 7: ffffffffffffe000 0 NOTYPE LOCAL DEFAULT ABS vvar_page 8: ffffffffffffe080 0 NOTYPE LOCAL DEFAULT ABS vvar_vsyscall_gtod_data
The problem was in assignSectionSymbol(). We used Body->Section->Addr too early.
At the point of evaluation Addr was unset and == 0x0. Solution I suggest - to postpone the evaluation.
After that patch values we produce are correct for case above.
I don't think I understand this comment. Why Sym value is affected by the following .sec?
I do understand that Sym is affected if it is .sec : { ... }; Sym = ., but this is Sym = .; .sec { ... };. Can a following expression affects the results of preceding expressions?
By the way, why + 0x1?