llvm-capstone/lld/ELF
Simon Atanasyan ed9ee69ccf [ELF][MIPS] Multi-GOT implementation
Almost all entries inside MIPS GOT are referenced by signed 16-bit
index. Zero entry lies approximately in the middle of the GOT. So the
total number of GOT entries cannot exceed ~16384 for 32-bit architecture
and ~8192 for 64-bit architecture. This limitation makes impossible to
link rather large application like for example LLVM+Clang. There are two
workaround for this problem. The first one is using the -mxgot
compiler's flag. It enables using a 32-bit index to access GOT entries.
But each access requires two assembly instructions two load GOT entry
index to a register. Another workaround is multi-GOT. This patch
implements it.

Here is a brief description of multi-GOT for detailed one see the
following link https://dmz-portal.mips.com/wiki/MIPS_Multi_GOT.

If the sum of local, global and tls entries is less than 64K only single
got is enough. Otherwise, multi-got is created. Series of primary and
multiple secondary GOTs have the following layout:
```
- Primary GOT
    Header
    Local entries
    Global entries
    Relocation only entries
    TLS entries

- Secondary GOT
    Local entries
    Global entries
    TLS entries
...
```

All GOT entries required by relocations from a single input file
entirely belong to either primary or one of secondary GOTs. To reference
GOT entries each GOT has its own _gp value points to the "middle" of the
GOT. In the code this value loaded to the register which is used for GOT
access.

MIPS 32 function's prologue:
```
lui     v0,0x0
0: R_MIPS_HI16  _gp_disp
addiu   v0,v0,0
4: R_MIPS_LO16  _gp_disp
```

MIPS 64 function's prologue:
```
lui     at,0x0
14: R_MIPS_GPREL16  main
```

