Commit Graph

4668 Commits

Author SHA1 Message Date
Rafael Espindola 6b2b45020c Use 4 as the alignment of .eh_frame_hdr.
It includes 32 bit values and this matches both gold and bfd.

llvm-svn: 323172
2018-01-23 05:23:23 +00:00
Chandler Carruth c58f2166ab Introduce the "retpoline" x86 mitigation technique for variant #2 of the speculative execution vulnerabilities disclosed today, specifically identified by CVE-2017-5715, "Branch Target Injection", and is one of the two halves to Spectre..
Summary:
First, we need to explain the core of the vulnerability. Note that this
is a very incomplete description, please see the Project Zero blog post
for details:
https://googleprojectzero.blogspot.com/2018/01/reading-privileged-memory-with-side.html

The basis for branch target injection is to direct speculative execution
of the processor to some "gadget" of executable code by poisoning the
prediction of indirect branches with the address of that gadget. The
gadget in turn contains an operation that provides a side channel for
reading data. Most commonly, this will look like a load of secret data
followed by a branch on the loaded value and then a load of some
predictable cache line. The attacker then uses timing of the processors
cache to determine which direction the branch took *in the speculative
execution*, and in turn what one bit of the loaded value was. Due to the
nature of these timing side channels and the branch predictor on Intel
processors, this allows an attacker to leak data only accessible to
a privileged domain (like the kernel) back into an unprivileged domain.

The goal is simple: avoid generating code which contains an indirect
branch that could have its prediction poisoned by an attacker. In many
cases, the compiler can simply use directed conditional branches and
a small search tree. LLVM already has support for lowering switches in
this way and the first step of this patch is to disable jump-table
lowering of switches and introduce a pass to rewrite explicit indirectbr
sequences into a switch over integers.

However, there is no fully general alternative to indirect calls. We
introduce a new construct we call a "retpoline" to implement indirect
calls in a non-speculatable way. It can be thought of loosely as
a trampoline for indirect calls which uses the RET instruction on x86.
Further, we arrange for a specific call->ret sequence which ensures the
processor predicts the return to go to a controlled, known location. The
retpoline then "smashes" the return address pushed onto the stack by the
call with the desired target of the original indirect call. The result
is a predicted return to the next instruction after a call (which can be
used to trap speculative execution within an infinite loop) and an
actual indirect branch to an arbitrary address.

On 64-bit x86 ABIs, this is especially easily done in the compiler by
using a guaranteed scratch register to pass the target into this device.
For 32-bit ABIs there isn't a guaranteed scratch register and so several
different retpoline variants are introduced to use a scratch register if
one is available in the calling convention and to otherwise use direct
stack push/pop sequences to pass the target address.

This "retpoline" mitigation is fully described in the following blog
post: https://support.google.com/faqs/answer/7625886

We also support a target feature that disables emission of the retpoline
thunk by the compiler to allow for custom thunks if users want them.
These are particularly useful in environments like kernels that
routinely do hot-patching on boot and want to hot-patch their thunk to
different code sequences. They can write this custom thunk and use
`-mretpoline-external-thunk` *in addition* to `-mretpoline`. In this
case, on x86-64 thu thunk names must be:
```
  __llvm_external_retpoline_r11
```
or on 32-bit:
```
  __llvm_external_retpoline_eax
  __llvm_external_retpoline_ecx
  __llvm_external_retpoline_edx
  __llvm_external_retpoline_push
```
And the target of the retpoline is passed in the named register, or in
the case of the `push` suffix on the top of the stack via a `pushl`
instruction.

There is one other important source of indirect branches in x86 ELF
binaries: the PLT. These patches also include support for LLD to
generate PLT entries that perform a retpoline-style indirection.

The only other indirect branches remaining that we are aware of are from
precompiled runtimes (such as crt0.o and similar). The ones we have
found are not really attackable, and so we have not focused on them
here, but eventually these runtimes should also be replicated for
retpoline-ed configurations for completeness.

