diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-27 00:36:05 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-27 00:36:05 +0000 |
commit | 3a83c40ab61d5ca624f2bbadd70237c6adbdb304 (patch) | |
tree | f0e3c71d1852277f7ed6d945f96c8493bc395101 /lib/MC | |
parent | def548f9a0efa6e997a68ac2d77cb0ef574b7d43 (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.cpp | 50 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 9 | ||||
-rw-r--r-- | lib/MC/MCDwarf.cpp | 51 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 4 | ||||
-rw-r--r-- | lib/MC/TargetAsmBackend.cpp | 3 |
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 §ion = *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]) && |