summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2016-04-24 01:03:57 +0000
committerDavide Italiano <davide@freebsd.org>2016-04-24 01:03:57 +0000
commitf59b0da654cdb80a138063f681045f40069765e7 (patch)
tree73c96f48ad245ea8830a68c1a3c816df2de85af4 /llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
parent02fa65209cc7f5803ea409365c87d9863838b996 (diff)
downloadbcm5719-llvm-f59b0da654cdb80a138063f681045f40069765e7.tar.gz
bcm5719-llvm-f59b0da654cdb80a138063f681045f40069765e7.zip
[MC/ELF] Implement support for GOTPCRELX/REX_GOTPCRELX.
The option to control the emission of the new relocations is -relax-relocations (blatantly copied from GNU as). It can't be enabled by default because it breaks relatively recent versions of ld.bfd/ld.gold (late 2015). llvm-svn: 267307
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 9f2d2738d1d..6fa479e4d7e 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -9,6 +9,7 @@
#include "MCTargetDesc/X86FixupKinds.h"
#include "MCTargetDesc/X86MCTargetDesc.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
@@ -84,10 +85,10 @@ static void checkIs32(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) {
"32 bit reloc applied to a field with a different size");
}
-static unsigned getRelocType64(MCContext &Ctx, const MCFixup &Fixup,
+static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
MCSymbolRefExpr::VariantKind Modifier,
- X86_64RelType Type, bool IsPCRel) {
- SMLoc Loc = Fixup.getLoc();
+ X86_64RelType Type, bool IsPCRel,
+ unsigned Kind) {
switch (Modifier) {
default:
llvm_unreachable("Unimplemented");
@@ -173,7 +174,19 @@ static unsigned getRelocType64(MCContext &Ctx, const MCFixup &Fixup,
return ELF::R_X86_64_PLT32;
case MCSymbolRefExpr::VK_GOTPCREL:
checkIs32(Ctx, Loc, Type);
- return ELF::R_X86_64_GOTPCREL;
+ // Older versions of ld.bfd/ld.gold/lld
+ // do not support GOTPCRELX/REX_GOTPCRELX,
+ // and we want to keep back-compatibility.
+ if (!Ctx.getAsmInfo()->canRelaxRelocations())
+ return ELF::R_X86_64_GOTPCREL;
+ switch (Kind) {
+ default:
+ return ELF::R_X86_64_GOTPCREL;
+ case X86::reloc_riprel_4byte:
+ return ELF::R_X86_64_GOTPCRELX;
+ case X86::reloc_riprel_4byte_movq_load:
+ return ELF::R_X86_64_REX_GOTPCRELX;
+ }
}
}
@@ -259,7 +272,8 @@ unsigned X86ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
X86_64RelType Type = getType64(Fixup.getKind(), Modifier, IsPCRel);
if (getEMachine() == ELF::EM_X86_64)
- return getRelocType64(Ctx, Fixup, Modifier, Type, IsPCRel);
+ return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel,
+ Fixup.getKind());
assert((getEMachine() == ELF::EM_386 || getEMachine() == ELF::EM_IAMCU) &&
"Unsupported ELF machine type.");
OpenPOWER on IntegriCloud