Skip to content

Commit 6478345

Browse files
authored
Cut down on #[cfg] soup in libunwind.rs (#449)
Try to wrangle things with `cfg_if!` since otherwise it's pretty hard to understand what's going on.
1 parent 14837b9 commit 6478345

File tree

1 file changed

+98
-121
lines changed

1 file changed

+98
-121
lines changed

src/backtrace/libunwind.rs

Lines changed: 98 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -146,145 +146,122 @@ mod uw {
146146
extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code;
147147

148148
extern "C" {
149-
// No native _Unwind_Backtrace on iOS
150-
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
151149
pub fn _Unwind_Backtrace(
152150
trace: _Unwind_Trace_Fn,
153151
trace_argument: *mut c_void,
154152
) -> _Unwind_Reason_Code;
153+
}
155154

155+
cfg_if::cfg_if! {
156156
// available since GCC 4.2.0, should be fine for our purpose
157-
#[cfg(all(
157+
if #[cfg(all(
158158
not(all(target_os = "android", target_arch = "arm")),
159159
not(all(target_os = "freebsd", target_arch = "arm")),
160160
not(all(target_os = "linux", target_arch = "arm")),
161161
not(all(target_os = "horizon", target_arch = "arm"))
162-
))]
163-
pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
162+
))] {
163+
extern "C" {
164+
pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
165+
pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
164166

165-
#[cfg(all(
166-
not(all(target_os = "android", target_arch = "arm")),
167-
not(all(target_os = "freebsd", target_arch = "arm")),
168-
not(all(target_os = "linux", target_arch = "arm"))
169-
))]
170-
pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
171-
172-
#[cfg(all(
173-
not(all(target_os = "android", target_arch = "arm")),
174-
not(all(target_os = "freebsd", target_arch = "arm")),
175-
not(all(target_os = "linux", target_arch = "arm")),
176-
not(all(target_os = "linux", target_arch = "s390x"))
177-
))]
178-
// This function is a misnomer: rather than getting this frame's
179-
// Canonical Frame Address (aka the caller frame's SP) it
180-
// returns this frame's SP.
181-
//
182-
// https://github.com/libunwind/libunwind/blob/d32956507cf29d9b1a98a8bce53c78623908f4fe/src/unwind/GetCFA.c#L28-L35
183-
#[link_name = "_Unwind_GetCFA"]
184-
pub fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
185-
}
167+
#[cfg(not(all(target_os = "linux", target_arch = "s390x")))]
168+
// This function is a misnomer: rather than getting this frame's
169+
// Canonical Frame Address (aka the caller frame's SP) it
170+
// returns this frame's SP.
171+
//
172+
// https://github.com/libunwind/libunwind/blob/d32956507cf29d9b1a98a8bce53c78623908f4fe/src/unwind/GetCFA.c#L28-L35
173+
#[link_name = "_Unwind_GetCFA"]
174+
pub fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
186175

187-
// s390x uses a biased CFA value, therefore we need to use
188-
// _Unwind_GetGR to get the stack pointer register (%r15)
189-
// instead of relying on _Unwind_GetCFA.
190-
#[cfg(all(target_os = "linux", target_arch = "s390x"))]
191-
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
192-
extern "C" {
193-
pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, index: libc::c_int) -> libc::uintptr_t;
194-
}
195-
_Unwind_GetGR(ctx, 15)
196-
}
176+
}
197177

