summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-04-27 12:25:22 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-04-27 12:25:22 +0000
commit15cec298e64872b693430214980a822ee2044a5d (patch)
treeafa02d598cd98f16abb85d24619fdeb4e36a8885
parent520ed3a621f4fa9a67a66039996657ba5dc71180 (diff)
downloadbcm5719-llvm-15cec298e64872b693430214980a822ee2044a5d.tar.gz
bcm5719-llvm-15cec298e64872b693430214980a822ee2044a5d.zip
Represent TOC relative relocations as GOTREL.
That way we only need to subtract the offset is relocateOne. llvm-svn: 267702
-rw-r--r--lld/ELF/Target.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 1d1bb35ab7a..6f6f9cccf63 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -822,6 +822,8 @@ PPC64TargetInfo::PPC64TargetInfo() {
VAStart = 0x10000000;
}
+static uint64_t PPC64TocOffset = 0x8000;
+
uint64_t getPPC64TocBase() {
// The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
// TOC starts where the first of these sections starts. We always create a
@@ -833,13 +835,20 @@ uint64_t getPPC64TocBase() {
// thus permitting a full 64 Kbytes segment. Note that the glibc startup
// code (crt1.o) assumes that you can get from the TOC base to the
// start of the .toc section with only a single (signed) 16-bit relocation.
- return TocVA + 0x8000;
+ return TocVA + PPC64TocOffset;
}
RelExpr PPC64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
switch (Type) {
default:
return R_ABS;
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_LO_DS:
+ return R_GOTREL;
case R_PPC64_TOC:
return R_PPC_TOC;
case R_PPC64_REL24:
@@ -880,17 +889,17 @@ bool PPC64TargetInfo::isRelRelative(uint32_t Type) const {
void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
uint64_t Val) const {
- uint64_t TB = getPPC64TocBase();
+ uint64_t TO = PPC64TocOffset;
- // For a TOC-relative relocation, adjust the addend and proceed in terms of
- // the corresponding ADDR16 relocation type.
+ // For a TOC-relative relocation, proceed in terms of the corresponding
+ // ADDR16 relocation type.
switch (Type) {
- case R_PPC64_TOC16: Type = R_PPC64_ADDR16; Val -= TB; break;
- case R_PPC64_TOC16_DS: Type = R_PPC64_ADDR16_DS; Val -= TB; break;
- case R_PPC64_TOC16_HA: Type = R_PPC64_ADDR16_HA; Val -= TB; break;
- case R_PPC64_TOC16_HI: Type = R_PPC64_ADDR16_HI; Val -= TB; break;
- case R_PPC64_TOC16_LO: Type = R_PPC64_ADDR16_LO; Val -= TB; break;
- case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; Val -= TB; break;
+ case R_PPC64_TOC16: Type = R_PPC64_ADDR16; Val -= TO; break;
+ case R_PPC64_TOC16_DS: Type = R_PPC64_ADDR16_DS; Val -= TO; break;
+ case R_PPC64_TOC16_HA: Type = R_PPC64_ADDR16_HA; Val -= TO; break;
+ case R_PPC64_TOC16_HI: Type = R_PPC64_ADDR16_HI; Val -= TO; break;
+ case R_PPC64_TOC16_LO: Type = R_PPC64_ADDR16_LO; Val -= TO; break;
+ case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; Val -= TO; break;
default: break;
}
OpenPOWER on IntegriCloud