mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-02-17 02:31:41 +01:00
Merge branch 'master' into freebsd
This commit is contained in:
commit
e1493dc011
2 changed files with 34 additions and 3 deletions
|
@ -93,6 +93,7 @@ unw_handle_signal_frame (unw_cursor_t *cursor)
|
||||||
Hence dwarf_step() should never call this function. Maybe
|
Hence dwarf_step() should never call this function. Maybe
|
||||||
restore old non-dwarf signal handling here, but then the
|
restore old non-dwarf signal handling here, but then the
|
||||||
gating on unw_is_signal_frame() needs to be removed. */
|
gating on unw_is_signal_frame() needs to be removed. */
|
||||||
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n",
|
Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n",
|
||||||
c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa);
|
c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa);
|
||||||
assert(c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME);
|
assert(c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME);
|
||||||
|
|
|
@ -28,14 +28,38 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
#include "unwind_i.h"
|
#include "unwind_i.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* Recognise PLT entries such as:
|
||||||
|
3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip)
|
||||||
|
3bdf6: 68 ae 03 00 00 pushq $0x3ae
|
||||||
|
3bdfb: e9 00 c5 ff ff jmpq 38300 <_init+0x18> */
|
||||||
|
static int
|
||||||
|
is_plt_entry (struct dwarf_cursor *c)
|
||||||
|
{
|
||||||
|
unw_word_t w0, w1;
|
||||||
|
unw_accessors_t *a;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
a = unw_get_accessors (c->as);
|
||||||
|
if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0
|
||||||
|
|| (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = (((w0 & 0xffff) == 0x25ff)
|
||||||
|
&& (((w0 >> 48) & 0xff) == 0x68)
|
||||||
|
&& (((w1 >> 24) & 0xff) == 0xe9));
|
||||||
|
|
||||||
|
Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
PROTECTED int
|
PROTECTED int
|
||||||
unw_step (unw_cursor_t *cursor)
|
unw_step (unw_cursor_t *cursor)
|
||||||
{
|
{
|
||||||
struct cursor *c = (struct cursor *) cursor;
|
struct cursor *c = (struct cursor *) cursor;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
Debug (1, "(cursor=%p, ip=0x%016llx)\n",
|
Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n",
|
||||||
c, (unsigned long long) c->dwarf.ip);
|
c, c->dwarf.ip, c->dwarf.cfa);
|
||||||
|
|
||||||
/* Try DWARF-based unwinding... */
|
/* Try DWARF-based unwinding... */
|
||||||
c->sigcontext_format = X86_64_SCF_NONE;
|
c->sigcontext_format = X86_64_SCF_NONE;
|
||||||
|
@ -86,6 +110,12 @@ unw_step (unw_cursor_t *cursor)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (is_plt_entry (&c->dwarf))
|
||||||
|
{
|
||||||
|
Debug (2, "found plt entry\n");
|
||||||
|
c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0);
|
||||||
|
c->dwarf.cfa += 8;
|
||||||
|
}
|
||||||
else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))
|
else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))
|
||||||
{
|
{
|
||||||
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
|
||||||
|
@ -139,7 +169,7 @@ unw_step (unw_cursor_t *cursor)
|
||||||
|
|
||||||
c->dwarf.ret_addr_column = RIP;
|
c->dwarf.ret_addr_column = RIP;
|
||||||
|
|
||||||
if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))
|
if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RIP]))
|
||||||
{
|
{
|
||||||
ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip);
|
ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip);
|
||||||
Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",
|
Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",
|
||||||
|
|
Loading…
Add table
Reference in a new issue