For kernels or other freestanding or fully static executables, the
compiler switch `-mretpoline` is sufficient to fully mitigate this
particular attack. For dynamic executables, you must compile *all*
libraries with `-mretpoline` and additionally link the dynamic
executable and all shared libraries with LLD and pass `-z retpolineplt`
(or use similar functionality from some other linker). We strongly
recommend also using `-z now` as non-lazy binding allows the
retpoline-mitigated PLT to be substantially smaller.

When manually apply similar transformations to `-mretpoline` to the
Linux kernel we observed very small performance hits to applications
running typical workloads, and relatively minor hits (approximately 2%)
even for extremely syscall-heavy applications. This is largely due to
the small number of indirect branches that occur in performance
sensitive paths of the kernel.

When using these patches on statically linked applications, especially
C++ applications, you should expect to see a much more dramatic
performance hit. For microbenchmarks that are switch, indirect-, or
virtual-call heavy we have seen overheads ranging from 10% to 50%.

However, real-world workloads exhibit substantially lower performance
impact. Notably, techniques such as PGO and ThinLTO dramatically reduce
the impact of hot indirect calls (by speculatively promoting them to
direct calls) and allow optimized search trees to be used to lower
switches. If you need to deploy these techniques in C++ applications, we
*strongly* recommend that you ensure all hot call targets are statically
linked (avoiding PLT indirection) and use both PGO and ThinLTO. Well
tuned servers using all of these techniques saw 5% - 10% overhead from
the use of retpoline.

We will add detailed documentation covering these components in
subsequent patches, but wanted to make the core functionality available
as soon as possible. Happy for more code review, but we'd really like to
get these patches landed and backported ASAP for obvious reasons. We're
planning to backport this to both 6.0 and 5.0 release streams and get
a 5.0 release with just this cherry picked ASAP for distros and vendors.

This patch is the work of a number of people over the past month: Eric, Reid,
Rui, and myself. I'm mailing it out as a single commit due to the time
sensitive nature of landing this and the need to backport it. Huge thanks to
everyone who helped out here, and everyone at Intel who helped out in
discussions about how to craft this. Also, credit goes to Paul Turner (at
Google, but not an LLVM contributor) for much of the underlying retpoline
design.

Reviewers: echristo, rnk, ruiu, craig.topper, DavidKreitzer

Subscribers: sanjoy, emaste, mcrosier, mgorny, mehdi_amini, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D41723

llvm-svn: 323155
2018-01-22 22:05:25 +00:00
Rui Ueyama 2f8af79927 Avoid divisions.
Compiler doesn't know the fact that Config->WordSize * 8 is always a
power of two, so it had to use the div instruction to divide some
number with C.

llvm-svn: 323014
2018-01-20 00:14:16 +00:00
Rui Ueyama 517366c7e0 Make the bloom filter a bit larger.
I created https://reviews.llvm.org/D42202 to see how large the bloom
filter should be. With that patch, I tested various bloom filter sizes
with the following commands:

  $ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_LLD=true \
    -DLLVM_ENABLE_PROJECTS='clang;lld' -DBUILD_SHARED_LIBS=ON \
    -DCMAKE_SHARED_LINKER_FLAGS=-Wl,-bloom-filter-bits=<some integer> \
    ../llvm-project/llvm
  $ rm -f $(find . -name \*.so.7.0.0svn)
  $ ninja lld
  $ LD_BIND_NOW=1 perf stat bin/ld.lld

Here is the result:

  -bloom-filter-bits=8   0.220351609 seconds
  -bloom-filter-bits=10  0.217146597 seconds
  -bloom-filter-bits=12  0.206870826 seconds
  -bloom-filter-bits=16  0.209456312 seconds
  -bloom-filter-bits=32  0.195092075 seconds

Currently we allocate 8 bits for a symbol, but according to the above
result, that number is not optimal. Even though the numbers follow the
diminishing return rule, the point where a marginal improvement becomes
too small is not -bloom-filter-bits=8 but 12. So this patch sets it to 12.

Differential Revision: https://reviews.llvm.org/D42204

llvm-svn: 323010
2018-01-19 23:54:31 +00:00
Simon Atanasyan 712cd41fa0 [ELF][MIPS] Rename function. NFC
llvm-svn: 322861
2018-01-18 15:59:10 +00:00
Simon Atanasyan ceddcdf01c [ELF][MIPS] Decompose relocation type for N32 / N64 earlier. NFC
We need to decompose relocation type for N32 / N64 ABI. Let's do it
before any other manipulations with relocation type in the `relocateOne`
routine.

