mirror of
https://github.com/libunwind/libunwind.git
synced 2026-01-12 00:04:03 +08:00
Rewrite how we read link register
This commit is contained in:
@@ -412,7 +412,7 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
|
||||
struct cursor *c = (struct cursor *) cursor;
|
||||
struct dwarf_cursor *d = &c->dwarf;
|
||||
unw_trace_cache_t *cache;
|
||||
unw_word_t fp, sp, pc, cfa, lr;
|
||||
unw_word_t fp, sp, pc, cfa, lr = 0;
|
||||
int maxdepth = 0;
|
||||
int depth = 0;
|
||||
int ret;
|
||||
@@ -433,11 +433,6 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
|
||||
ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_AARCH64_X29]), fp);
|
||||
assert(ret == 0);
|
||||
|
||||
/* In case of unwinding from ucontext_t, we can look at the link
|
||||
register value. */
|
||||
ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_AARCH64_X30]), lr);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Get frame cache. */
|
||||
if (unlikely(! (cache = trace_cache_get())))
|
||||
{
|
||||
|
||||
@@ -424,11 +424,6 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
|
||||
ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_ARM_R7]), r7);
|
||||
assert(ret == 0);
|
||||
|
||||
/* In case of unwinding from ucontext_t, we can look at the link
|
||||
register value. On ARM, the register R14 acts as the link register */
|
||||
ACCESS_MEM_FAST(ret, 0, d, DWARF_GET_LOC(d->loc[UNW_ARM_R14]), lr);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Get frame cache. */
|
||||
if (unlikely(! (cache = trace_cache_get())))
|
||||
{
|
||||
@@ -488,8 +483,13 @@ tdep_trace (unw_cursor_t *cursor, void **buffer, int *size)
|
||||
/* Advance standard traceable frame. */
|
||||
cfa = (f->cfa_reg_sp ? sp : r7) + f->cfa_reg_offset;
|
||||
if (likely(f->lr_cfa_offset != -1))
|
||||
{
|
||||
ACCESS_MEM_FAST(ret, c->validate, d, cfa + f->lr_cfa_offset, pc);
|
||||
else if (lr != 0)
|
||||
}
|
||||
// lr might have been set by the previous frame (sigreturn)
|
||||
// but we might get here directly (uwn_backtrace2 for ex) and lr was not set.
|
||||
// In that case, try reading from the Link Register (X30)
|
||||
else if (lr != 0 || dwarf_get (d, d->loc[UNW_ARM_R14], &lr) >= 0)
|
||||
{
|
||||
/* Use the saved link register as the new pc. */
|
||||
Debug(4, "use link register value 0x%lx as the new pc\n", lr);
|
||||
|
||||
Reference in New Issue
Block a user