From debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2be Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 1 May 2011 03:50:49 +0000 Subject: [PATCH] Simplify the handling of pcrel relocations on ELF. Now we do the right thing for all symbol differences and can drop the old EmitPCRelSymbolValue method. This also make getExprForFDESymbol on ELF equal to the one on MachO, and it can be made non-virtual. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130634 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAsmInfo.h | 7 +++++-- include/llvm/MC/MCAsmInfoDarwin.h | 2 -- include/llvm/MC/MCObjectStreamer.h | 2 +- include/llvm/MC/MCStreamer.h | 11 +---------- lib/MC/ELFObjectWriter.cpp | 6 +++++- lib/MC/MCAsmInfo.cpp | 16 ++++++++++++++-- lib/MC/MCAsmInfoDarwin.cpp | 11 ----------- lib/MC/MCAsmStreamer.cpp | 5 ++--- lib/MC/MCDwarf.cpp | 17 ++++++----------- lib/MC/MCLoggingStreamer.cpp | 4 ++-- lib/MC/MCNullStreamer.cpp | 2 +- lib/MC/MCObjectStreamer.cpp | 4 ++-- lib/MC/MCStreamer.cpp | 21 +++------------------ lib/Target/PTX/PTXMCAsmStreamer.cpp | 5 ++--- tools/lto/LTOModule.cpp | 2 +- 15 files changed, 45 insertions(+), 70 deletions(-) diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 566535ebacd..87331613945 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -326,10 +326,13 @@ namespace llvm { virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, MCStreamer &Streamer) const; - virtual const MCExpr * - getExprForFDESymbol(const MCSymbol *Sym, MCStreamer &Streamer) const; + const MCExpr * + getExprForFDESymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h index 634f163d84e..c85aa3da957 100644 --- a/include/llvm/MC/MCAsmInfoDarwin.h +++ b/include/llvm/MC/MCAsmInfoDarwin.h @@ -25,8 +25,6 @@ namespace llvm { struct MCAsmInfoDarwin : public MCAsmInfo { explicit MCAsmInfoDarwin(); - virtual const MCExpr * - getExprForFDESymbol(const MCSymbol *Sym, MCStreamer &Streamer) const; }; } diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 69a62d86108..8b0d87adabd 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -63,7 +63,7 @@ public: virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace); + unsigned AddrSpace); virtual void EmitULEB128Value(const MCExpr *Value); virtual void EmitSLEB128Value(const MCExpr *Value); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 7f529c67f06..b005c8bd886 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -50,9 +50,6 @@ namespace llvm { MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT - void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - bool isPCRel, unsigned AddrSpace); - std::vector FrameInfos; MCDwarfFrameInfo *getCurrentFrameInfo(); void EnsureValidFrame(); @@ -311,13 +308,10 @@ namespace llvm { /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) = 0; + unsigned AddrSpace) = 0; void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); - void EmitPCRelValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace = 0); - /// EmitIntValue - Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size, @@ -347,9 +341,6 @@ namespace llvm { void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace = 0); - void EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace = 0); - /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index b7d30cd46bf..23c6d4c1e4c 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1476,13 +1476,17 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { default: llvm_unreachable("invalid fixup kind!"); + + case FK_Data_8: Type = ELF::R_X86_64_PC64; break; + case FK_Data_4: Type = ELF::R_X86_64_PC32; break; + case FK_Data_2: Type = ELF::R_X86_64_PC16; break; + case FK_PCRel_8: assert(Modifier == MCSymbolRefExpr::VK_None); Type = ELF::R_X86_64_PC64; break; case X86::reloc_signed_4byte: case X86::reloc_riprel_4byte_movq_load: - case FK_Data_4: // FIXME? case X86::reloc_riprel_4byte: case FK_PCRel_4: switch (Modifier) { diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index b685c1a264c..541dd080acc 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -13,9 +13,11 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Dwarf.h" #include #include using namespace llvm; @@ -111,12 +113,22 @@ unsigned MCAsmInfo::getSLEB128Size(int Value) { const MCExpr * MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, MCStreamer &Streamer) const { - return getExprForFDESymbol(Sym, Streamer); + return getExprForFDESymbol(Sym, Encoding, Streamer); } const MCExpr * MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, + unsigned Encoding, MCStreamer &Streamer) const { - return MCSymbolRefExpr::Create(Sym, Streamer.getContext()); + if (!(Encoding & dwarf::DW_EH_PE_pcrel)) + return MCSymbolRefExpr::Create(Sym, Streamer.getContext()); + + MCContext &Context = Streamer.getContext(); + const MCExpr *Res = MCSymbolRefExpr::Create(Sym, Context); + MCSymbol *PCSym = Context.CreateTempSymbol(); + Streamer.EmitLabel(PCSym); + const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, Context); + return MCBinaryExpr::CreateSub(Res, PC, Context); } diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index fea1548f462..4dd1d44af5d 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -59,14 +59,3 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { DwarfUsesAbsoluteLabelForStmtList = false; DwarfUsesLabelOffsetForRanges = false; } - -const MCExpr * -MCAsmInfoDarwin::getExprForFDESymbol(const MCSymbol *Sym, - MCStreamer &Streamer) const { - MCContext &Context = Streamer.getContext(); - const MCExpr *Res = MCSymbolRefExpr::Create(Sym, Context); - MCSymbol *PCSym = Context.CreateTempSymbol(); - Streamer.EmitLabel(PCSym); - const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, Context); - return MCBinaryExpr::CreateSub(Res, PC, Context); -} diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index be7febfb178..8f9209d67f0 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -162,7 +162,7 @@ public: virtual void EmitBytes(StringRef Data, unsigned AddrSpace); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace); + unsigned AddrSpace); virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace = 0); @@ -566,9 +566,8 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, } void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) { + unsigned AddrSpace) { assert(getCurrentSection() && "Cannot emit contents before setting section!"); - assert(!isPCRel && "Cannot emit pc relative relocations!"); const char *Directive = 0; switch (Size) { default: break; diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 0296951490f..09a87fb0bfd 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -468,26 +468,21 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, MCContext &context = streamer.getContext(); const MCAsmInfo &asmInfo = context.getAsmInfo(); const MCExpr *v = asmInfo.getExprForFDESymbol(&symbol, + symbolEncoding, streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); - unsigned application = symbolEncoding & 0x70; - if (isa(v) && application == dwarf::DW_EH_PE_pcrel) - streamer.EmitPCRelValue(v, size); - else - streamer.EmitAbsValue(v, size); + streamer.EmitAbsValue(v, size); } static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding) { MCContext &context = streamer.getContext(); const MCAsmInfo &asmInfo = context.getAsmInfo(); - const MCExpr *v = asmInfo.getExprForPersonalitySymbol(&symbol, streamer); + const MCExpr *v = asmInfo.getExprForPersonalitySymbol(&symbol, + symbolEncoding, + streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); - unsigned application = symbolEncoding & 0x70; - if (isa(v) && application == dwarf::DW_EH_PE_pcrel) - streamer.EmitPCRelValue(v, size); - else - streamer.EmitValue(v, size); + streamer.EmitValue(v, size); } static const MachineLocation TranslateMachineLocation( diff --git a/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp index ae9f8a0c9a1..46ea9b844a6 100644 --- a/lib/MC/MCLoggingStreamer.cpp +++ b/lib/MC/MCLoggingStreamer.cpp @@ -154,9 +154,9 @@ public: } virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace){ + unsigned AddrSpace){ LogCall("EmitValue"); - return Child->EmitValueImpl(Value, Size, isPCRel, AddrSpace); + return Child->EmitValueImpl(Value, Size, AddrSpace); } virtual void EmitULEB128Value(const MCExpr *Value) { diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index d1c50e11426..f38b8223120 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -67,7 +67,7 @@ namespace { virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) {} + unsigned AddrSpace) {} virtual void EmitULEB128Value(const MCExpr *Value) {} virtual void EmitSLEB128Value(const MCExpr *Value) {} virtual void EmitGPRel32Value(const MCExpr *Value) {} diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index cb5eea7e50c..0f349d0d0b3 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -90,7 +90,7 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { } void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) { + unsigned AddrSpace) { assert(AddrSpace == 0 && "Address space must be 0!"); MCDataFragment *DF = getOrCreateDataFragment(); @@ -102,7 +102,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, } DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, - MCFixup::getKindForSize(Size, isPCRel))); + MCFixup::getKindForSize(Size, false))); DF->getContents().resize(DF->getContents().size() + Size, 0); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 55ccf56288f..fa245b11ade 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -114,30 +114,15 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { - EmitValueImpl(Value, Size, false, AddrSpace); -} - -void MCStreamer::EmitPCRelValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace) { - EmitValueImpl(Value, Size, true, AddrSpace); + EmitValueImpl(Value, Size, AddrSpace); } void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - bool isPCRel, unsigned AddrSpace) { - EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, isPCRel, + unsigned AddrSpace) { + EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace); } -void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace) { - EmitSymbolValue(Sym, Size, false, AddrSpace); -} - -void MCStreamer::EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace) { - EmitSymbolValue(Sym, Size, true, AddrSpace); -} - void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { report_fatal_error("unsupported directive in streamer"); } diff --git a/lib/Target/PTX/PTXMCAsmStreamer.cpp b/lib/Target/PTX/PTXMCAsmStreamer.cpp index 63bac790cc3..1574670b6e9 100644 --- a/lib/Target/PTX/PTXMCAsmStreamer.cpp +++ b/lib/Target/PTX/PTXMCAsmStreamer.cpp @@ -143,7 +143,7 @@ public: virtual void EmitBytes(StringRef Data, unsigned AddrSpace); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace); + unsigned AddrSpace); virtual void EmitULEB128Value(const MCExpr *Value); virtual void EmitSLEB128Value(const MCExpr *Value); virtual void EmitGPRel32Value(const MCExpr *Value); @@ -352,9 +352,8 @@ void PTXMCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { } void PTXMCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) { + unsigned AddrSpace) { assert(getCurrentSection() && "Cannot emit contents before setting section!"); - assert(!isPCRel && "Cannot emit pc relative relocations!"); const char *Directive = 0; switch (Size) { default: break; diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index d9f5fa55bad..8f2b1f48406 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -582,7 +582,7 @@ namespace { uint64_t Size, unsigned ByteAlignment) {} virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) {} + unsigned AddrSpace) {} virtual void EmitULEB128Value(const MCExpr *Value) {} virtual void EmitSLEB128Value(const MCExpr *Value) {} virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, -- 2.34.1