Closed nickdesaulniers closed 5 years ago
Thanks all!
r358652
George has also authored: https://reviews.llvm.org/D55550 to help simplify https://reviews.llvm.org/D55423.
I investigated the issue, thoughts are below.
So we have: aliastotext = text; SECTIONS { .text 0x1000 : { __text = . ; *(.text) } }
In this script, we have 2 assignment symbols commands (for 'aliastotext' and for 'text') and the problem is that we set the final value of the second symbol too late and first does not get the correct section value.
I experimented with the GNU linkers and the following script:
aliastotext = aliastotext1; aliastotext1 = aliastotext2; aliastotext2 = text;
gold (2.28) does not support it: (gold does set the section index as expected) Num: Value Size Type Bind Vis Ndx Name 6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS aliastotext 7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS aliastotext1 8: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aliasto__text2
Though BFD do: Num: Value Size Type Bind Vis Ndx Name 16: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aliastotext2 17: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aliastotext1 18: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aliasto__text
I think we do not need to support the BFD behavior and it is enough to follow the behavior gold has.
Let see what LLD do now with the linker script symbols of the initial script:
1) First, we declare Defined symbols stubs in declareSymbols
https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L246
https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L198
We create stub Defined symbols early because want to make them visible by LTO and to do a symbol versioning.
2) Later during processSectionCommands
we call addSymbol
:
(https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L475)
(https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L165)
Just like internal comment says, we do that because want to set symbol values early if we can. This allows us to use symbols as variables in linker scripts. Doing so allows us to write expressions like this:
VAR = 0x1000; ... SECTIONS { ... .bbb : ALIGN(VAR) { *(.bbb) }
So we are able to set 0x1000 value early and set the proper section .bbb alignment in
adjustSectionsBeforeSorting
:
https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L879
3) At the end, we set the final symbol values in the assignSymbol
:
assignAddresses() (https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L1036)
assignOffsets() (https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L764)
assignSymbol() (https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L270)
What happens for the sample script above?
We do steps 1 and 2 as usual. Since we iterate assignment commands one by one, at the step 2
we assign a nullptr as a section value to aliasto__text
(https://github.com/llvm-mirror/lld/blob/master/ELF/LinkerScript.cpp#L176). That happens
because we assign aliasto__text
before the __text
and at the moment of assignment
__text
does not have a section assigned, what leaves aliasto__text
symbol absolute.
Then we are scanning the relocations in scanRelocations<ELFT>
and fail with
'cannot refer to absolute symbol' here:
https://github.com/llvm-mirror/lld/blob/master/ELF/Relocations.cpp#L408
I experimented with few different approaches and ended up with a next patch finally: https://reviews.llvm.org/D55423
To reproduce:
// rtoabs.s .text .globl _start .type _start, %function _start: .globl aliastotext bl text // Ok, text is section relative. bl aliastotext // Should be ok, but isn't. ret
aliastotext = text; SECTIONS { .text 0x1000 : { __text = . ; *(.text) } }
This will link fine without -pie or -shared: bin/ld.lld rtoabs.o -o rtoabs.axf --script=rtoabs.lds
With -pie then we get: ld.lld rtoabs.o -o rtoabs.axf --script=rtoabs.lds --pie ld.lld: error: relocation R_AARCH64_CALL26 cannot refer to absolute symbol: aliasto__text
defined in
referenced by rtoabs.o:(.text+0x4)
Extended Description
Not sure the best way to reproduce this, but it was reported in another bug and in a mail thread.
llvm/llvm-project#39157 #c11: "It seems like efistubtext = _text; loses the section relative property of _text."
llvm/llvm-project#39157 #c13: 2.) A symbol assignment to symbol defined in a section description in a linker script can lose the section information.
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20170116/420898.html: "The real problem is that we are not tracking absoluteness correctly."
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-December/616765.html: (since using an intermediate assignment loses the section relative property when using ld.lld)