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 | 2ac8355ecd187bcf86aeae9ae0c8a92b37daf8b1 (patch) | |
tree | 753ca21bd3bcd0c3963e5fd001475888307471f2 /llvm/lib/MC | |
parent | 84bd73c52744b33955a85174b8912d001de604a3 (diff) | |
download | bcm5719-llvm-2ac8355ecd187bcf86aeae9ae0c8a92b37daf8b1.tar.gz bcm5719-llvm-2ac8355ecd187bcf86aeae9ae0c8a92b37daf8b1.zip |
Add support for the same encodings of the personality function that gnu as
supports.
llvm-svn: 122577
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/MC/TargetAsmBackend.cpp | 3 |
6 files changed, 88 insertions, 31 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 5ff12bc01f0..88c7200734f 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/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/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index a171ba120be..ee1342937f5 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/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/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 75c844f09ec..9d26bec824e 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/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/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index cf11ca9c5a8..450a927a2ad 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/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/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 68146de9c05..399b4baded1 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/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/llvm/lib/MC/TargetAsmBackend.cpp b/llvm/lib/MC/TargetAsmBackend.cpp index e0653d05ef0..b13aa1d97c6 100644 --- a/llvm/lib/MC/TargetAsmBackend.cpp +++ b/llvm/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]) && |