Dynamic linker does not know anything about secondary GOTs and cannot
use a regular MIPS mechanism for GOT entries initialization. So we have
to use an approach accepted by other architectures and create dynamic
relocations R_MIPS_REL32 to initialize global entries (and local in case
of PIC code) in secondary GOTs. But ironically MIPS dynamic linker
requires GOT entries and correspondingly ordered dynamic symbol table
entries to deal with dynamic relocations. To handle this problem
relocation-only section in the primary GOT contains entries for all
symbols referenced in global parts of secondary GOTs. Although the sum
of local and normal global entries of the primary got should be less
than 64K, the size of the primary got (including relocation-only entries
can be greater than 64K, because parts of the primary got that overflow
the 64K limit are used only by the dynamic linker at dynamic link-time
and not by 16-bit gp-relative addressing at run-time.

The patch affects common LLD code in the following places:

- Added new hidden -mips-got-size flag. This flag required to set low
maximum size of a single GOT to be able to test the implementation using
small test cases.

- Added InputFile argument to the getRelocTargetVA function. The same
symbol referenced by GOT relocation from different input file might be
allocated in different GOT. So result of relocation depends on the file.

- Added new ctor to the DynamicReloc class. This constructor records
settings of dynamic relocation which used to adjust address of 64kb page
lies inside a specific output section.

With the patch LLD is able to link all LLVM+Clang+LLD applications and
libraries for MIPS 32/64 targets.

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

llvm-svn: 334390
2018-06-11 07:24:31 +00:00
..
Arch [PPC64] Add support for local-exec TLS model 2018-06-08 17:04:09 +00:00
AArch64ErrataFix.cpp Add a SectionBase::getVA helper. NFC. 2018-03-24 00:35:11 +00:00
AArch64ErrataFix.h Consistent (non) use of empty lines in include blocks 2018-02-20 21:53:18 +00:00
Bits.h Move bit operations to a new file, ELF/Bits.h. 2017-10-26 21:37:17 +00:00
CallGraphSort.cpp [ELF] - Never use std::sort. 2018-04-24 09:55:39 +00:00
CallGraphSort.h [ELF] Add profile guided section layout 2018-04-17 23:30:05 +00:00
CMakeLists.txt [CMake] Fix BUILD_SHARED_LIBS regression due to r331405 2018-05-03 10:03:45 +00:00
Config.h [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
Driver.cpp [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
Driver.h Remove "--full-shutdown" and instead use an environment variable LLD_IN_TEST. 2018-02-16 23:41:48 +00:00
DriverUtils.cpp Handle --plugin-opt= options as alias options. 2018-05-22 02:53:11 +00:00
EhFrame.cpp [ELF] Simplify read32. NFC 2018-03-30 23:13:00 +00:00
EhFrame.h De-template EhReader. NFC. 2017-10-27 03:14:09 +00:00
Filesystem.cpp s/LLVM_ON_WIN32/_WIN32/, lld 2018-04-10 13:15:21 +00:00
Filesystem.h Add a missing #include. 2017-11-17 08:17:21 +00:00
GdbIndex.cpp s/uncompress/decompress/g. 2018-02-12 21:56:14 +00:00
GdbIndex.h [ELF] - Teach LLD to use information from .debug_str for error reporting. 2017-11-17 11:57:47 +00:00
ICF.cpp ELF: Do not ICF sections named with a C identifier. 2018-05-23 02:14:28 +00:00
ICF.h Consistent use of header file for ICF and MarkLive 2018-02-20 22:09:59 +00:00
InputFiles.cpp Remove a dead variable. 2018-06-09 00:54:18 +00:00
InputFiles.h [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
InputSection.cpp [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
InputSection.h ELF: Do not ICF two sections with different output sections. 2018-05-23 01:58:43 +00:00
LinkerScript.cpp Make ALIGN work with -r in linker scripts 2018-05-17 20:22:39 +00:00
LinkerScript.h [ELF] - Eliminate the AssertCommand. 2018-04-25 11:16:31 +00:00
LTO.cpp [ThinLTO/lld] Document constant bool ModuleSummaryIndex parameter (NFC) 2018-06-06 22:22:13 +00:00
LTO.h Improve error message for -thinlto-object-suffix-replace and simplify code. 2018-05-17 18:27:12 +00:00
MapFile.cpp Replace SharedSymbols with Defined when creating copy relocations. 2018-04-26 17:58:58 +00:00
MapFile.h Implement --cref. 2018-03-14 20:29:45 +00:00
MarkLive.cpp [ELF] - Do not crash when do --gc-sections for non-allocatable metadata sections. 2018-05-17 10:00:34 +00:00
MarkLive.h Consistent use of header file for ICF and MarkLive 2018-02-20 22:09:59 +00:00
Options.td [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
OutputSections.cpp [PPC64] Remove support for ELF V1 ABI in LLD 2018-05-04 15:09:49 +00:00
OutputSections.h [PPC64] Remove support for ELF V1 ABI in LLD 2018-05-04 15:09:49 +00:00
README.md Update the documents of the new LLD. 2016-03-12 06:06:40 +00:00
Relocations.cpp [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
Relocations.h [PPC64] Support R_PPC64_GOT_TLSLD16 relocations. 2018-05-31 18:44:12 +00:00
ScriptLexer.cpp Simplify script lexer. 2017-12-26 10:13:10 +00:00
ScriptLexer.h Move new lld's code to Common subdirectory. 2017-10-02 21:00:41 +00:00
ScriptParser.cpp [ELF] - Eliminate the AssertCommand. 2018-04-25 11:16:31 +00:00
ScriptParser.h [ELF] Support expressions with -defsym option 2017-11-04 02:03:58 +00:00
Symbols.cpp [ELF] Do not error for missing version when symbol has local version. 2018-05-14 10:13:56 +00:00
Symbols.h [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
SymbolTable.cpp Fix typo. 2018-05-21 18:12:46 +00:00
SymbolTable.h Make fetchIfLazy only fetch an object file. NFC. 2018-04-03 18:01:18 +00:00
SyntheticSections.cpp [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
SyntheticSections.h [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
Target.cpp [ELF] - Teach LLD to hint about -fdebug-types-section. 2018-03-21 09:19:34 +00:00
Target.h [PPC64] Add support for local-exec TLS model 2018-06-08 17:04:09 +00:00
Thunks.cpp ELF Thunks: fix build error: missing 'overrides' 2018-05-06 19:50:04 +00:00
Thunks.h ELF: Allow thunks to change size. NFCI. 2018-03-29 22:32:13 +00:00
Writer.cpp [ELF][MIPS] Multi-GOT implementation 2018-06-11 07:24:31 +00:00
Writer.h ELF: Do not ICF two sections with different output sections. 2018-05-23 01:58:43 +00:00

See docs/NewLLD.rst