We add the following extra error checking:
1) That TLS relocations (including SIZE relocations, but excluding
Local-Exec relocations) are not requested against a symbol plus
addend.
2) That SIZE relocations are requested against a defined symbol in the
current binary (i.e. one that the static linker knows the size of).
3) A TLS Local-Exec relocation must be against a symbol in the current
binary.
All the above also have error messages that describe the problem so that
the user could fix it.
Treating a relocation against a "symbol plus addend" as an error is due
to a combination of factors.
- The linker implementation does not have any way to represent a GOT
entry of "symbol plus addend". Hence we currently just have silent
bugs if asked to implement those relocations which require a GOT
entry if they have a "symbol plus addend" relocation.
- It would be wasteful anyway to have multiple entries in the GOT for
e.g. sym+off1, sym+off2.
- Morello size relocations don't support "symbol plus addend" since
the meaning would have to be defined (is this the *remaining* size
of the symbol?) and there is no known use for this.
We allow local-exec relocation on "symbol plus addend" since then the
addend just implements an offset into the object we're accessing (rather
than a new GOT entry for the location of "symbol plus addend").
There is also an existing testcase in the BFD linker to allow such
relocations. The compiler can always avoid emitting these if it wants.
Notes on implementation:
- We choose to check errors in final_link_relocate rather than
check_relocs since this is where most existing error checking is
done.
- We check for errors around addends in relocate_section rather than
final_link_relocate or check_relocs since final_link_relocate does
not get told the *original* relocation (before TLS relaxation) and
check_relocs does not know about addends coming from the result of
previous relocations on the same code.
N.b. in order to emit multiple errors when there are multiple
relocations with an addend we change things in relocate_section to
store a "return value" in a local variable and set it to false if
any problem was seen but not return early.