You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The goal here is to separate bar from main by 0x100000B.
Let's see what happens with various linkers without LTO first so that we can see clearly that LTO's behavior is quite surprising.
First let's look at GNU ld.bfd:
$ clang x.c -Wl,-T,foo.lds -O0
$ llvm-nm a.out | grep -e bar -e ' main'00000000001005d8 D bar00000000000000f0 T main
Well, they're not exactly 0x100000B apart, but they are at least 0x100000B apart. Ok.
And LLVM ld.lld:
$ clang x.c -Wl,-T,foo.lds -O0 -fuse-ld=lld
$ llvm-nm a.out | grep -e bar -e ' main'0000000000100510 D bar00000000000000f0 T main
Slightly different address for bar, but again, at least 0x100000B apart.
Now let's see what lld does with LTO:
$ clang x.c -Wl,-T,foo.lds -O0 -fuse-ld=lld -flto
$ llvm-nm a.out | grep -e bar -e ' main'0000000000100530 d bar0000000000100030 T main
This is a bit unexpected; suddenly both symbols are offset by 0x100000B. (at least the relative order of symbols hasn't changed, I guess).
This is forked from ClangBuiltLinux/linux#1909 in which Linux kernel security mitigations for AMD SRSO hardware vulnerabilities try to use a linker script to keep two symbols 0x104104 B apart. I don't think this can be done portably via linker script, but "it happened to have worked with ld.bfd" and now such kernel patches are merged in virtually every relevant tree, breaking every x86 build with lld.
It's pretty common in the Linux kernel's linker scripts to realign various sections using:
. = ALIGN(some constant)
if LTO is messing this up, some sections might not have the proper or expected alignment.
Is there another way to specify that a specific section (or symbol) should have an alignment (for ELF objects)? These sections in the kernel sources are defined in the assembler.
Consider the following C code:
(So
bar
is in sectionfoo
, whilemain
is in.text
).and poorly written (minimal?) linker script:
The goal here is to separate
bar
frommain
by 0x100000B.Let's see what happens with various linkers without LTO first so that we can see clearly that LTO's behavior is quite surprising.
First let's look at GNU ld.bfd:
Well, they're not exactly 0x100000B apart, but they are at least 0x100000B apart. Ok.
And LLVM ld.lld:
Slightly different address for
bar
, but again, at least 0x100000B apart.Now let's see what lld does with LTO:
This is a bit unexpected; suddenly both symbols are offset by 0x100000B. (at least the relative order of symbols hasn't changed, I guess).
This is forked from ClangBuiltLinux/linux#1909 in which Linux kernel security mitigations for AMD SRSO hardware vulnerabilities try to use a linker script to keep two symbols
0x104104
B apart. I don't think this can be done portably via linker script, but "it happened to have worked with ld.bfd" and now such kernel patches are merged in virtually every relevant tree, breaking every x86 build with lld.It's pretty common in the Linux kernel's linker scripts to realign various sections using:
if LTO is messing this up, some sections might not have the proper or expected alignment.
Is there another way to specify that a specific section (or symbol) should have an alignment (for ELF objects)? These sections in the kernel sources are defined in the assembler.
cc @MaskRay
The text was updated successfully, but these errors were encountered: