diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCTargetMachine.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCTargetMachine.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 8079c6e..c7f7882 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -194,4 +194,31 @@ bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, return false; } - +/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte, +/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA +/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte +/// pointer by default. However, some systems may require a different size due +/// to bugs or other conditions. We will default to a 4-byte encoding unless the +/// system tells us otherwise. +/// +/// The issue is when the CIE says their is an LSDA. That mandates that every +/// FDE have an LSDA slot. But if the function does not need an LSDA. There +/// needs to be some way to signify there is none. The LSDA is encoded as +/// pc-rel. But you don't look for some magic value after adding the pc. You +/// have to look for a zero before adding the pc. The problem is that the size +/// of the zero to look for depends on the encoding. The unwinder bug in SL is +/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8 +/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are +/// non-zero so it goes ahead and then reads the value based on the encoding. +/// But if you use sdata4 and there is no LSDA, then the test for zero gives a +/// false negative and the unwinder thinks there is an LSDA. +/// +/// FIXME: This call-back isn't good! We should be using the correct encoding +/// regardless of the system. However, there are some systems which have bugs +/// that prevent this from occuring. +DwarfLSDAEncoding::Encoding PPCTargetMachine::getLSDAEncoding() const { + if (Subtarget.isDarwin() && Subtarget.getDarwinVers() != 10) + return DwarfLSDAEncoding::Default; + + return DwarfLSDAEncoding::EightByte; +} |