Fix mips64 ddb backtracing
M. Warner Losh
imp at bsdimp.com
Thu May 27 16:12:13 UTC 2010
In message: <4BFDA036.7080502 at gmail.com>
Vladimir 'φ-coder/phcoder' Serbinenko <phcoder at gmail.com> writes:
: This is a multi-part message in MIME format.
: --------------080906000803010207060400
: Content-Type: text/plain; charset=UTF-8
: Content-Transfer-Encoding: quoted-printable
:
: I've come accross this issue when coding for yeeloong. It's easy to fix
: (patch attached). After applying the patch I had the session with
: debugger as in attached capture file.
: Can this patch go directly to -current ?
:
: --=20
: Regards
: Vladimir '=CF=86-coder/phcoder' Serbinenko
:
:
: --------------080906000803010207060400
: Content-Type: text/x-diff;
: name="mips64_bt.diff"
: Content-Transfer-Encoding: quoted-printable
: Content-Disposition: inline;
: filename="mips64_bt.diff"
:
: =3D=3D=3D modified file 'mips/mips/db_trace.c'
: --- mips/mips/db_trace.c 2010-05-26 07:47:16 +0000
: +++ mips/mips/db_trace.c 2010-05-26 22:19:06 +0000
: @@ -49,9 +49,19 @@
: #define MIPS_END_OF_FUNCTION(ins) ((ins) =3D=3D 0x03e00008)
: =20
: /*
: - * kdbpeekD(addr) - skip one word starting at 'addr', then read the seco=
: nd word
: + * kdbpeekD(addr) - read double word.
: */
: -#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1)
: +
: +static inline register_t
: +kdbpeekD (uintptr_t addr) {
: +#ifdef __MIPSEL__
: + return ((register_t) kdbpeek ((int *) addr))
: + | (((register_t) kdbpeek ((int *) addr + 1)) << 32);
: +#else
: + return ((register_t) kdbpeek ((int *) addr + 1))
: + | (((register_t) kdbpeek ((int *) addr)) << 32);
: +#endif
This seems wrong. What's wrong with reading the 64-bit quantity
directly?
: +}
: =20
: /*
: * Functions ``special'' enough to print by name
: @@ -140,7 +150,7 @@
: }
: /* check for bad SP: could foul up next frame */
: /*XXX MIPS64 bad: this hard-coded SP is lame */
: - if (sp & 3 || sp < 0x80000000) {
: + if (sp & 3 || (uintptr_t) sp < 0xffffffff80000000ULL) {
This is wrong. sp should be cast to intptr_t to have it still work
with 32-bit debugging. Unsigned sp will be 0x80000000, which will
trigger this case.
: (*printfn) ("SP 0x%x: not in kernel\n", sp);
: ra =3D 0;
: subr =3D 0;
: @@ -181,7 +191,7 @@
: }
: /* check for bad PC */
: /*XXX MIPS64 bad: These hard coded constants are lame */
: - if (pc & 3 || pc < (uintptr_t)0x80000000) {
: + if (pc & 3 || (uintptr_t)pc < 0xffffffff80000000ULL) {
Ditto.
: (*printfn) ("PC 0x%x: not in kernel\n", pc);
: ra =3D 0;
: goto done;
: @@ -303,32 +313,34 @@
: mask |=3D (1 << i.IType.rt);
: switch (i.IType.rt) {
: case 4:/* a0 */
: - args[0] =3D kdbpeekD((int *)(sp + (short)i.IType.imm));
: + args[0] =3D kdbpeekD(sp + (short)i.IType.imm);
This likely is OK.
: valid_args[0] =3D 1;
: break;
: =20
: case 5:/* a1 */
: - args[1] =3D kdbpeekD((int *)(sp + (short)i.IType.imm));
: + args[1] =3D kdbpeekD(sp + (short)i.IType.imm);
: valid_args[1] =3D 1;
: break;
: =20
: case 6:/* a2 */
: - args[2] =3D kdbpeekD((int *)(sp + (short)i.IType.imm));
: + args[2] =3D kdbpeekD(sp + (short)i.IType.imm);
: valid_args[2] =3D 1;
: break;
: =20
: case 7:/* a3 */
: - args[3] =3D kdbpeekD((int *)(sp + (short)i.IType.imm));
: + args[3] =3D kdbpeekD(sp + (short)i.IType.imm);
: valid_args[3] =3D 1;
: break;
: =20
: case 31: /* ra */
: - ra =3D kdbpeekD((int *)(sp + (short)i.IType.imm));
: + ra =3D kdbpeekD(sp + (short)i.IType.imm);
: }
: break;
: =20
: case OP_ADDI:
: case OP_ADDIU:
: + case OP_DADDIU:
: + case OP_DADDI:
: /* look for stack pointer adjustment */
: if (i.IType.rs !=3D 29 || i.IType.rt !=3D 29)
: break;
: @@ -337,17 +349,18 @@
: }
: =20
: done:
: - (*printfn) ("%s+%x (", fn_name(subr), pc - subr);
: + (*printfn) ("%s+%lx (", fn_name(subr), (unsigned long) (pc - subr));
: for (j =3D 0; j < 4; j ++) {
: if (j > 0)
: (*printfn)(",");
: if (valid_args[j])
: - (*printfn)("%x", args[j]);
: + (*printfn)("%lx", (unsigned long) args[j]);
These casts aren't right. We should likely be using intmax_t here and
%j.
: else
: (*printfn)("?");
: }
: =20
: - (*printfn) (") ra %x sp %x sz %d\n", ra, sp, stksize);
: + (*printfn) (") ra %lx sp %lx sz %ld\n", (unsigned long) ra,
: + (unsigned long) sp, (long) stksize);
: =20
These casts aren't right. We should likely be using intmax_t here and
%j.
: if (ra) {
: if (pc =3D=3D ra && stksize =3D=3D 0)
:
More information about the freebsd-mips
mailing list