mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-04-02 12:12:18 +02:00
Implement a cheaper getcontext()
Since the fast unwinding code path doesn't need the full context, a faster target dependent getcontext is implemented. Signed-off-by: Lassi Tuura <lat@cern.ch>
This commit is contained in:
parent
15f182828d
commit
e2962af9d3
10 changed files with 39 additions and 1 deletions
include
tdep-arm
tdep-hppa
tdep-ia64
tdep-mips
tdep-ppc32
tdep-ppc64
tdep-x86
tdep-x86_64
src
|
@ -215,6 +215,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
|
|
||||||
#endif /* !UNW_LOCAL_ONLY */
|
#endif /* !UNW_LOCAL_ONLY */
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -221,6 +221,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
|
|
||||||
#endif /* !UNW_LOCAL_ONLY */
|
#endif /* !UNW_LOCAL_ONLY */
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -216,6 +216,7 @@ struct ia64_global_unwind_state
|
||||||
# endif
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization unw.needs_initialization
|
#define tdep_needs_initialization unw.needs_initialization
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -276,6 +276,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
|
|
||||||
#endif /* !UNW_LOCAL_ONLY */
|
#endif /* !UNW_LOCAL_ONLY */
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -251,6 +251,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
1, c->as_arg);
|
1, c->as_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -251,6 +251,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
1, c->as_arg);
|
1, c->as_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -237,6 +237,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
|
|
||||||
#endif /* !UNW_LOCAL_ONLY */
|
#endif /* !UNW_LOCAL_ONLY */
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace unw_getcontext
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
|
||||||
|
|
|
@ -177,6 +177,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
|
||||||
1, c->as_arg);
|
1, c->as_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define tdep_getcontext_trace UNW_ARCH_OBJ(getcontext_trace)
|
||||||
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
#define tdep_needs_initialization UNW_OBJ(needs_initialization)
|
||||||
#define tdep_init_mem_validate UNW_OBJ(init_mem_validate)
|
#define tdep_init_mem_validate UNW_OBJ(init_mem_validate)
|
||||||
#define tdep_init UNW_OBJ(init)
|
#define tdep_init UNW_OBJ(init)
|
||||||
|
@ -244,6 +245,7 @@ extern void tdep_stash_frame (struct dwarf_cursor *c,
|
||||||
struct dwarf_reg_state *rs);
|
struct dwarf_reg_state *rs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int tdep_getcontext_trace (unw_tdep_context_t *);
|
||||||
extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n);
|
extern int tdep_trace (unw_cursor_t *cursor, void **addresses, int *n);
|
||||||
|
|
||||||
#endif /* X86_64_LIBUNWIND_I_H */
|
#endif /* X86_64_LIBUNWIND_I_H */
|
||||||
|
|
|
@ -61,7 +61,7 @@ unw_backtrace (void **buffer, int size)
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
int n = size;
|
int n = size;
|
||||||
|
|
||||||
unw_getcontext (&uc);
|
tdep_getcontext_trace (&uc);
|
||||||
|
|
||||||
if (unw_init_local (&cursor, &uc) < 0)
|
if (unw_init_local (&cursor, &uc) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -101,5 +101,34 @@ _Ux86_64_getcontext:
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
.size _Ux86_64_getcontext, . - _Ux86_64_getcontext
|
.size _Ux86_64_getcontext, . - _Ux86_64_getcontext
|
||||||
|
|
||||||
|
/* int _Ux86_64_getcontext_trace (ucontext_t *ucp)
|
||||||
|
|
||||||
|
Saves limited machine context in UCP necessary for libunwind.
|
||||||
|
Unlike _Ux86_64_getcontext, saves only the parts needed for
|
||||||
|
fast trace. If fast trace fails, caller will have to get the
|
||||||
|
full context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global _Ux86_64_getcontext_trace
|
||||||
|
.hidden _Ux86_64_getcontext_trace
|
||||||
|
.type _Ux86_64_getcontext_trace, @function
|
||||||
|
_Ux86_64_getcontext_trace:
|
||||||
|
.cfi_startproc
|
||||||
|
|
||||||
|
/* Save only RBP, RBX, RSP, RIP - exclude this call. */
|
||||||
|
movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi)
|
||||||
|
movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi)
|
||||||
|
|
||||||
|
leaq 8(%rsp), %rax
|
||||||
|
movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi)
|
||||||
|
|
||||||
|
movq 0(%rsp), %rax
|
||||||
|
movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi)
|
||||||
|
|
||||||
|
xorq %rax, %rax
|
||||||
|
retq
|
||||||
|
.cfi_endproc
|
||||||
|
.size _Ux86_64_getcontext_trace, . - _Ux86_64_getcontext_trace
|
||||||
|
|
||||||
/* We do not need executable stack. */
|
/* We do not need executable stack. */
|
||||||
.section .note.GNU-stack,"",@progbits
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
|
Loading…
Add table
Reference in a new issue