[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] unwinding through dynamically modified code?
From: |
David Mosberger |
Subject: |
Re: [libunwind] unwinding through dynamically modified code? |
Date: |
Thu, 25 Mar 2004 12:21:39 -0800 |
>>>>> On Wed, 24 Mar 2004 13:05:41 -0600 (CST), Todd L Miller <address@hidden>
>>>>> said:
Todd> /* The unw_dyn_info_t which points to regionZero (whose 'next' is
Todd> regionOne) has a start_ip of 0x60000ffffffe9f80. */
Looks fine.
Todd> 0x60000ffffffe9f80: [MLX] nop.m 0x0
Todd> 0x60000ffffffe9f81: brl.few 0x60000ffffffea1e0;;
Todd> /* This jump is because this code fragment is currently configured
Todd> not to do anything; it will be later replaced with a bundle
Todd> of no-ops. */
OK.
Todd> 0x60000ffffffe9f90: [MII] alloc r43=ar.pfs,61,53,0
Todd> 0x60000ffffffe9f91: nop.i 0x0
Todd> 0x60000ffffffe9f92: nop.i 0x0;;
Todd> /* op_count was initialized to 0, and insn_count is 3. */
Todd> _U_dyn_op_save_reg( & regionOne->op[ regionOne->op_count++ ],
Todd> _U_QP_TRUE, regionOne->insn_count++,
Todd> UNW_IA64_AR_PFS, UNW_IA64_GR + 43 );
This looks wrong: the "when" field must be set to the index of the
instruction it is describing. In C, this index is calculated like
this:
insn_index = (Ib - Rb)/16*3 + Is - Rs
where:
Ib = instruction's bundle address
Rb = bundle address of start of region
Is = instruction's slot number
Rs = slot number at which region starts
Note: customarily, the slot number is encoded in the least-significant
2 bits of an instruction-pointer.
Apart from the "when" field, the directive looks fine.
Todd> 0x60000ffffffe9fa0: [MII] mov r44=r1
Todd> /* Is this still superflous if I later change the gp to make a
Todd> function call? */
Not just superfluous, but actually illegal. Libunwind would complain
at the time this descriptor was interpreted (for performance-reasons,
no checking is done at the time _U_dyn_register() is called).
Todd> _U_dyn_op_save_reg( & regionOne->op[ regionOne->op_count++ ],
Todd> _U_QP_TRUE, regionOne->insn_count++,
Todd> UNW_IA64_GR + 1, UNW_IA64_GR + 44 );
Todd> 0x60000ffffffe9fa1: mov r45=r2
Todd> 0x60000ffffffe9fa2: mov r46=r3
Todd> ... // the other unstacked scratch registers
Todd> 0x60000ffffffea020: [MII] mov r68=r31
Eh, r4-r7 are "preserved" registers. If you save those, you'll need
to add describe the saving instructions.
Todd> 0x60000ffffffea051: mov r75=pr
Todd> _U_dyn_op_save_reg( & regionOne->op[ regionOne->op_count++ ],
Todd> _U_QP_TRUE, regionOne->insn_count++,
Todd> UNW_IA64_PR, UNW_IA64_GR + 75 );
Apart from the "when" field, this looks fine.
Todd> 0x60000ffffffea061: mov r76=r12
Todd> _U_dyn_op_save_reg( & regionOne->op[ regionOne->op_count++ ],
Todd> _U_QP_TRUE, regionOne->insn_count++,
Todd> UNW_IA64_SP, UNW_IA64_GR + 76 );
Likewise.
Todd> 0x60000ffffffea062: adds r12=-32,r12;;
This one:
Todd> 0x60000ffffffea1b2: mov r12=r76
needs to be described with:
_U_dyn_op_pop_frames(op, qp, when, 1)
because you're popping 1 stack-frame.
Todd> 0x60000ffffffea1c0: [MII] nop.m 0x0
Todd> 0x60000ffffffea1c1: mov.i ar.pfs=r43
Todd> 0x60000ffffffea1c2: nop.i 0x0;;
The second region must end here, so the unwinder knows that
after this point, the existing frame-info is no longer valid.
Todd> 0x60000ffffffea1d0: [MII] alloc r43=ar.pfs,12,3,0
Todd> /* At this point, the machine state, excepting the extra output
Todd> register and the pc, is the same as it was before the jump
Todd> to this code fragment. After this bundle finishes its
Todd> nops, */
You'll need to open up a new region. Assuming that the code matches
_exactly_ as the code at the original location, you can use ALIAS
to ensure that the unwinder will find the right unwind info.
Todd> /* More importantly, however, after this alloc, the registers
Todd> in which I'd been preserving ar.pfs, the gp, the stack pointer,
Todd> and the predicate registers are no longer accessible.
That's why the second region needs to end before the "alloc".
Todd> Given that my code fragment is only half-way done, do I insert
Todd> another alias operation, or _U_dyn_op_stop() the current region
Todd> and start another one?
Yup.
Todd> Immediately after the emulated instructions, I insert another
Todd> large alloc and repeat the entire process. If I used more
Todd> than two regions, would the third be an aliased region
Todd> covering the emulated instruction(s), and then the fourth
Todd> effectively a duplicate of the second? Or do the label
Todd> state/copy state operations come into play here? */
If I understand you correctly, label_state and copy_state would be
what you'd want to use here.
Todd> I then have to copy the unw_dyn_info_t and its linked list of
Todd> regions into the remote process (diddling the pointers as I
Todd> go) and link it into the dynamic unwind information list
Todd> there.
Yes, that sounds about right.
Just for your info: the tests/test-ptrace program can single-step over
a (region) of a program and unwind at each step. That's a good way to
test whether the unwind info is correct. It's not a _complete_ test,
because it only tests what is needed to unwind to the root function,
but especially when combined with --enable-debug and UNW_DEBUG_LEVEL,
it's a very good way to verify that things look sane.
Thanks,
--david
- Re: [libunwind] unwinding through dynamically modified code?, (continued)
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, Young, Mark, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, Keith Owens, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/15
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/24
- Re: [libunwind] unwinding through dynamically modified code?,
David Mosberger <=
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/25
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/25
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/25
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/25
- Re: [libunwind] unwinding through dynamically modified code?, Todd L Miller, 2004/03/26
- Re: [libunwind] unwinding through dynamically modified code?, David Mosberger, 2004/03/26
- [libunwind] multiple dynamic list-info addresses?, Todd L Miller, 2004/03/29
- [libunwind] Re: multiple dynamic list-info addresses?, David Mosberger, 2004/03/29
- [libunwind] Re: multiple dynamic list-info addresses?, Todd L Miller, 2004/03/30
- [libunwind] Re: multiple dynamic list-info addresses?, David Mosberger, 2004/03/30