Skip to content

Commit ff8fbf9

Browse files
committedJul 24, 2015
unwind: Fix libc++abi and libgcc build.
To build libc++abi without libunwind, we should make sure that all function calls to _Unwind_{Get,Set}{GR,IP}() are inlined as function calls to _Unwind_VRS_{Get,Set}(). Otherwise, libc++abi.so will fail to link since libgcc does not provide these symbol at all. This commit fixes the problem by providing both the inlined version and exported version. llvm-svn: 243073
1 parent b1e77a3 commit ff8fbf9

File tree

2 files changed

+50
-35
lines changed

2 files changed

+50
-35
lines changed
 

‎libunwind/include/unwind.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,55 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
204204
_Unwind_VRS_DataRepresentation representation);
205205
#endif
206206

207+
#if !_LIBUNWIND_ARM_EHABI
208+
207209
extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
208210
extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
209211
uintptr_t new_value);
210212
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
211213
extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
212214

215+
#else // _LIBUNWIND_ARM_EHABI
216+
217+
#if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE)
218+
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern
219+
#else
220+
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__
221+
#endif
222+
223+
// These are de facto helper functions for ARM, which delegate the function
224+
// calls to _Unwind_VRS_Get/Set(). These are not a part of ARM EHABI
225+
// specification, thus these function MUST be inlined. Please don't replace
226+
// these with the "extern" function declaration; otherwise, the program
227+
// including this <unwind.h> header won't be ABI compatible and will result in
228+
// link error when we are linking the program with libgcc.
229+
230+
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
231+
uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) {
232+
uintptr_t value = 0;
233+
_Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
234+
return value;
235+
}
236+
237+
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
238+
void _Unwind_SetGR(struct _Unwind_Context *context, int index,
239+
uintptr_t value) {
240+
_Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
241+
}
242+
243+
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
244+
uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
245+
// remove the thumb-bit before returning
246+
return _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
247+
}
248+
249+
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
250+
void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) {
251+
uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
252+
_Unwind_SetGR(context, 15, value | thumb_bit);
253+
}
254+
#endif // _LIBUNWIND_ARM_EHABI
255+
213256
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
214257
extern uintptr_t
215258
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);

‎libunwind/src/UnwindLevel1.c

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15+
// ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}(). Thus, we are
16+
// defining inline functions to delegate the function calls to
17+
// _Unwind_VRS_{Get,Set}(). However, some applications might declare the
18+
// function protetype directly (instead of including <unwind.h>), thus we need
19+
// to export these functions from libunwind.so as well.
20+
#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1
21+
1522
#include <inttypes.h>
1623
#include <stdint.h>
1724
#include <stdbool.h>
@@ -496,39 +503,4 @@ _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
496503
unw_set_reg(cursor, UNW_REG_IP, value);
497504
}
498505

499-
#else
500-
501-
_LIBUNWIND_EXPORT uintptr_t
502-
_Unwind_GetGR(struct _Unwind_Context *context, int index) {
503-
uintptr_t value = 0;
504-
_Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
505-
_LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
506-
(void *)context, index, (uint64_t)value);
507-
return value;
508-
}
509-
510-
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
511-
uintptr_t value) {
512-
_LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0"PRIx64")\n",
513-
(void *)context, index, (uint64_t)value);
514-
_Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
515-
}
516-
517-
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
518-
// remove the thumb-bit before returning
519-
uintptr_t value = _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
520-
_LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
521-
(void *)context, (uint64_t)value);
522-
return value;
523-
}
524-
525-
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
526-
uintptr_t value) {
527-
_LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
528-
(void *)context, (uint64_t)value);
529-
uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
530-
_Unwind_SetGR(context, 15, value | thumb_bit);
531-
}
532-
533506
#endif // !_LIBUNWIND_ARM_EHABI
534-

0 commit comments

Comments
 (0)
Please sign in to comment.