Is virtual memory reliable beyond suspicion 2.2.17-rmk1 ?
[sorry about the length of the following]
I'm trying to debug
int
Perl_runops_standard(void )
{
extern int Perl___notused ;
while ((PL_op = (* PL_op->op_ppaddr ) ( ))) {
(void)0 ;
}
(PL_tainted = (0) ) ;
return 0;
}
Dump of assembler code for function Perl_runops_standard:
0x205db80 <Perl_runops_standard>: mov r12, sp
0x205db84 <Perl_runops_standard+4>: stmdb sp!, {r4, r11, r12, lr, pc}
0x205db88 <Perl_runops_standard+8>: sub r11, r12, #4 ; 0x4
0x205db8c <Perl_runops_standard+12>:
ldr r4, [pc, #24] ; 0x205dbb8 <Perl_runops_standard+56>
0x205db90 <Perl_runops_standard+16>: ldr r3, [r4]
0x205db94 <Perl_runops_standard+20>: mov lr, pc
0x205db98 <Perl_runops_standard+24>: ldr pc, [r3, #8]
0x205db9c <Perl_runops_standard+28>: mov r2, r0
0x205dba0 <Perl_runops_standard+32>: cmp r2, #0 ; 0x0
0x205dba4 <Perl_runops_standard+36>: str r2, [r4]
0x205dba8 <Perl_runops_standard+40>:
bne 0x205db90 <Perl_runops_standard+16>
0x205dbac <Perl_runops_standard+44>:
ldr r3, [pc, #8] ; 0x205dbbc <Perl_runops_standard+60>
0x205dbb0 <Perl_runops_standard+48>: strb r2, [r3]
0x205dbb4 <Perl_runops_standard+52>: ldmdb r11, {r4, r11, sp, pc}
0x205dbb8 <Perl_runops_standard+56>: andeq r3, sp, #262144 ; 0x40000
0x205dbbc <Perl_runops_standard+60>:
andeq r3, sp, #1179648 ; 0x120000
which is SEGVing when it executes
ldr pc, [r3, #8]
and sets PC to 0.
The reason I ask is
(gdb) info registers
r0 0x20e0250 34472528
r1 0x0 0
r2 0x20d3ae0 34421472
r3 0x20d3950 34421072
r4 0x20d3a40 34421312
r5 0x0 0
r6 0x20d5390 34427792
r7 0x20d3a40 34421312
r8 0x0 0
r9 0x20e0228 34472488
r10 0x0 0
r11 0xbffff350 -1073745072
r12 0xbffff2e4 -1073745180
sp 0xbffff340 -1073745088
lr 0x205db9c 33938332
pc 0x205db9c 33938332
r4 is correct:
(gdb) x Perl_runops_standard+56
0x205dbb8 <Perl_runops_standard+56>: 0x020d3a40
so r3 SHOULD be 0x020d3a40, and
0x20d3a40 <PL_op>: 0x020e0468
(gdb) x 0x020e0468 + 8
0x20e0470: 0x0208dc54
(gdb) info symbol 0x0208dc54
Perl_pp_leaveeval in section .text
(Perl_pp_leaveeval is a plausible function taking void returning int)
which would be correct.
BUT r3 is 0x20d3950 (and I can't see how it got it). and this leads to:
(gdb) x 0x20d3950
0x20d3950 <PL_stack_sp>: 0x020d5394
(gdb) x 0x20d3950 + 8
0x20d3958 <PL_reg_magic>: 0x00000000
and there's my 0 that PC gets loaded with.
So is that ldr r3, [r4]
page faulting, and loading garbage into r3 on return?
[or getting garbage from the D cache, as the page ought to be live 'cos we're
executing it]
It's the only thing that seems to be left, as I can't spot what's
wrong with the above digging in gdb.
Nicholas Clark
PS gcc -O2 using "mov r2, r0; cmp r0, #0" rather than "movs r2, r0" :-(
_______________________________________________
http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm