forked from OSchip/llvm-project
Make it possible to use libunwind without heap.
This patch allows to use libunwind on bare-metal systems that do not include malloc/free by conditionally turning off nonessential functionality that requires these functions. The disabled functionality includes: * the .cfi_remember_state and .cfi_restore_state instructions; * the DWARF FDE cache. The .cfi_{remember,restore}_state instructions don't seem to be used by contemporary compilers. None of the LLVM backends emit it. The DWARF FDE cache is bypassed if _LIBUNWIND_NO_HEAP is defined. Specifically, entries are never added to it, so the search begins and ends at the statically allocated, empty initial cache. Such heap-less libunwind on a bare metal system is successfully used in the ARTIQ project[1], and it is my hope that it will be useful elsewhere. [1]: http://m-labs.hk/artiq Differential Revision: http://reviews.llvm.org/D11897 llvm-svn: 252452
This commit is contained in:
parent
7a6e292d86
commit
b0342a66a0
|
@ -380,7 +380,9 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
|
|||
uint64_t length;
|
||||
uint8_t opcode = addressSpace.get8(p);
|
||||
uint8_t operand;
|
||||
#if !defined(_LIBUNWIND_NO_HEAP)
|
||||
PrologInfoStackEntry *entry;
|
||||
#endif
|
||||
++p;
|
||||
switch (opcode) {
|
||||
case DW_CFA_nop:
|
||||
|
@ -492,6 +494,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
|
|||
fprintf(stderr, "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n",
|
||||
reg, reg2);
|
||||
break;
|
||||
#if !defined(_LIBUNWIND_NO_HEAP)
|
||||
case DW_CFA_remember_state:
|
||||
// avoid operator new, because that would be an upward dependency
|
||||
entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry));
|
||||
|
@ -517,6 +520,7 @@ bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
|
|||
if (logDwarf)
|
||||
fprintf(stderr, "DW_CFA_restore_state\n");
|
||||
break;
|
||||
#endif
|
||||
case DW_CFA_def_cfa:
|
||||
reg = addressSpace.getULEB128(p, instructionsEnd);
|
||||
offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd);
|
||||
|
|
|
@ -114,6 +114,7 @@ typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
|
|||
template <typename A>
|
||||
void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
|
||||
pint_t fde) {
|
||||
#if !defined(_LIBUNWIND_NO_HEAP)
|
||||
_LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_wrlock(&_lock));
|
||||
if (_bufferUsed >= _bufferEnd) {
|
||||
size_t oldSize = (size_t)(_bufferEnd - _buffer);
|
||||
|
@ -139,6 +140,7 @@ void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
|
|||
}
|
||||
#endif
|
||||
_LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
|
|
Loading…
Reference in New Issue