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.

llvm-svn: 130634
This commit is contained in:
Rafael Espindola 2011-05-01 03:50:49 +00:00
parent ca87290f36
commit fd05785324
15 changed files with 45 additions and 70 deletions

View File

@ -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;

View File

@ -25,8 +25,6 @@ namespace llvm {
struct MCAsmInfoDarwin : public MCAsmInfo {
explicit MCAsmInfoDarwin();
virtual const MCExpr *
getExprForFDESymbol(const MCSymbol *Sym, MCStreamer &Streamer) const;
};
}

View File

@ -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);

View File

@ -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<MCDwarfFrameInfo> 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.
///

View File

@ -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) {

View File

@ -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 <cctype>
#include <cstring>
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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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<MCSymbolRefExpr>(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<MCSymbolRefExpr>(v) && application == dwarf::DW_EH_PE_pcrel)
streamer.EmitPCRelValue(v, size);
else
streamer.EmitValue(v, size);
streamer.EmitValue(v, size);
}
static const MachineLocation TranslateMachineLocation(

View File

@ -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) {

View File

@ -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) {}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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;

View File

@ -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,