llvm-svn: 322860
2018-01-18 15:59:05 +00:00
Rafael Espindola 5e9c77624c Handle parsing AT(ADDR(.foo-bar)).
The problem we had with it is that anything inside an AT is an
expression, so we failed to parse the section name because of the - in
it.

llvm-svn: 322801
2018-01-18 01:14:57 +00:00
George Rimar 0b89c55aea [ELF] - Stop mixing order of -defsym/-script commands.
Previously we always handled -defsym after other commands in command line.
That made impossible to overload values set by -defsym from linker script:

 test.script:            
  foo = 0x22;
-defsym=foo=0x11 -script t.script
would always set foo to 0x11.

That is inconstent with common logic which allows to override command line
options. it is inconsistent with bfd behavior and seems breaks assumption that
-defsym is the same as linker script assignment, as -defsyms always handled out of
command line order.

Patch fixes the handling order.

Differential revision: https://reviews.llvm.org/D42054

llvm-svn: 322625
2018-01-17 10:24:49 +00:00
Rafael Espindola 62003fbb02 Inline foot gun into only valid use.
Symbol had both Visibility and getVisibility() and they had different
meanings. That is just too easy to get wrong.

getVisibility() would compute the visibility of a particular symbol
(foo in bar.o), and Visibility stores the computed value we will put
in the output.

There is only one case when we want what getVisibility() provides, so
inline it.

llvm-svn: 322590
2018-01-16 19:28:28 +00:00
Rafael Espindola 7e6aeb614c Fix another case we used the wrong visibility.
In here too we want the computed output visibility.

llvm-svn: 322586
2018-01-16 19:02:46 +00:00
Rafael Espindola 3c3544652b Fix another case we were using the wrong visibility.
llvm-svn: 322580
2018-01-16 18:21:23 +00:00
Rafael Espindola 37e4e695e9 Use the combined visibility when computing dso_local.
We track both the combined visibility that will be used for the output
symbol and the original input visibility of the selected symbol.

Almost everything should use the computed visibility.

I will make the names less confusing an a followup patch.

llvm-svn: 322576
2018-01-16 17:34:26 +00:00
Rafael Espindola c6df38c985 Set dso_local in lld.
We were already doing this in gold, but not in lld.

llvm-svn: 322572
2018-01-16 16:49:05 +00:00
Rui Ueyama fe148c88da Remove dead code.
parseInt assumed that it could take a negative number literal (e.g.
"-123"). However, such number is in reality already handled as a
unary operator '-' followed by a number literal, so the number
literal is always non-negative. Thus, this code is dead.

llvm-svn: 322453
2018-01-14 04:44:21 +00:00
Rafael Espindola 75702389bd Fix incorrect physical address on self-referencing AT command.
When a section placement (AT) command references the section itself,
the physical address of the section in the ELF header was calculated
incorrectly due to alignment happening right after the location
pointer's value was captured.

The problem was diagnosed and the first version of the patch written
by Erick Reyes.

llvm-svn: 322421
2018-01-12 23:26:25 +00:00
Rui Ueyama e2dfdbf0aa Do not pass an argument that can be easily inferred from other argument.
llvm-svn: 322416
2018-01-12 22:29:29 +00:00
George Rimar 9fc2c64b35 [ELF] - Do not use HeaderSize for conditions in PltSection.
Previously we checked (HeaderSize == 0) to find out if
PltSection section is IPLT or PLT. Some targets does not set
HeaderSize though. For example PPC64 has no lazy binding implemented
and does not set PltHeaderSize constant.

Because of that using of both IPLT and PLT relocations worked
incorrectly there (testcase is provided).

Patch fixes the issue.

Differential revision: https://reviews.llvm.org/D41613

llvm-svn: 322362
2018-01-12 09:35:57 +00:00
George Rimar 5d01a8be96 [ELF] - Fix for ld.lld does not accept "AT" syntax for declaring LMA region
AT> lma_region expression allows to specify the memory region
for section load address.

