diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2016-10-21 07:22:30 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2016-10-21 07:22:30 +0000 |
commit | bed04bf1df9d442f4a8e4d914d0dcd9155f2b931 (patch) | |
tree | 57eed9ee55e416965099b4be23be081c3a8f03aa /lld/ELF/Relocations.cpp | |
parent | c1db0db8647110c89924e6a29afe6455ed61a2a5 (diff) | |
download | bcm5719-llvm-bed04bf1df9d442f4a8e4d914d0dcd9155f2b931.tar.gz bcm5719-llvm-bed04bf1df9d442f4a8e4d914d0dcd9155f2b931.zip |
[ELF][MIPS] Put local GOT entries accessed via a 16-bit index first
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
Diffstat (limited to 'lld/ELF/Relocations.cpp')
-rw-r--r-- | lld/ELF/Relocations.cpp | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 2f7757ae6f4..62f81f729f8 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -62,10 +62,11 @@ namespace elf { static bool refersToGotEntry(RelExpr Expr) { return Expr == R_GOT || Expr == R_GOT_OFF || Expr == R_MIPS_GOT_LOCAL_PAGE || - Expr == R_MIPS_GOT_OFF || Expr == R_MIPS_TLSGD || - Expr == R_MIPS_TLSLD || Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC || - Expr == R_GOT_FROM_END || Expr == R_TLSGD || Expr == R_TLSGD_PC || - Expr == R_TLSDESC || Expr == R_TLSDESC_PAGE; + Expr == R_MIPS_GOT_OFF || Expr == R_MIPS_GOT_OFF32 || + Expr == R_MIPS_TLSGD || Expr == R_MIPS_TLSLD || + Expr == R_GOT_PAGE_PC || Expr == R_GOT_PC || Expr == R_GOT_FROM_END || + Expr == R_TLSGD || Expr == R_TLSGD_PC || Expr == R_TLSDESC || + Expr == R_TLSDESC_PAGE; } static bool isPreemptible(const SymbolBody &Body, uint32_t Type) { @@ -303,11 +304,11 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type, const SymbolBody &Body) { // These expressions always compute a constant if (E == R_SIZE || E == R_GOT_FROM_END || E == R_GOT_OFF || - E == R_MIPS_GOT_LOCAL_PAGE || E == R_MIPS_GOT_OFF || E == R_MIPS_TLSGD || - E == R_GOT_PAGE_PC || E == R_GOT_PC || E == R_PLT_PC || - E == R_TLSGD_PC || E == R_TLSGD || E == R_PPC_PLT_OPD || - E == R_TLSDESC_CALL || E == R_TLSDESC_PAGE || E == R_HINT || - E == R_THUNK_PC || E == R_THUNK_PLT_PC) + E == R_MIPS_GOT_LOCAL_PAGE || E == R_MIPS_GOT_OFF || + E == R_MIPS_GOT_OFF32 || E == R_MIPS_TLSGD || E == R_GOT_PAGE_PC || + E == R_GOT_PC || E == R_PLT_PC || E == R_TLSGD_PC || E == R_TLSGD || + E == R_PPC_PLT_OPD || E == R_TLSDESC_CALL || E == R_TLSDESC_PAGE || + E == R_HINT || E == R_THUNK_PC || E == R_THUNK_PLT_PC) return true; // These never do, except if the entire file is position dependent or if |