Skip to content

Commit 8990708

Browse files
committed
auto merge of #11301 : vadimcn/rust/fix-android, r=brson
This fixes stack unwinding on targets using ARM EHABI. closes #11147
2 parents b432e82 + cefb2c7 commit 8990708

File tree

3 files changed

+128
-47
lines changed

3 files changed

+128
-47
lines changed

mk/platform.mk

+14
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-l
157157
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
158158
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
159159
CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
160+
CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
160161
CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
161162
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-linux-gnu =
162163
CFG_LLVM_BUILD_ENV_x86_64-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
@@ -184,6 +185,7 @@ CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-lis
184185
CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
185186
CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
186187
CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
188+
CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
187189
CFG_INSTALL_NAME_i686-unknown-linux-gnu =
188190
CFG_LIBUV_LINK_FLAGS_i686-unknown-linux-gnu =
189191
CFG_LLVM_BUILD_ENV_i686-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
@@ -213,6 +215,7 @@ CFG_GCCISH_DEF_FLAG_arm-apple-darwin := -Wl,-exported_symbols_list,
213215
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-darwin :=
214216
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-darwin :=
215217
CFG_DEF_SUFFIX_arm-apple-darwin := .darwin.def
218+
CFG_LLC_FLAGS_arm-apple-darwin := -arm-enable-ehabi -arm-enable-ehabi-descriptors
216219
CFG_INSTALL_NAME_arm-apple-darwin = -Wl,-install_name,@rpath/$(1)
217220
CFG_LIBUV_LINK_FLAGS_arm-apple-darwin =
218221
CFG_EXE_SUFFIX_arm-apple-darwin :=
@@ -240,6 +243,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
240243
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
241244
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
242245
CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
246+
CFG_LLC_FLAGS_x86_64-apple-darwin :=
243247
CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
244248
CFG_LIBUV_LINK_FLAGS_x86_64-apple-darwin =
245249
CFG_EXE_SUFFIX_x86_64-apple-darwin :=
@@ -266,6 +270,7 @@ CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
266270
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
267271
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
268272
CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
273+
CFG_LLC_FLAGS_i686-apple-darwin :=
269274
CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
270275
CFG_LIBUV_LINK_FLAGS_i686-apple-darwin =
271276
CFG_EXE_SUFFIX_i686-apple-darwin :=
@@ -292,6 +297,7 @@ CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list
292297
CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
293298
CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
294299
CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
300+
CFG_LLC_FLAGS_arm-linux-androideabi := -arm-enable-ehabi -arm-enable-ehabi-descriptors
295301
CFG_INSTALL_NAME_arm-linux-androideabi =
296302
CFG_LIBUV_LINK_FLAGS_arm-linux-androideabi =
297303
CFG_EXE_SUFFIX_arm-linux-androideabi :=
@@ -321,6 +327,7 @@ CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynami
321327
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
322328
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
323329
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
330+
CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf := -arm-enable-ehabi -arm-enable-ehabi-descriptors
324331
CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
325332
CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabihf =
326333
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
@@ -350,6 +357,7 @@ CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-
350357
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
351358
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
352359
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
360+
CFG_LLC_FLAGS_arm-unknown-linux-gnueabi := -arm-enable-ehabi -arm-enable-ehabi-descriptors
353361
CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
354362
CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabi =
355363
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
@@ -378,6 +386,7 @@ CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-lis
378386
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
379387
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
380388
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
389+
CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
381390
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
382391
CFG_LIBUV_LINK_FLAGS_mips-unknown-linux-gnu =
383392
CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
@@ -405,6 +414,7 @@ CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 :=
405414
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-mingw32 :=
406415
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 :=
407416
CFG_DEF_SUFFIX_i686-pc-mingw32 := .mingw32.def
417+
CFG_LLC_FLAGS_i686-pc-mingw32 :=
408418
CFG_INSTALL_NAME_i686-pc-mingw32 =
409419
CFG_LIBUV_LINK_FLAGS_i686-pc-mingw32 := -lws2_32 -lpsapi -liphlpapi
410420
CFG_LLVM_BUILD_ENV_i686-pc-mingw32 := CPATH=$(CFG_SRC_DIR)src/etc/mingw-fix-include
@@ -432,6 +442,7 @@ CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
432442
CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
433443
CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
434444
CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
445+
CFG_LLC_FLAGS_i586-mingw32msvc :=
435446
CFG_INSTALL_NAME_i586-mingw32msvc =
436447
CFG_LIBUV_LINK_FLAGS_i586-mingw32msvc := -L$(CFG_MINGW32_CROSS_PATH)/i586-mingw32msvc/lib -lws2_32 -lpsapi -liphlpapi
437448
CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
@@ -461,6 +472,7 @@ CFG_GCCISH_DEF_FLAG_i686-w64-mingw32 :=
461472
CFG_GCCISH_PRE_LIB_FLAGS_i686-w64-mingw32 :=
462473
CFG_GCCISH_POST_LIB_FLAGS_i686-w64-mingw32 :=
463474
CFG_DEF_SUFFIX_i686-w64-mingw32 := .mingw32.def
475+
CFG_LLC_FLAGS_i686-w64-mingw32 :=
464476
CFG_INSTALL_NAME_i686-w64-mingw32 =
465477
CFG_LIBUV_LINK_FLAGS_i686-w64-mingw32 := -lws2_32 -lpsapi -liphlpapi
466478
CFG_EXE_SUFFIX_i686-w64-mingw32 := .exe
@@ -489,6 +501,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 :=
489501
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 :=
490502
CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 :=
491503
CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def
504+
CFG_LLC_FLAGS_x86_64-w64-mingw32 :=
492505
CFG_INSTALL_NAME_x86_64-w64-mingw32 =
493506
CFG_LIBUV_LINK_FLAGS_x86_64-w64-mingw32 := -lws2_32 -lpsapi -liphlpapi
494507
CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe
@@ -515,6 +528,7 @@ CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-lis
515528
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
516529
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
517530
CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
531+
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
518532
CFG_INSTALL_NAME_x86_64-unknown-freebsd =
519533
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-freebsd := -pthread -lkvm
520534
CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=