Should fix PR35684.

Differential revision: https://reviews.llvm.org/D41397

llvm-svn: 322359
2018-01-12 09:07:35 +00:00
Rui Ueyama c43b7e61a2 Improve an error message.
Before:
$ ld.lld --plugin-opt=Os
ld.lld: error: --plugin-opt: number expected, but got 's'

After:
$ ld.lld --plugin-opt=Os
ld.lld: error: --plugin-opt=Os: number expected, but got 's'

llvm-svn: 322315
2018-01-11 22:11:25 +00:00
Dimitry Andric 656714a311 Fix thread race between SectionPiece's OutputOff and Live members
Summary:
As reported in bug 35788, rL316280 reintroduces a race between two
members of SectionPiece, which share the same 64 bit memory location.

To fix the race, check the hash before checking the Live member, as
suggested by Rafael.

Reviewers: ruiu, rafael

Reviewed By: ruiu

Subscribers: smeenai, emaste, llvm-commits

Differential Revision: https://reviews.llvm.org/D41884

llvm-svn: 322264
2018-01-11 08:03:22 +00:00
Rui Ueyama 45fcbf0991 Remove redundnat Args.filter() argument.
OPT_plugin_opt_eq is an alias to OPT_plugin_opt, so we don't need
to give that twice.

llvm-svn: 322263
2018-01-11 07:55:01 +00:00
Shoaib Meenai d79bbf4474 [ELF] Fix SysV hash tables with --no-rosegment
When setting up the chain, we copy over the bucket's previous symbol
index, assuming that this index will be 0 (STN_UNDEF) for an unused
bucket (marking the end of the chain). When linking with --no-rosegment,
however, unused buckets will in fact contain the padding value, and so
the hash table will end up containing invalid chains. Zero out the hash
table section explicitly to avoid this, similar to what's already done
for GNU hash sections.

Differential Revision: https://reviews.llvm.org/D41928

llvm-svn: 322259
2018-01-11 06:57:01 +00:00
Ed Maste 6ed7f00e49 Correct typo in help text
Information is a mass noun and doesn't take a plural "s".

llvm-svn: 322180
2018-01-10 12:55:14 +00:00
Rafael Espindola b5506e6baf Rename --icf-data and add a corresponding flag for functions.
When we have --icf=safe we should be able to define --icf=all as a
shorthand for --icf=safe --ignore-function-address-equality.

For now --ignore-function-address-equality is used only to control
access to non preemptable symbols in shared libraries.

llvm-svn: 322152
2018-01-10 01:37:36 +00:00
Igor Kudrin 5e9da2d06b [ELF] Add a comment for ARMExidxSentinelSection::Highest; Use "= nullptr" instead of "= 0". NFC.
Differential Revision: https://reviews.llvm.org/D41234

llvm-svn: 322066
2018-01-09 09:44:27 +00:00
Easwaran Raman bfa48a14ab [ELF] Explicit template instantiations for addFile
Summary:
All other templated methods have explicit instantiations but this one is
missing. Discovered while building with a clang with inliner
modifications.

Reviewers: espindola

Subscribers: emaste, llvm-commits, davidxl

Differential Revision: https://reviews.llvm.org/D41847

llvm-svn: 322057
2018-01-09 05:35:29 +00:00
Rafael Espindola 4b6833332b Rewrite our relocation processing.
This splits relocation processing in two steps.

First, analyze what needs to be done at the relocation spot. This can
be a constant (non preemptible symbol, relative got reference, etc) or
require a dynamic relocation. At this step we also consider creating
copy relocations.

Once that is done we decide if we need a got or a plt entry.

The code is simpler IMHO. For example:

- There is a single call to isPicRel since the logic is not split
  among adjustExpr and the caller.
- R_MIPS_GOTREL is simple to handle now.
- The tracking of what is preemptible or not is much simpler now.

This also fixes a regression with symbols being both in a got and copy
relocated. They had regressed in r268668 and r268149.

The other test changes are because of error messages changes or the
order of two relocations in the output.

llvm-svn: 322047
2018-01-09 00:13:54 +00:00
Shoaib Meenai c1ca8065b5 [ELF] Small grammar fix. NFC
The whole consists of the parts, not the other way around.

