This change permits there to be more than one thunk to be associated with
a symbol. For interworking thunks we only require one thunk, but range
extension thunks may require more than one.
Differential Revision: https://reviews.llvm.org/D34037
llvm-svn: 307136
In preparation for supporting range extension thunks we now continually
call createThunks() until no more thunks are added. This requires us to
record the thunks we add on each pass and only merge the new ones into the
OutputSection. We also need to check if a Relocation is targeting a thunk
to prevent us from infinitely creating more thunks.
Differential Revision: https://reviews.llvm.org/D34034
llvm-svn: 305555
Thunks are now generated per InputSectionDescription instead of per
OutputSection. This allows created ThunkSections to be inserted directly
into InputSectionDescription.
Changes in this patch:
- Loop over InputSectionDescriptions to find relocations to Thunks
- Generate a ThunkSection per InputSectionDescription
- Remove synchronize() as we no longer need it
- Move fabricateDefaultCommands() before createThunks
Differential Revision: https://reviews.llvm.org/D33835
llvm-svn: 304887
In preparation for inserting Thunks into InputSectionDescription::Sections
extract the loop that finds InputSections that may have calls that need
Thunks. This isn't much benefit now but this will be useful when we have to
extract the InputSectionDescriptions::Sections from the script.
Differential Revision: https://reviews.llvm.org/D33834
llvm-svn: 304783
In preparation for inserting Thunks into InputSectionDescriptions this
simple change associates added Thunks with a vector of InputSections instead
of an OutputSection. As of now we are just using OutputSection::Sections.
Differential Revision: https://reviews.llvm.org/D33832
llvm-svn: 304782
This change adds support for the R_ARM_SBREL32 relocation. The relocation
is a base relative relocation that is produced by clang/llvm when -frwpi
is used. The use case for the -frwpi option is position independent data
for embedded systems that do not have a GOT. With -frwpi all data is
accessed via an offset from a base register (usually r9), where r9 is set
at run time to where the data has been loaded. The base of the data is
known as the static base.
The ARM ABI defines the static base as:
B(S) is the addressing origin of the output segment defining the symbol S.
The origin is not required to be the base address of the segment. For
simplicity we choose to use the base address of the segment.
The ARM procedure call standard only defines a read write variant using
R_ARM_SBREL32 relocations. The read-only data is accessed via pc-relative
offsets from the code, this is implemented in clang as -fropi.
Fixes PR32924
Differential Revision: https://reviews.llvm.org/D33280
llvm-svn: 303337
Nothing special here, just detemplates code that became possible
to detemplate after recent commits in a straghtforward way.
Differential revision: https://reviews.llvm.org/D33234
llvm-svn: 303237
For range extension thunks we will need to repeatedly call createThunks()
until no more thunks are created. We will need to retain the state of
Thunks that we have created so far to avoid recreating them on later
passes. This change does not change the functionality of createThunks().
Differential Revision: https://reviews.llvm.org/D31654
llvm-svn: 299530
The patch introduces two new relocations expressions R_MIPS_GOT_GP and
R_MIPS_GOT_GP_PC. The first one represents a current value of `_gp`
pointer and used to calculate relocations against the `__gnu_local_gp`
symbol. The second one represents the offset between the beginning of
the function and the `_gp` pointer's value.
There are two motivations for introducing new expressions:
- It's better to keep all non-trivial relocation calculations in the
single place - `getRelocTargetVA` function.
- Relocations against both `_gp_disp` and `__gnu_local_gp` symbols
depend on the `_gp` value. It's a magical value points to the "middle"
of GOT. Now all relocations use a common `_gp` value. But in fact,
under some conditions each input file might require its own `_gp`
value. I'm going to implement it in the future patches. So it's
better to make `MipsGotSection` responsible for calculation of
the `_gp` value.
llvm-svn: 298306
This change moves the calls to finalizeContent() for each synthetic section
before createThunks(). This will allow us to assign addresses prior to
calling createThunks(). As addition of thunks may add to the static
symbol table and may affect the size of the mips got section we introduce a
couple of additional member functions to update these values.
Differential revision: https://reviews.llvm.org/D29983
llvm-svn: 297277
With this we complete the transition out of special output sections,
and with the previous patches it should be possible to merge
OutputSectionBase and OuputSection.
llvm-svn: 296023
With the current design an InputSection is basically anything that
goes directly in a OutputSection. That includes plain input section
but also synthetic sections, so this should probably not be a
template.
llvm-svn: 295993
We shouldn't report an error for R_*_NONE relocs since we're emitting
them when writing relocations to discarded sections.
Differential Revision: https://reviews.llvm.org/D30279
llvm-svn: 295936
In the target dependent code we already always return a int64_t. In
the target independent code we carefully use uintX_t, which has the
same result given 2 complement rules.
This just simplifies the code to use int64_t everywhere.
llvm-svn: 295263
Thunks are now implemented by redirecting the relocation to the
symbol S, to a symbol TS in a Thunk. The Thunk will transfer control
to S. This has the following implications:
- All the side-effects of Thunks happen within createThunks()
- Thunks are no longer stored in InputSections and Symbols no longer
need to hold a pointer to a Thunk
- The synthetic Thunk sections need to be merged into OutputSections
This implementation is almost a direct conversion of the existing
Thunks with the following exceptions:
- Mips LA25 Thunks are placed before the InputSection that defines
the symbol that needs a Thunk.
- All ARM Thunks are placed at the end of the OutputSection of the
first caller to the Thunk.
Range extension Thunks are not supported yet so it is optimistically
assumed that all Thunks can be reused.
This is a recommit of r293283 with a fixed comparison predicate as
std::merge requires a strict weak ordering.
Differential revision: https://reviews.llvm.org/D29327
llvm-svn: 293757
Thunks are now implemented by redirecting the relocation to the
symbol S, to a symbol TS in a Thunk. The Thunk will transfer control
to S. This has the following implications:
- All the side-effects of Thunks happen within createThunks()
- Thunks are no longer stored in InputSections and Symbols no longer
need to hold a pointer to a Thunk
- The synthetic Thunk sections need to be merged into OutputSections
This implementation is almost a direct conversion of the existing
Thunks with the following exceptions:
- Mips LA25 Thunks are placed before the InputSection that defines
the symbol that needs a Thunk.
- All ARM Thunks are placed at the end of the OutputSection of the
first caller to the Thunk.
Range extension Thunks are not supported yet so it is optimistically
assumed that all Thunks can be reused.
Differential Revision: https://reviews.llvm.org/D29129
llvm-svn: 293283
A necessary first step towards range extension thunks is to delay
the creation of thunks until the layout of InputSections within
OutputSections has been done.
The change scans the relocations directly from InputSections rather
than looking in the ELF File the InputSection came from. This will
allow a future change to redirect the relocations to symbols defined
by Thunks rather than indirect when resolving relocations.
A side-effect of moving ThunkCreation is that the OutSecOff of
InputSections may change in an OutputSection that contains Thunks.
In well behaved programs thunks are not in OutputSections with
dynamic relocations.
Differential Revision: https://reviews.llvm.org/D28811
llvm-svn: 292359
In various places in LLD's hot loops, we have expressions of the form
"E == R_FOO || E == R_BAR || ..." (E is a RelExpr).
Some of these expressions are quite long, and even though they usually go just
a very small number of ways and so should be well predicted, they can still
occupy branch predictor resources harming other parts of the code, or they
won't be predicted well if they overflow branch predictor resources or if the
branches are too dense and the branch predictor can't track them all (the
compiler can in theory avoid this, at a cost in text size). And some of these
expressions are so large and executed so frequently that even when
well-predicted they probably still have a nontrivial cost.
This speedup should be pretty portable. The cost of these simple bit tests is
independent of:
- the target we are linking for
- the distribution of RelExpr's for a given link (which can depend on how the
input files were compiled)
- what compiler was used to compile LLD (it is just a simple bit test;
hopefully the compiler gets it right!)
- adding new target-dependent relocations (e.g. needsPlt doesn't pay any extra
cost checking R_PPC_PLT_OPD on x86-64 builds)
I did some rough measurements on clang-fsds and this patch gives over about 4%
speedup for a regular -O1 link, about 2.5% for -O3 --gc-sections and over 5%
for -O0. Sorry, I don't have my current machine set up for doing really
accurate measurements right now.
This also is just a bit cleaner. Thanks for Joerg for suggesting for
this approach.
Differential Revision: https://reviews.llvm.org/D27156
llvm-svn: 288314
The function was used only within Relocations.cpp, but now we are
using it in many places, so this patch moves it to a file that fits
to the functionality.
llvm-svn: 287943
MIPS GOT handling is very different from other targets so it is better
to keep the code in the separatre section class MipsGotSection. This
patch introduces the new section and moves all MIPS specific code from
GotSection to the new class. I did not rename fields and methods in the
MipsGotSection class to reduce the diff and plan to do that by the
separate commit.
Differential revision: https://reviews.llvm.org/D26733
llvm-svn: 287150
Relocations are the last thing that we wore storing a raw section
pointer to and parsing on demand.
With this patch we parse it only once and store a pointer to the
actual data.
The patch also changes where we store it. It is now in
InputSectionBase. Not all sections have relocations, but most do and
this simplifies the logic. It also means that we now only support one
relocation section per section. Given that that constraint is
maintained even with -r with gold bfd and lld, I think it is OK.
llvm-svn: 286459
Some MIPS relocations used to access GOT entries are able to manipulate
16-bit index. The other ones like R_MIPS_CALL_HI16/LO16 can handle
32-bit indexes. 16-bit relocations are generated by default. The 32-bit
relocations are generated by -mxgot flag passed to compiler. Usually
these relocation are not mixed in the same code but files like crt*.o
contain 16-bit relocations so even if all "user's" code compiled with
-mxgot flag a few 16-bit relocations might come to the linking phase.
Now LLD does not differentiate local GOT entries accessed via a 16-bit
and 32-bit indexes. That might lead to relocation's overflow if 16-bit
entries are allocated to far from the beginning of the GOT.
The patch introduces new "part" of MIPS GOT dedicated to the local GOT
entries accessed by 32-bit relocations. That allows to put local GOT
entries accessed via a 16-bit index first and escape relocation's overflow.
Differential revision: https://reviews.llvm.org/D25833
llvm-svn: 284809
The R_ARM_PREL31 and R_ARM_NONE relocations should not be faulted in
shared libraries. In the case of R_ARM_NONE, we have moved the TLS
relaxation hint instruction to R_TLSDESC_CALL so that R_HINT can be used
without side-effects. In the case of R_ARM_PREL31 we permit it to be used
against PLT entries as the personality routines are imported when used in
shared libraries.
Differential Revision: https://reviews.llvm.org/D25721
llvm-svn: 284710
We will need to do something like this to support range extension
thunks since that process is iterative.
Doing this also has the advantage that when doing the regular
relocation scan the offset in the output section is known and we can
just store that. This reduces the number of times we have to run
getOffset and I think will allow a more specialized .eh_frame
representation.
By itself this is already a performance win.
firefox
master 7.295045737
patch 7.209466989 0.98826892235
chromium
master 4.531254468
patch 4.509221804 0.995137623774
chromium fast
master 1.836928973
patch 1.823805241 0.992855612714
the gold plugin
master 0.379768791
patch 0.380043405 1.00072310839
clang
master 0.642698284
patch 0.642215663 0.999249070657
llvm-as
master 0.036665467
patch 0.036456225 0.994293213284
the gold plugin fsds
master 0.40395817
patch 0.404384555 1.0010555177
clang fsds
master 0.722045545
patch 0.720946135 0.998477367518
llvm-as fsds
master 0.03292646
patch 0.032759965 0.994943428477
scylla
master 3.427376378
patch 3.368316181 0.98276810292
llvm-svn: 276146
The TinyPtrVector of const Thunk<ELFT>* in InputSections.h can cause
build failures on certain compiler/library combinations when Thunk<ELFT>
is not a complete type or is an abstract class. Fixed by making Thunk<ELFT>
non Abstract.
type or is an abstract class
llvm-svn: 274863
Generalise the Mips LA25 Thunk code and implement ARM and Thumb
interworking Thunks.
- Introduce a new module Thunks.cpp to store the Target Specific Thunk
implementations.
- DefinedRegular and Shared have a ThunkData field to record Thunk.
- A Target can have more than one type of Thunk.
- Support PC-relative calls to Thunks.
- Support Thunks to PLT entries.
- Existing Mips LA25 Thunk code integrated.
- Support for ARMv7A interworking Thunks.
Limitations:
- Only one Thunk per SymbolBody, this is sufficient for all currently
implemented Thunks.
- ARM thunks assume presence of V6T2 MOVT and MOVW instructions.
Differential revision: http://reviews.llvm.org/D21891
llvm-svn: 274836
The patch adds one more partition to the MIPS GOT. This time it is for
TLS related GOT entries. Such entries are located after 'local' and 'global'
ones. We cannot get a final offset for these entries at the time of
creation because we do not know size of 'local' and 'global' partitions.
So we have to adjust the offset later using `getMipsTlsOffset()` method.
All MIPS TLS relocations which need GOT entries operates MIPS style GOT
offset - 'offset from the GOT's beginning' - MipsGPOffset constant. That
is why I add new types of relocation expressions.
One more difference from othe ABIs is that the MIPS ABI does not support
any TLS relocation relaxations. I decided to make a separate function
`handleMipsTlsRelocation` and put MIPS TLS relocation handling code
there. It is similar to `handleTlsRelocation` routine and duplicates its
code. But it allows to make the code cleaner and prevent pollution of
the `handleTlsRelocation` by MIPS 'if' statements.
Differential Revision: http://reviews.llvm.org/D21606
llvm-svn: 273569
Peter Smith found while trying to support thunk creation for ARM that
LLD sometimes creates broken thunks for MIPS. The cause of the bug is
that we assign file offsets to input sections too early. We need to
create all sections and then assign section offsets because appending
thunks changes file offsets for all following sections.
This patch separates the pass to assign file offsets from thunk
creation pass. This effectively reverts r265673.
Differential Revision: http://reviews.llvm.org/D21598
llvm-svn: 273532
There are two motivations for this patch. The first one is a preparation
for support MIPS TLS relocations. It might sound like a joke but for GOT
entries related to TLS relocations MIPS ABI uses almost regular approach
with creation of dynamic relocations for each GOT enty etc. But we need
to separate these 'regular' TLS related entries from MIPS specific local
and global parts of GOT. ABI declare simple solution - all TLS related
entries allocated at the end of GOT after local/global parts. The second
motivation it to support GOT relocations for non-preemptible symbols
with addends. If we have more than one GOT relocations against symbol S
with different addends we need to create GOT entries for each unique
Symbol/Addend pairs.
So we store all MIPS GOT entries in separate containers. For non-preemptible
symbols we have to maintain two data structures. The first one is MipsLocal
vector. Each entry corresponds to the GOT entry from the 'local' part
of the GOT contains the symbol's address plus addend. The second one
is MipsLocalMap. It is a map from Symbol/Addend pair to the GOT index.
Differential Revision: http://reviews.llvm.org/D21297
llvm-svn: 273127
This is mostly extracted from http://reviews.llvm.org/D18960.
The general idea for tlsdesc is that the two GD got entries are used
for a function pointer and its argument. The dynamic linker sets
both. In the non-dlopen case the dynamic linker sets the function to
the identity and the argument to the offset in the tls block.
All that the static linker has to do in the non-dlopen case is
relocate the code to point to the got entries and create a dynamic
relocation.
The dlopen case is more complicated, but can be implemented in another patch.
llvm-svn: 271569
Patch implements next relaxation from latest ABI:
"Convert memory operand of test and binop into immediate operand, where binop is one of adc, add, and, cmp, or,
sbb, sub, xor instructions, when position-independent code is disabled."
It is described in System V Application Binary Interface AMD64 Architecture Processor
Supplement Draft Version 0.99.8 (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-r249.pdf,
B.2 "B.2 Optimize GOTPCRELX Relocations").
Differential revision: http://reviews.llvm.org/D20793
llvm-svn: 271405