diff options
| author | Fangrui Song <maskray@google.com> | 2019-05-07 04:26:05 +0000 |
|---|---|---|
| committer | Fangrui Song <maskray@google.com> | 2019-05-07 04:26:05 +0000 |
| commit | 912251e82f09b586712aae0441a9822f5cc37947 (patch) | |
| tree | ac74ab03e2072c2035e604d2a18a6753d30c6f85 /lld/ELF/InputSection.cpp | |
| parent | c6d445f9c1cb08e901c906a8772accc04d62562d (diff) | |
| download | bcm5719-llvm-912251e82f09b586712aae0441a9822f5cc37947.tar.gz bcm5719-llvm-912251e82f09b586712aae0441a9822f5cc37947.zip | |
[PPC64] toc-indirect to toc-relative relaxation
This is based on D54720 by Sean Fertile.
When accessing a global symbol which is not defined in the translation unit,
compilers will generate instructions that load the address from the toc entry.
If the symbol is defined, non-preemptable, and addressable with a 32-bit
signed offset from the toc pointer, the address can be computed
directly. e.g.
addis 3, 2, .LC0@toc@ha # R_PPC64_TOC16_HA
ld 3, .LC0@toc@l(3) # R_PPC64_TOC16_LO_DS, load the address from a .toc entry
ld/lwa 3, 0(3) # load the value from the address
.section .toc,"aw",@progbits
.LC0: .tc var[TC],var
can be relaxed to
addis 3,2,var@toc@ha # this may be relaxed to a nop,
addi 3,3,var@toc@l # then this becomes addi 3,2,var@toc
ld/lwa 3, 0(3) # load the value from the address
We can delete the test ppc64-got-indirect.s as its purpose is covered by
newly added ppc64-toc-relax.s and ppc64-toc-relax-constants.s
Reviewed By: ruiu, sfertile
Differential Revision: https://reviews.llvm.org/D60958
llvm-svn: 360112
Diffstat (limited to 'lld/ELF/InputSection.cpp')
| -rw-r--r-- | lld/ELF/InputSection.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index eb67592c0c3..85c8ffeb7ea 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -631,6 +631,7 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A, case R_GOTPLTONLY_PC: return In.GotPlt->getVA() + A - P; case R_GOTREL: + case R_PPC64_RELAX_TOC: return Sym.getVA(A) - In.Got->getVA(); case R_GOTPLTREL: return Sym.getVA(A) - In.GotPlt->getVA(); @@ -894,7 +895,11 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) { switch (Expr) { case R_RELAX_GOT_PC: case R_RELAX_GOT_PC_NOPIC: - Target->relaxGot(BufLoc, TargetVA); + Target->relaxGot(BufLoc, Type, TargetVA); + break; + case R_PPC64_RELAX_TOC: + if (!tryRelaxPPC64TocIndirection(Type, Rel, BufLoc)) + Target->relocateOne(BufLoc, Type, TargetVA); break; case R_RELAX_TLS_IE_TO_LE: Target->relaxTlsIeToLe(BufLoc, Type, TargetVA); |

