diff options
author | Davide Italiano <davide@freebsd.org> | 2016-04-24 01:03:57 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2016-04-24 01:03:57 +0000 |
commit | f59b0da654cdb80a138063f681045f40069765e7 (patch) | |
tree | 73c96f48ad245ea8830a68c1a3c816df2de85af4 /llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp | |
parent | 02fa65209cc7f5803ea409365c87d9863838b996 (diff) | |
download | bcm5719-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.cpp | 24 |
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."); |