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

Reply via email to