Skip to content

Commit b477f7a

Browse files
committed
auto merge of #10013 : bdash/rust/mavericks-unwinding, r=alexcrichton
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.
2 parents ae0905a + fd8c06e commit b477f7a

File tree

4 files changed

+23
-13
lines changed

4 files changed

+23
-13
lines changed

mk/platform.mk

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
204204
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
205205
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64
206206
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti
207-
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -Wl,-no_compact_unwind -m64
207+
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
208208
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
209209
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
210210
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
@@ -230,7 +230,7 @@ CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
230230
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
231231
CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386
232232
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti
233-
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -Wl,-no_compact_unwind -m32
233+
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
234234
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
235235
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
236236
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=

src/librustc/back/link.rs

-8
Original file line numberDiff line numberDiff line change
@@ -1112,14 +1112,6 @@ pub fn link_args(sess: Session,
11121112
~"-Wl,-rpath,/usr/local/lib/gcc44"]);
11131113
}
11141114

1115-
// OS X 10.6 introduced 'compact unwind info', which is produced by the
1116-
// linker from the dwarf unwind info. Unfortunately, it does not seem to
1117-
// understand how to unwind our __morestack frame, so we have to turn it
1118-
// off. This has impacted some other projects like GHC.
1119-
if sess.targ_cfg.os == session::OsMacos {
1120-
args.push(~"-Wl,-no_compact_unwind");
1121-
}
1122-
11231115
// Stack growth requires statically linking a __morestack function
11241116
args.push(~"-lmorestack");
11251117

src/rt/arch/i386/morestack.S

+12-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@
6262
is that OS X 10.6+ uses its own 'compact unwind info',
6363
an undocumented format generated by the linker from
6464
the DWARF CFI. This compact unwind info doesn't correctly
65-
capture the nuance of the __morestack frame, and as a
66-
result all of our linking on OS X uses the -no_compact_unwind
67-
flag.
65+
capture the nuance of the __morestack frame, so we need to
66+
prevent the linker from attempting to convert its DWARF unwind
67+
information.
6868
*/
6969

7070
.text
@@ -118,6 +118,15 @@ MORESTACK:
118118
// FIXME(#9854) these cfi directives don't work on windows.
119119

120120
pushl %ebp
121+
122+
#if defined(__APPLE__)
123+
// The pattern of the return address being saved twice to the same location
124+
// tells the OS X linker that it should not attempt to convert the DWARF
125+
// unwind information to the compact format.
126+
.cfi_offset %eip, -4
127+
.cfi_offset %eip, -4
128+
#endif
129+
121130
// The CFA is 20 bytes above the register that it is
122131
// associated with for this frame (which will be %ebp)
123132
.cfi_def_cfa_offset 20

src/rt/arch/x86_64/morestack.S

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ MORESTACK:
4343
// bytes greater than a normal frame, to allow the unwinder
4444
// to skip the partial frame of the original function.
4545
.cfi_def_cfa_offset 24
46+
47+
#if defined(__APPLE__)
48+
// The pattern of the return address being saved twice to the same location
49+
// tells the OS X linker that it should not attempt to convert the DWARF
50+
// unwind information to the compact format.
51+
.cfi_offset %rip, -8
52+
.cfi_offset %rip, -8
53+
#endif
54+
4655
// %rbp is -24 bytes from the CFA
4756
.cfi_offset %rbp, -24
4857
movq %rsp, %rbp

0 commit comments

Comments
 (0)