diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 5621e53270b..74dd11fd035 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -81,6 +81,14 @@ namespace CodeGenOpt { }; } +// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes. +namespace DwarfLSDAEncoding { + enum Encoding { + Default, + FourByte, + EightByte + }; +} //===----------------------------------------------------------------------===// /// @@ -192,6 +200,12 @@ public: /// is false. static void setAsmVerbosityDefault(bool); + /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are + /// 4-byte, 8-byte, and target default. + virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const { + return DwarfLSDAEncoding::Default; + } + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit. enum CodeGenFileType { diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index d01f300990c..c1d3f4900c3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -283,17 +283,28 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { if (MMI->getPersonalities()[0] != NULL) { bool is4Byte = TD->getPointerSize() == sizeof(int32_t); - Asm->EmitULEB128Bytes(is4Byte ? 4 : 8); - Asm->EOL("Augmentation size"); + if (Asm->TM.getLSDAEncoding() == DwarfLSDAEncoding::FourByte) { + Asm->EmitULEB128Bytes(4); + Asm->EOL("Augmentation size"); - if (EHFrameInfo.hasLandingPads) - EmitReference("exception", EHFrameInfo.Number, true, false); - else { - if (is4Byte) - Asm->EmitInt32((int)0); + if (EHFrameInfo.hasLandingPads) + EmitReference("exception", EHFrameInfo.Number, true, true); else - Asm->EmitInt64((int)0); + Asm->EmitInt32((int)0); + } else { + Asm->EmitULEB128Bytes(is4Byte ? 4 : 8); + Asm->EOL("Augmentation size"); + + if (EHFrameInfo.hasLandingPads) { + EmitReference("exception", EHFrameInfo.Number, true, false); + } else { + if (is4Byte) + Asm->EmitInt32((int)0); + else + Asm->EmitInt64((int)0); + } } + Asm->EOL("Language Specific Data Area"); } else { Asm->EmitULEB128Bytes(0); diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 962f0f7be9a..ea21676c3b2 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -249,3 +249,10 @@ void X86TargetMachine::setCodeModelForJIT() { else setCodeModel(CodeModel::Small); } + +DwarfLSDAEncoding::Encoding X86TargetMachine::getLSDAEncoding() const { + if (Subtarget.isTargetDarwin() && Subtarget.getDarwinVers() > 10) + return DwarfLSDAEncoding::FourByte; + + return DwarfLSDAEncoding::Default; +} diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h index 6183e917157..c42aa89ff9b 100644 --- a/lib/Target/X86/X86TargetMachine.h +++ b/lib/Target/X86/X86TargetMachine.h @@ -62,6 +62,8 @@ public: return Subtarget.isTargetELF() ? &ELFWriterInfo : 0; } + virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const; + // Set up the pass pipeline. virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); virtual bool addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel);