]> git.lizzy.rs Git - rust.git/commitdiff
Fix unwinding on OS X 10.9.
authorMark Rowe <mrowe@bdash.net.nz>
Tue, 22 Oct 2013 09:50:52 +0000 (02:50 -0700)
committerMark Rowe <mrowe@bdash.net.nz>
Tue, 22 Oct 2013 10:02:25 +0000 (03:02 -0700)
OS X 10.9's linker has a bug that results in it failing to preserve
DWARF unwind information when passed the -no_compact_unwind flag.
This flag is passed on OS X because the unwind information for
__morestack cannot be represented by the compact unwind format.

We can work around this problem by using a more targeted approach
to disabling compact unwind information. The OS X linker looks for
a particular pattern in the DWARF unwind information and will not
attempt to convert the unwind information to the compact format.
The pattern in question is the return address register being saved
twice to the same location.

Fixes #6849.

mk/platform.mk
src/librustc/back/link.rs
src/rt/arch/i386/morestack.S
src/rt/arch/x86_64/morestack.S

index 7ba8f77ef980eb348a0faacafbf2c434823788e0..27fe373b761eafa8cfc42631c03686b3b8aba4a3 100644 (file)
@@ -204,7 +204,7 @@ CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
 CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
 CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64
 CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti
-CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread  -framework CoreServices -Wl,-no_compact_unwind -m64
+CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m64
 CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
 CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
 CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
@@ -230,7 +230,7 @@ CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
 CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
 CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386
 CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti
-CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread  -framework CoreServices -Wl,-no_compact_unwind -m32
+CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread  -framework CoreServices -m32
 CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
 CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
 CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
index 7c2856b75776af9b587822794a9b86d2140ab1a4..ad74aa68dd3e40f77ac9641b76856d4e53d289bc 100644 (file)
@@ -1112,14 +1112,6 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
                        ~"-Wl,-rpath,/usr/local/lib/gcc44"]);
     }
 
-    // OS X 10.6 introduced 'compact unwind info', which is produced by the
-    // linker from the dwarf unwind info. Unfortunately, it does not seem to
-    // understand how to unwind our __morestack frame, so we have to turn it
-    // off. This has impacted some other projects like GHC.
-    if sess.targ_cfg.os == session::OsMacos {
-        args.push(~"-Wl,-no_compact_unwind");
-    }
-
     // Stack growth requires statically linking a __morestack function
     args.push(~"-lmorestack");
 
index 25f907f479caa6148fbbfdebdb523f5b1be1b03a..2f03251e54ae5e8a26f878c42beb31d0803ac85b 100644 (file)
@@ -62,9 +62,9 @@
        is that OS X 10.6+ uses its own 'compact unwind info',
        an undocumented format generated by the linker from
        the DWARF CFI. This compact unwind info doesn't correctly
-       capture the nuance of the __morestack frame, and as a
-       result all of our linking on OS X uses the -no_compact_unwind
-       flag.
+       capture the nuance of the __morestack frame, so we need to
+       prevent the linker from attempting to convert its DWARF unwind
+       information.
 */
 
 .text
@@ -118,6 +118,15 @@ MORESTACK:
         // FIXME(#9854) these cfi directives don't work on windows.
 
        pushl %ebp
+
+#if defined(__APPLE__)
+       // The pattern of the return address being saved twice to the same location
+       // tells the OS X linker that it should not attempt to convert the DWARF
+       // unwind information to the compact format.
+       .cfi_offset %eip, -4
+       .cfi_offset %eip, -4
+#endif
+
        // The CFA is 20 bytes above the register that it is
        // associated with for this frame (which will be %ebp)
        .cfi_def_cfa_offset 20
index d248d79d12147b623fc4d008e33de4c4d5b1bc6b..6ccabbf5994d5f4549f870540ec3cb4b5a0968bd 100644 (file)
@@ -43,6 +43,15 @@ MORESTACK:
        // bytes greater than a normal frame, to allow the unwinder
        // to skip the partial frame of the original function.
        .cfi_def_cfa_offset 24
+
+#if defined(__APPLE__)
+       // The pattern of the return address being saved twice to the same location
+       // tells the OS X linker that it should not attempt to convert the DWARF
+       // unwind information to the compact format.
+       .cfi_offset %rip, -8
+       .cfi_offset %rip, -8
+#endif
+
        // %rbp is -24 bytes from the CFA
        .cfi_offset %rbp, -24
        movq %rsp, %rbp