mk/rt.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ $$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.S $$(MKFILE_DEPS) \
116116
$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.ll $$(MKFILE_DEPS) \
117117
$$(LLVM_CONFIG_$$(CFG_BUILD))
118118
@$$(call E, compile: $$@)
119-
$$(Q)$(LLC_$(CFG_BUILD)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
119+
$$(Q)$(LLC_$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<
120120

121121
$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_$(1)_$(2))
122122
@$$(call E, link: $$@)

src/libstd/rt/unwind.rs

+113-46
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ use any::{Any, AnyRefExt};
5959
use c_str::CString;
6060
use cast;
6161
use kinds::Send;
62-
use libc::{c_char, size_t};
63-
use libc::{c_void, c_int};
62+
use libc::{c_void, c_char, size_t};
6463
use option::{Some, None, Option};
6564
use result::{Err, Ok};
6665
use rt::local::Local;
@@ -78,6 +77,7 @@ mod libunwind {
7877

7978
use libc::{uintptr_t, uint64_t};
8079

80+
#[cfg(not(target_os = "android"))]
8181
#[repr(C)]
8282
pub enum _Unwind_Action
8383
{
@@ -88,6 +88,18 @@ mod libunwind {
8888
_UA_END_OF_STACK = 16,
8989
}
9090

91+
#[cfg(target_os = "android")]
92+
#[repr(C)]
93+
pub enum _Unwind_State
94+
{
95+
_US_VIRTUAL_UNWIND_FRAME = 0,
96+
_US_UNWIND_FRAME_STARTING = 1,
97+
_US_UNWIND_FRAME_RESUME = 2,
98+
_US_ACTION_MASK = 3,
99+
_US_FORCE_UNWIND = 8,
100+
_US_END_OF_STACK = 16
101+
}
102+
91103
#[repr(C)]
92104
pub enum _Unwind_Reason_Code {
93105
_URC_NO_REASON = 0,
@@ -99,6 +111,7 @@ mod libunwind {
99111
_URC_HANDLER_FOUND = 6,
100112
_URC_INSTALL_CONTEXT = 7,
101113
_URC_CONTINUE_UNWIND = 8,
114+
_URC_FAILURE = 9, // used only by ARM EABI
102115
}
103116

104117
pub type _Unwind_Exception_Class = uint64_t;
@@ -108,8 +121,7 @@ mod libunwind {
108121
pub struct _Unwind_Exception {
109122
exception_class: _Unwind_Exception_Class,
110123
exception_cleanup: _Unwind_Exception_Cleanup_Fn,
111-
private_1: _Unwind_Word,
112-
private_2: _Unwind_Word,
124+
private: [_Unwind_Word, ..20],
113125
}
114126

115127
pub enum _Unwind_Context {}
@@ -148,7 +160,7 @@ impl Unwinder {
148160
let ep = rust_try(try_fn, closure.code as *c_void,
149161
closure.env as *c_void);
150162
if !ep.is_null() {
151-
rtdebug!("Caught {}", (*ep).exception_class);
163+
rtdebug!("caught {}", (*ep).exception_class);
152164
uw::_Unwind_DeleteException(ep);
153165
}
154166
}
@@ -190,8 +202,7 @@ impl Unwinder {
190202
let exception = ~uw::_Unwind_Exception {
191203
exception_class: rust_exception_class(),
192204
exception_cleanup: exception_cleanup,
193-
private_1: 0,
194-
private_2: 0
205+
private: [0, ..20],
195206
};
196207
let error = uw::_Unwind_RaiseException(cast::transmute(exception));
197208
rtabort!("Could not unwind stack, error = {}", error as int)
@@ -242,51 +253,107 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
242253
// This is achieved by overriding the return value in search phase to always
243254
// say "catch!".
244255

245-
extern "C" {
246-
fn __gcc_personality_v0(version: c_int,
247-
actions: uw::_Unwind_Action,
248-
exception_class: uw::_Unwind_Exception_Class,
249-
ue_header: *uw::_Unwind_Exception,
250-
context: *uw::_Unwind_Context)
251-
-> uw::_Unwind_Reason_Code;
252-
}
256+
#[cfg(not(target_os = "android"))]
257+
pub mod eabi {
258+
use uw = super::libunwind;
259+
use libc::c_int;
253260

254-
#[lang="eh_personality"]
255-
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
256-
#[doc(hidden)]
257-
#[cfg(not(test))]
258-
pub extern "C" fn rust_eh_personality(
259-
version: c_int,
260-
actions: uw::_Unwind_Action,
261-
exception_class: uw::_Unwind_Exception_Class,
262-
ue_header: *uw::_Unwind_Exception,
263-
context: *uw::_Unwind_Context
264-
) -> uw::_Unwind_Reason_Code
265-
{
266-
unsafe {
267-
__gcc_personality_v0(version, actions, exception_class, ue_header,
268-
context)
261+
extern "C" {
262+
fn __gcc_personality_v0(version: c_int,
263+
actions: uw::_Unwind_Action,
264+
exception_class: uw::_Unwind_Exception_Class,
265+
ue_header: *uw::_Unwind_Exception,
266+
context: *uw::_Unwind_Context)
267+
-> uw::_Unwind_Reason_Code;
268+
}
269+
270+
#[lang="eh_personality"]
271+
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
272+
#[doc(hidden)]
273+
#[cfg(not(test))]
274+
pub extern "C" fn rust_eh_personality(
275+
version: c_int,
276+
actions: uw::_Unwind_Action,
277+
exception_class: uw::_Unwind_Exception_Class,
278+
ue_header: *uw::_Unwind_Exception,
279+
context: *uw::_Unwind_Context
280+
) -> uw::_Unwind_Reason_Code
281+
{
282+
unsafe {
283+
__gcc_personality_v0(version, actions, exception_class, ue_header,
284+
context)
285+
}
286+
}
287+
288+
#[no_mangle] // referenced from rust_try.ll
289+
#[doc(hidden)]
290+
#[cfg(not(test))]
291+
pub extern "C" fn rust_eh_personality_catch(
292+
version: c_int,
293+
actions: uw::_Unwind_Action,
294+
exception_class: uw::_Unwind_Exception_Class,
295+
ue_header: *uw::_Unwind_Exception,
296+
context: *uw::_Unwind_Context
297+
) -> uw::_Unwind_Reason_Code
298+
{
299+
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
300+
uw::_URC_HANDLER_FOUND // catch!
301+
}
302+
else { // cleanup phase
303+
unsafe {
304+
__gcc_personality_v0(version, actions, exception_class, ue_header,
305+
context)
306+
}
307+
}
269308
}
270309
}
271310

272-
#[no_mangle] // referenced from rust_try.ll
273-
#[doc(hidden)]
274-
#[cfg(not(test))]
275-
pub extern "C" fn rust_eh_personality_catch(
276-
version: c_int,
277-
actions: uw::_Unwind_Action,
278-
exception_class: uw::_Unwind_Exception_Class,
279-
ue_header: *uw::_Unwind_Exception,
280-
context: *uw::_Unwind_Context
281-
) -> uw::_Unwind_Reason_Code
282-
{
283-
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
284-
uw::_URC_HANDLER_FOUND // catch!
311+
// ARM EHABI uses a slightly different personality routine signature,
312+
// but otherwise works the same.
313+
#[cfg(target_os = "android")]
314+
pub mod eabi {
315+
use uw = super::libunwind;
316+
use libc::c_int;
317+
318+
extern "C" {
319+
fn __gcc_personality_v0(state: uw::_Unwind_State,
320+
ue_header: *uw::_Unwind_Exception,
321+
context: *uw::_Unwind_Context)
322+
-> uw::_Unwind_Reason_Code;
285323
}
286-
else { // cleanup phase
324+
325+
#[lang="eh_personality"]
326+
#[no_mangle] // so we can reference it by name from middle/trans/base.rs
327+
#[doc(hidden)]
328+
#[cfg(not(test))]
329+
pub extern "C" fn rust_eh_personality(
330+
state: uw::_Unwind_State,
331+
ue_header: *uw::_Unwind_Exception,
332+
context: *uw::_Unwind_Context
333+
) -> uw::_Unwind_Reason_Code
334+
{
287335
unsafe {
288-
__gcc_personality_v0(version, actions, exception_class, ue_header,
289-
context)
336+
__gcc_personality_v0(state, ue_header, context)
337+
}
338+
}
339+
340+
#[no_mangle] // referenced from rust_try.ll
341+
#[doc(hidden)]
342+
#[cfg(not(test))]
343+
pub extern "C" fn rust_eh_personality_catch(
344+
state: uw::_Unwind_State,
345+
ue_header: *uw::_Unwind_Exception,
346+
context: *uw::_Unwind_Context
347+
) -> uw::_Unwind_Reason_Code
348+
{
349+
if (state as c_int & uw::_US_ACTION_MASK as c_int)
350+
== uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
351+
uw::_URC_HANDLER_FOUND // catch!
352+
}
353+
else { // cleanup phase
354+
unsafe {
355+
__gcc_personality_v0(state, ue_header, context)
356+
}
290357
}
291358
}
292359
}

0 commit comments

Comments
 (0)