llvm-svn: 322042
2018-01-08 23:18:16 +00:00
Rui Ueyama 0657e5c3f2 Do not use parallelForEach to call maybeCompress().
Currently LLVM's paralellForEach has a problem with reentracy.
That caused https://bugs.llvm.org/show_bug.cgi?id=35788 (lld somtimes
hangs while linking Ruby 2.4) because maybeCompress calls writeTo which
uses paralellForEach.

This patch is to avoid using paralellForEach to call maybeCompress
to workaround the issue.

llvm-svn: 322041
2018-01-08 23:12:42 +00:00
Rafael Espindola d1bd95cf73 Move scanReloc to an auxiliary function.
The body of the in scanRelocs is fairly big. This moves it to its own
function.

It is not a big readability win by itself, but should help further
refactoring.

llvm-svn: 322035
2018-01-08 22:20:44 +00:00
James Henderson e1689689d8 [ELF] Compress debug sections after assignAddresses and support custom layout
Previously, in r320472, I moved the calculation of section offsets and sizes
for compressed debug sections into maybeCompress, which happens before
assignAddresses, so that the compression had the required information. However,
I failed to take account of relocations that patch such sections. This had two
effects:

1. A race condition existed when a debug section referred to a different debug
section (see PR35788).
2. References to symbols in non-debug sections would be patched incorrectly.
This is because the addresses of such symbols are not calculated until after
assignAddresses (this was a partial regression caused by r320472, but they
could still have been broken before, in the event that a custom layout was used
in a linker script).

assignAddresses does not need to know about the output section size of
non-allocatable sections, because they do not affect the value of Dot. This
means that there is no longer a reason not to support custom layout of
compressed debug sections, as far as I'm aware. These two points allow for
delaying when maybeCompress can be called, removing the need for the loop I
previously added to calculate the section size, and therefore the race
condition. Furthermore, by delaying, we fix the issues of relocations getting
incorrect symbol values, because they have now all been finalized.

llvm-svn: 321986
2018-01-08 10:17:03 +00:00
Shoaib Meenai 3a15fb591e [ELF] Drop unnecessary VersionId setting in scanShlibUndefined
LLD previously used to handle dynamic lists and version scripts in the
exact same way, even though they have very different semantics for
shared libraries and subtly different semantics for executables. r315114
untangled their semantics for executables (building on previous work to
correct their semantics for shared libraries). With that change, dynamic
lists won't set the default version to VER_NDX_LOCAL, and so resetting
the version to VER_NDX_GLOBAL in scanShlibUndefined is unnecessary.

This was causing an issue because version scripts containing `local: *`
work by setting the default version to VER_NDX_LOCAL, but scanShlibUndefined
would override this default, and therefore symbols which should have
been local would end up in the dynamic symbol table, which differs from
both bfd and gold's behavior. gold silently keeps the symbol hidden in
such a scenario, whereas bfd issues an error. I prefer bfd's behavior
and plan to implement that in LLD in a follow-up (and the test case
added here will be updated accordingly).

Differential Revision: https://reviews.llvm.org/D41639

llvm-svn: 321982
2018-01-08 05:53:11 +00:00
Rafael Espindola 8d13b213d4 Simplify handling of size relocations.
This is possible now that getSize is not a template.

llvm-svn: 321900
2018-01-05 21:41:17 +00:00
Rafael Espindola 73584cb587 Centralize Config->IsRela handling.
This merges the two places were we check Config->IsRela to decide how
to write a relocation addend.