198-
// On android and arm, the function `_Unwind_GetIP` and a bunch of others
199-
// are macros, so we define functions containing the expansion of the
200-
// macros.
201-
//
202-
// TODO: link to the header file that defines these macros, if you can find
203-
// it. (I, fitzgen, cannot find the header file that some of these macro
204-
// expansions were originally borrowed from.)
205-
#[cfg(any(
206-
all(target_os = "android", target_arch = "arm"),
207-
all(target_os = "freebsd", target_arch = "arm"),
208-
all(target_os = "linux", target_arch = "arm"),
209-
all(target_os = "horizon", target_arch = "arm")
210-
))]
211-
pub use self::arm::*;
212-
#[cfg(any(
213-
all(target_os = "android", target_arch = "arm"),
214-
all(target_os = "freebsd", target_arch = "arm"),
215-
all(target_os = "linux", target_arch = "arm"),
216-
all(target_os = "horizon", target_arch = "arm")
217-
))]
218-
mod arm {
219-
pub use super::*;
220-
#[repr(C)]
221-
enum _Unwind_VRS_Result {
222-
_UVRSR_OK = 0,
223-
_UVRSR_NOT_IMPLEMENTED = 1,
224-
_UVRSR_FAILED = 2,
225-
}
226-
#[repr(C)]
227-
enum _Unwind_VRS_RegClass {
228-
_UVRSC_CORE = 0,
229-
_UVRSC_VFP = 1,
230-
_UVRSC_FPA = 2,
231-
_UVRSC_WMMXD = 3,
232-
_UVRSC_WMMXC = 4,
233-
}
234-
#[repr(C)]
235-
enum _Unwind_VRS_DataRepresentation {
236-
_UVRSD_UINT32 = 0,
237-
_UVRSD_VFPX = 1,
238-
_UVRSD_FPAX = 2,
239-
_UVRSD_UINT64 = 3,
240-
_UVRSD_FLOAT = 4,
241-
_UVRSD_DOUBLE = 5,
242-
}
178+
// s390x uses a biased CFA value, therefore we need to use
179+
// _Unwind_GetGR to get the stack pointer register (%r15)
180+
// instead of relying on _Unwind_GetCFA.
181+
#[cfg(all(target_os = "linux", target_arch = "s390x"))]
182+
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
183+
extern "C" {
184+
pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, index: libc::c_int) -> libc::uintptr_t;
185+
}
186+
_Unwind_GetGR(ctx, 15)
187+
}
188+
} else {
189+
// On android and arm, the function `_Unwind_GetIP` and a bunch of
190+
// others are macros, so we define functions containing the
191+
// expansion of the macros.
192+
//
193+
// TODO: link to the header file that defines these macros, if you
194+
// can find it. (I, fitzgen, cannot find the header file that some
195+
// of these macro expansions were originally borrowed from.)
196+
#[repr(C)]
197+
enum _Unwind_VRS_Result {
198+
_UVRSR_OK = 0,
199+
_UVRSR_NOT_IMPLEMENTED = 1,
200+
_UVRSR_FAILED = 2,
201+
}
202+
#[repr(C)]
203+
enum _Unwind_VRS_RegClass {
204+
_UVRSC_CORE = 0,
205+
_UVRSC_VFP = 1,
206+
_UVRSC_FPA = 2,
207+
_UVRSC_WMMXD = 3,
208+
_UVRSC_WMMXC = 4,
209+
}
210+
#[repr(C)]
211+
enum _Unwind_VRS_DataRepresentation {
212+
_UVRSD_UINT32 = 0,
213+
_UVRSD_VFPX = 1,
214+
_UVRSD_FPAX = 2,
215+
_UVRSD_UINT64 = 3,
216+
_UVRSD_FLOAT = 4,
217+
_UVRSD_DOUBLE = 5,
218+
}
243219

244-
type _Unwind_Word = libc::c_uint;
245-
extern "C" {
246-
fn _Unwind_VRS_Get(
247-
ctx: *mut _Unwind_Context,
248-
klass: _Unwind_VRS_RegClass,
249-
word: _Unwind_Word,
250-
repr: _Unwind_VRS_DataRepresentation,
251-
data: *mut c_void,
252-
) -> _Unwind_VRS_Result;
253-
}
220+
type _Unwind_Word = libc::c_uint;
221+
extern "C" {
222+
fn _Unwind_VRS_Get(
223+
ctx: *mut _Unwind_Context,
224+
klass: _Unwind_VRS_RegClass,
225+
word: _Unwind_Word,
226+
repr: _Unwind_VRS_DataRepresentation,
227+
data: *mut c_void,
228+
) -> _Unwind_VRS_Result;
229+
}
254230

255-
pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
256-
let mut val: _Unwind_Word = 0;
257-
let ptr = &mut val as *mut _Unwind_Word;
258-
let _ = _Unwind_VRS_Get(
259-
ctx,
260-
_Unwind_VRS_RegClass::_UVRSC_CORE,
261-
15,
262-
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
263-
ptr as *mut c_void,
264-
);
265-
(val & !1) as libc::uintptr_t
266-
}
231+
pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
232+
let mut val: _Unwind_Word = 0;
233+
let ptr = &mut val as *mut _Unwind_Word;
234+
let _ = _Unwind_VRS_Get(
235+
ctx,
236+
_Unwind_VRS_RegClass::_UVRSC_CORE,
237+
15,
238+
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
239+
ptr as *mut c_void,
240+
);
241+
(val & !1) as libc::uintptr_t
242+
}
267243

268-
// R13 is the stack pointer on arm.
269-
const SP: _Unwind_Word = 13;
244+
// R13 is the stack pointer on arm.
245+
const SP: _Unwind_Word = 13;
270246

271-
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
272-
let mut val: _Unwind_Word = 0;
273-
let ptr = &mut val as *mut _Unwind_Word;
274-
let _ = _Unwind_VRS_Get(
275-
ctx,
276-
_Unwind_VRS_RegClass::_UVRSC_CORE,
277-
SP,
278-
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
279-
ptr as *mut c_void,
280-
);
281-
val as libc::uintptr_t
282-
}
247+
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
248+
let mut val: _Unwind_Word = 0;
249+
let ptr = &mut val as *mut _Unwind_Word;
250+
let _ = _Unwind_VRS_Get(
251+
ctx,
252+
_Unwind_VRS_RegClass::_UVRSC_CORE,
253+
SP,
254+
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
255+
ptr as *mut c_void,
256+
);
257+
val as libc::uintptr_t
258+
}
283259

284-
// This function also doesn't exist on Android or ARM/Linux, so make it
285-
// a no-op.
286-
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void {
287-
pc
260+
// This function also doesn't exist on Android or ARM/Linux, so make it
261+
// a no-op.
262+
pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void {
263+
pc
264+
}
288265
}
289266
}
290267
}

0 commit comments

Comments
 (0)