[OpenBIOS] memory corruption with "read" $call-method (sparc32)
Mark Cave-Ayland
mark.cave-ayland at siriusit.co.uk
Wed Apr 7 16:17:57 UTC 2010
Artyom Tarasenko wrote:
> Breakpoint 4, obp_devread (dev_desc=-2400864, buf=0xf00a30ec "\240",
> nbytes=8192) at ../arch/sparc32/romvec.c:314
> 314 PUSH((int)buf);
> (gdb) next
> 315 PUSH(nbytes);
> (gdb) next
> 316 push_str("read");
> (gdb) next
> 317 PUSH(dev_desc);
> (gdb) next
> 318 fword("$call-method");
> // just in case
> (gdb) info registers
> g0 0x0 0
> g1 0x4c 76
> g2 0xffd4f1b0 -2821712
> g3 0x13 19
> g4 0xffdb5da0 -2400864
> g5 0x0 0
> g6 0x0 0
> g7 0x0 0
> o0 0xffdb5da0 -2400864
> o1 0x0 0
> o2 0xf00a30ec -267767572
> o3 0x20 32
> o4 0x10 16
> o5 0x0 0
> sp 0x125fb0 0x125fb0
> o7 0xffd05eb0 -3121488
> l0 0x4401dc4 71310788
> l1 0x10e6dc 1107676
> l2 0x107388 1078152
> l3 0x40 64
> l4 0x80 128
> l5 0x0 0
> l6 0x0 0
> l7 0x0 0
> i0 0xffdb5da0 -2400864
> i1 0xf00a30ec -267767572
> i2 0x2000 8192
> i3 0xfffffffc -4
> i4 0x20 32
> i5 0x10f444 1111108
> fp 0x126020 0x126020
> i7 0x10e88c 1108108
> y 0x800 2048
> psr 0x4401de4 [ #2 ET PS S #8 #10 #11 EF #22 #26 ]
> wim 0x40 64
> tbr 0xffd00060 -3145632
> pc 0xffd05eb8 0xffd05eb8 <obp_devread+80>
> npc 0xffd05ebc 0xffd05ebc <obp_devread+84>
> fsr 0x80000 [ #19 ]
> csr 0x0 0
>
> // here resides Solaris's printf:
>
> (gdb) disas 0x00104798, 0x001047c0
> Dump of assembler code from 0x104798 to 0x1047c0:
> 0x00104798: save %sp, -96, %sp
> 0x0010479c: st %i1, [ %fp + 0x48 ]
> 0x001047a0: mov %i0, %o0
> 0x001047a4: st %i2, [ %fp + 0x4c ]
> 0x001047a8: add %fp, 0x48, %o1
> 0x001047ac: st %i3, [ %fp + 0x50 ]
> 0x001047b0: st %i4, [ %fp + 0x54 ]
> 0x001047b4: call 0x10f4a8
> 0x001047b8: st %i5, [ %fp + 0x58 ]
> 0x001047bc: ret
> End of assembler dump.
> (gdb) next
> 319 ret = POP();
>
> // Oooops, not anymore
>
> (gdb) disas 0x00104798, 0x001047c0
> Dump of assembler code from 0x104798 to 0x1047c0:
> 0x00104798: bne,a 0x1046bc
> 0x0010479c: ld [ %i0 + 0x14 ], %o0
> 0x001047a0: ld [ %i1 + 0x10 ], %i4
> 0x001047a4: cmp %i4, %i2
> 0x001047a8: be 0x104894
> 0x001047ac: nop
> 0x001047b0: ld [ %i4 + 0x10 ], %o0
> 0x001047b4: call 0x1048fc
> 0x001047b8: nop
> 0x001047bc: mov %o0, %i1
> End of assembler dump.
>
> reading 8192 bytes into the address 0xf00a30ec corrupts 0x00104798.
Hmmm it may be interesting to see on which device the read is being
issued. Inside obp_devread add something like the following:
ucell ihandle;
ihandle = ih_to_phandle(dev_desc);
printk("### phandle: " FMT_ucellx\n");
This will convert the device descriptor (which appears to be an ihandle
or device instance in OF) into a phandle or package handle and display
it on the console.
If you then compare the phandle with the output of "show-devs" from the
Forth console then you can work out which device, and hence which driver
is being used. Note that there was an issue in the SPARC64 CIF related
to C argument order versus Forth stack order so you may wish to verify
the order under SPARC32 aswell.
> Is there an easy way to see from gdb where the both addresses are
> mapped to? "map?" seems to be not implemented in the OpenBIOS.
To see all of the memory allocations/deallocations and mappings then you
want to set CONFIG_DEBUG_OFMEM to true in
config/examples/cross-sparc32.xml and rebuild. For the low level stuff
(e.g. interacting with the virtual qemu hardware) then take a look at
defining CONFIG_DEBUG_MEM in arch/sparc32/lib.c and going from there.
HTH,
Mark.
--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
More information about the OpenBIOS
mailing list