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_pageBFD 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?