llvm-svn: 321889
2018-01-05 20:08:38 +00:00
Rafael Espindola a3ce1fdaba Inline a function that is only called once. NFC.
llvm-svn: 321780
2018-01-04 01:33:41 +00:00
Rafael Espindola bba410668a Use references for a few arguments that are never null.
llvm-svn: 321772
2018-01-03 23:26:20 +00:00
Rafael Espindola 9cded98ad6 Mention symbol name in error message.
llvm-svn: 321769
2018-01-03 22:55:46 +00:00
Rafael Espindola 7c99c14722 Use getLocation to improve error message.
llvm-svn: 321768
2018-01-03 22:44:58 +00:00
Rafael Espindola 7137b8c298 Update code as this also handles GOT relocations.
llvm-svn: 321738
2018-01-03 16:54:18 +00:00
Rafael Espindola 49422f341a Use a switch. NFC.
llvm-svn: 321737
2018-01-03 16:52:15 +00:00
Rafael Espindola cc333d7400 Refactor duplicated expression.
llvm-svn: 321736
2018-01-03 16:38:46 +00:00
Rafael Espindola 6e102b2fc6 Use a swtich. NFC.
llvm-svn: 321734
2018-01-03 16:29:43 +00:00
Rafael Espindola 28aa6e2bc5 Simplify mips gprel handling.
We normally add checks on the architecture independent Expr instead of
on the architecture dependent relocation type.

llvm-svn: 321733
2018-01-03 16:16:05 +00:00
Rafael Espindola b5153ef7e8 Don't assume that size relocations are always constant.
llvm-svn: 321688
2018-01-03 03:58:58 +00:00
Rafael Espindola 4b2350d79b Produce relocations with weak undef if the section is RW.
If a section is RW there is no reason to drop a relocation with a weak
undefined symbol.

llvm-svn: 321684
2018-01-03 01:24:58 +00:00
Rafael Espindola 2640a0a5e5 Align SHT_NOBITS sections is they are the first on a PT_LOAD.
We normally want to ignore SHT_NOBITS sections when computing
offsets. The sh_offset of section itself seems to be irrelevant and

- If the section is in the middle of a PT_LOAD, it will make no
  difference on the computed offset of the followup section.

- If it is in the end of a PT_LOAD, we want to avoid its alignment
  changing the offset of the followup sections.

The issue is if it is at the start of the PT_LOAD. In that case we do
have to align it so that the following sections have congruent address
and offset module the page size. We were not handling this case.

This should fix freebsd kernel link.

llvm-svn: 321657
2018-01-02 16:46:30 +00:00
George Rimar edb61167e5 [ELF] - Add missing dynamic tags when producing output with IRelative relocations only.
This is "Bug 35751 - .dynamic relocation entries omitted if output
contains only IFUNC relocations"

We have InX::RelaPlt and InX::RelaIPlt synthetic sections for PLT relocations.
They are usually live in rela.plt section. Problem appears when InX::RelaPlt
section is empty. In that case we did not produce normal set of dynamic tags
required, because logic was written in the way assuming we always have
non-IRelative relocations in rela.plt.

Patch fixes the issue.

Differential revision: https://reviews.llvm.org/D41592

llvm-svn: 321600
2017-12-31 07:42:54 +00:00
George Rimar 3208588e7a [ELF] - Remove excessive checks. NFC.
This was raised in comments for D41592.
With current code we always assign parent
section for Rel[a] sections like
InX::RelaPlt or InX::RelaDyn, so checking
their parent for null is excessive.

llvm-svn: 321581
2017-12-30 08:40:45 +00:00
Shoaib Meenai 0c958fba14 [ELF] Only scan executables for shlib undefined symbols
If using a version script with a `local: *` in it, symbols in shared
libraries will still get default visibility if another shared library on
the link line has an undefined reference to the symbol. This is quite
surprising. Neither bfd nor gold have this behavior when linking a
shared library, and none of LLD's tests fail without this behavior, so
it seems safe to limit scanShlibUndefined to executables.

As far as executables are concerned, gold doesn't do any automatic
default visibility marking, and bfd issues a link error about a shared
library having a reference to a hidden symbol rather than silently
giving that symbol default visibility. I think bfd's behavior here is
preferable to LLD's, but that's something to be considered in a
follow-up.

Differential Revision: https://reviews.llvm.org/D41524

llvm-svn: 321578
2017-12-30 08:00:44 +00:00
Rafael Espindola 465e7c94ed Allow copy relocation with -z notext.
This makes adjustExpr a bit simpler too IMHO.

It seems that some of the complication around relocation processing
is that we are trying to create copy relocations too early. It seems
we could handle a few simple cases first and continue.

llvm-svn: 321507
2017-12-28 00:23:49 +00:00