aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-27 00:36:05 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-27 00:36:05 +0000
commit3a83c40ab61d5ca624f2bbadd70237c6adbdb304 (patch)
treef0e3c71d1852277f7ed6d945f96c8493bc395101 /lib/MC
parentdef548f9a0efa6e997a68ac2d77cb0ef574b7d43 (diff)
Add support for the same encodings of the personality function that gnu as
supports. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122577 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/ELFObjectWriter.cpp50
-rw-r--r--lib/MC/MCAsmStreamer.cpp9
-rw-r--r--lib/MC/MCDwarf.cpp51
-rw-r--r--lib/MC/MCParser/AsmParser.cpp2
-rw-r--r--lib/MC/MCStreamer.cpp4
-rw-r--r--lib/MC/TargetAsmBackend.cpp3
6 files changed, 88 insertions, 31 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 5ff12bc01f..88c7200734 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -1604,26 +1604,41 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
unsigned Type;
if (is64Bit()) {
if (IsPCRel) {
- switch (Modifier) {
- default:
- llvm_unreachable("Unimplemented");
- case MCSymbolRefExpr::VK_None:
- Type = ELF::R_X86_64_PC32;
- break;
- case MCSymbolRefExpr::VK_PLT:
- Type = ELF::R_X86_64_PLT32;
- break;
- case MCSymbolRefExpr::VK_GOTPCREL:
- Type = ELF::R_X86_64_GOTPCREL;
+ switch ((unsigned)Fixup.getKind()) {
+ default: llvm_unreachable("invalid fixup kind!");
+ case FK_PCRel_8:
+ assert(Modifier == MCSymbolRefExpr::VK_None);
+ Type = ELF::R_X86_64_PC64;
break;
- case MCSymbolRefExpr::VK_GOTTPOFF:
- Type = ELF::R_X86_64_GOTTPOFF;
+ case FK_Data_4: // FIXME?
+ case X86::reloc_riprel_4byte:
+ case FK_PCRel_4:
+ switch (Modifier) {
+ default:
+ llvm_unreachable("Unimplemented");
+ case MCSymbolRefExpr::VK_None:
+ Type = ELF::R_X86_64_PC32;
+ break;
+ case MCSymbolRefExpr::VK_PLT:
+ Type = ELF::R_X86_64_PLT32;
+ break;
+ case MCSymbolRefExpr::VK_GOTPCREL:
+ Type = ELF::R_X86_64_GOTPCREL;
+ break;
+ case MCSymbolRefExpr::VK_GOTTPOFF:
+ Type = ELF::R_X86_64_GOTTPOFF;
break;
- case MCSymbolRefExpr::VK_TLSGD:
- Type = ELF::R_X86_64_TLSGD;
+ case MCSymbolRefExpr::VK_TLSGD:
+ Type = ELF::R_X86_64_TLSGD;
+ break;
+ case MCSymbolRefExpr::VK_TLSLD:
+ Type = ELF::R_X86_64_TLSLD;
+ break;
+ }
break;
- case MCSymbolRefExpr::VK_TLSLD:
- Type = ELF::R_X86_64_TLSLD;
+ case FK_PCRel_2:
+ assert(Modifier == MCSymbolRefExpr::VK_None);
+ Type = ELF::R_X86_64_PC16;
break;
}
} else {
@@ -1631,7 +1646,6 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
default: llvm_unreachable("invalid fixup kind!");
case FK_Data_8: Type = ELF::R_X86_64_64; break;
case X86::reloc_signed_4byte:
- case FK_PCRel_4:
assert(isInt<32>(Target.getConstant()));
switch (Modifier) {
default:
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index a171ba120b..ee1342937f 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -189,7 +189,7 @@ public:
virtual bool EmitCFIDefCfaOffset(int64_t Offset);
virtual bool EmitCFIDefCfaRegister(int64_t Register);
virtual bool EmitCFIOffset(int64_t Register, int64_t Offset);
- virtual bool EmitCFIPersonality(const MCSymbol *Sym);
+ virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
virtual bool EmitCFILsda(const MCSymbol *Sym);
virtual void EmitInstruction(const MCInst &Inst);
@@ -758,11 +758,12 @@ bool MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
return false;
}
-bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym) {
- if (this->MCStreamer::EmitCFIPersonality(Sym))
+bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
+ unsigned Encoding) {
+ if (this->MCStreamer::EmitCFIPersonality(Sym, Encoding))
return true;
- OS << ".cfi_personality 0, " << *Sym;
+ OS << ".cfi_personality " << Encoding << ", " << *Sym;
EmitEOL();
return false;
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 75c844f09e..9d26bec824 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -509,7 +509,8 @@ static void EmitFrameMoves(MCStreamer &streamer,
}
static const MCSymbol &EmitCIE(MCStreamer &streamer,
- const MCSymbol *personality) {
+ const MCSymbol *personality,
+ unsigned personalityEncoding) {
MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
const MCSection &section = *asmInfo.getEHFrameSection();
@@ -559,9 +560,44 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer,
streamer.EmitLabel(augmentationStart);
if (personality) {
// Personality Encoding
- streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1);
+ streamer.EmitIntValue(personalityEncoding, 1);
// Personality
- streamer.EmitSymbolValue(personality, asmInfo.getPointerSize());
+ unsigned format = personalityEncoding & 0x0f;
+ unsigned application = personalityEncoding & 0xf0;
+ unsigned size;
+ switch (format) {
+ default:
+ assert(0 && "Unknown Encoding");
+ break;
+ case dwarf::DW_EH_PE_absptr:
+ case dwarf::DW_EH_PE_signed:
+ size = asmInfo.getPointerSize();
+ break;
+ case dwarf::DW_EH_PE_udata2:
+ case dwarf::DW_EH_PE_sdata2:
+ size = 2;
+ break;
+ case dwarf::DW_EH_PE_udata4:
+ case dwarf::DW_EH_PE_sdata4:
+ size = 4;
+ break;
+ case dwarf::DW_EH_PE_udata8:
+ case dwarf::DW_EH_PE_sdata8:
+ size = 8;
+ break;
+ }
+ switch (application) {
+ default:
+ assert(0 && "Unknown Encoding");
+ break;
+ case 0:
+ case dwarf::DW_EH_PE_indirect:
+ streamer.EmitSymbolValue(personality, size);
+ break;
+ case dwarf::DW_EH_PE_pcrel:
+ streamer.EmitPCRelSymbolValue(personality, size);
+ break;
+ }
}
// Encoding of the FDE pointers
streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1);
@@ -620,13 +656,16 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) {
const MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
MCSymbol *fdeEnd = NULL;
- DenseMap<const MCSymbol*, const MCSymbol*> Personalities;
+ typedef std::pair<const MCSymbol*, unsigned> personalityKey;
+ DenseMap<personalityKey, const MCSymbol*> personalities;
for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
- const MCSymbol *&cieStart = Personalities[frame.Personality];
+ personalityKey key(frame.Personality, frame.PersonalityEncoding);
+ const MCSymbol *&cieStart = personalities[key];
if (!cieStart)
- cieStart = &EmitCIE(streamer, frame.Personality);
+ cieStart = &EmitCIE(streamer, frame.Personality,
+ frame.PersonalityEncoding);
fdeEnd = EmitFDE(streamer, *cieStart, frame);
if (i != n - 1)
streamer.EmitLabel(fdeEnd);
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index cf11ca9c5a..450a927a2a 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -2254,7 +2254,7 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
if (IDVal == ".cfi_personality")
- return getStreamer().EmitCFIPersonality(Sym);
+ return getStreamer().EmitCFIPersonality(Sym, Encoding);
else {
assert(IDVal == ".cfi_lsda");
return getStreamer().EmitCFILsda(Sym);
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 68146de9c0..399b4baded 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -187,10 +187,12 @@ bool MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
return false;
}
-bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym) {
+bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
+ unsigned Encoding) {
EnsureValidFrame();
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
CurFrame->Personality = Sym;
+ CurFrame->PersonalityEncoding = Encoding;
return false;
}
diff --git a/lib/MC/TargetAsmBackend.cpp b/lib/MC/TargetAsmBackend.cpp
index e0653d05ef..b13aa1d97c 100644
--- a/lib/MC/TargetAsmBackend.cpp
+++ b/lib/MC/TargetAsmBackend.cpp
@@ -27,7 +27,8 @@ TargetAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{ "FK_Data_8", 0, 64, 0 },
{ "FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel },
{ "FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
- { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel }
+ { "FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
+ { "FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel }
};
assert(Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&