Jeremy Bowen <[EMAIL PROTECTED]> wrote:
> On Thursday 06 November 2008 10:33:37 am Jeremy Bowen wrote:
> 
> > OK so now I'm playing whack-a-mole with this :-)
> 
> Right I've reconfigured uClibc to use the "old" regex code and have triggered 
> my problem again. I'm using "mdev" from busybox 1.12.0 to generate the 
> problem.
> 
> I have some disassembly of the working and segfaulting code.

Do you know exactly which instruction segfaults?

> This is triggered within the PATFETCH macro in libc/misc/regex/regex_old.c 
> around line #1977. NOTE: I have expanded the macro with additional linefeeds 
> to aid tracing of the issue.
> 
> ...
> #  else /* BYTE */
> #   define PATFETCH(c)                                                        
> \
>   do {                                              \
>       if (p == pend)                                \
>           return REG_EEND;                          \
>     c = (unsigned char) *p++;                                         \
>     if (translate)                                  \
>     {                                               \
> +       dprintf(2, ".");                                           \
>         c = (unsigned char) translate[c];                          \

This looks like something which might trigger the cond-exec bug.
Sometimes, translate[c] would get dereferenced even if translate is
NULL.

>     }                                                              \
>   } while (0)
> #  endif /* WCHAR */
> # endif
> ...
> 
> With the addition of the dprinf() call, the code works.
> Removing the dprintf() and it segfaults.
> 
> This macro is included at about line #2550 of regex_old.c and I have wrapped 
> __asm__ delimiters around the problematic section.
> ...
>     /* Loop through the uncompiled pattern until we're at the end.  */
>     while (p != pend)
>     {
>         __asm__("# AA");
>         PATFETCH (c);
>         __asm__("# FF");
> ...
> 
> Disassembly from avr32-linux-objdump (and listing from gcc -S) follows
> 
> First the standard (segfaulting) version.
> ===========================================================================
> .L143:
>         mov     r8, 32
>         st.w    r3[4], r8
> .L138:
>         ld.w    r4, r3[0]
>         mov     r1, 0
>         mov     r11, 32
>         mov     r2, r1
>         mov     r0, r1
>         stdsp   sp[64], r4
>         stdsp   sp[68], r1
>         stdsp   sp[108], r1
>         stdsp   sp[112], r11
>         bral    .L1114
> .L147:
> #APP
>         # AA
> #NO_APP
>         mov     r10, r9
>         ld.ub   r7, r10++
>         lddsp   r8, sp[60]
>         stdsp   sp[264], r10
>         cp.w    r8, 0
>         breq    .L148
> 
>         ld.ub   r7, r8[r7]
> .L148:

But that's not what happens here. r8 is only dereferenced if it's
non-NULL.

It's somewhat surprising that it decides to fetch the translate pointer
from the stack, though.

> #APP
>         # FF
> #NO_APP
> ...
> -----objdump---------------------------------------------------------------
>      526:       32 0b           mov     r11,32
>      528:       02 92           mov     r2,r1
>      52a:       02 90           mov     r0,r1
>      52c:       51 04           stdsp   sp[0x40],r4
>      52e:       51 11           stdsp   sp[0x44],r1
>      530:       51 b1           stdsp   sp[0x6c],r1
>      532:       51 cb           stdsp   sp[0x70],r11
>      534:       e0 8f 00 00     bral    534 <byte_regex_compile+0xf8>
>      538:       12 9a           mov     r10,r9
>      53a:       15 37           ld.ub   r7,r10++
>      53c:       40 f8           lddsp   r8,sp[0x3c]
>      53e:       54 2a           stdsp   sp[0x108],r10
>      540:       58 08           cp.w    r8,0
>      542:       c0 00           breq    542 <byte_regex_compile+0x106>
>      544:       f0 07 07 07     ld.ub   r7,r8[r7]
> 
> 
> ===========================================================================
> And now the working non-segfaulting version with the call to dprintf()
> 
> .L143:
>         mov     r8, 32
>         st.w    r3[4], r8
> .L138:
>         ld.w    r4, r3[0]
>         mov     r1, 0
>         mov     r9, 32
>         mov     r2, r1
>         stdsp   sp[60], r4
>         stdsp   sp[64], r1
>         stdsp   sp[68], r1
>         stdsp   sp[100], r1
>         stdsp   sp[104], r9
>         bral    .L1129
> .L147:
> #APP
>         # AA
> #NO_APP
>         ld.ub   r7, r8++
>         stdsp   sp[256], r8
>         lddsp   r8, sp[56]
>         cp.w    r8, 0
>         breq    .L148
> 
>         lda.w   r11, .LC9
>         mov     r12, 2
>         call    dprintf
>         lddsp   lr, sp[56]
> 
>         ld.ub   r7, lr[r7]
> .L148:
> #APP
>         # FF
> #NO_APP

Looks essentially identical apart from the call to dprintf and
associated argument setup.

> -----objdump---------------------------------------------------------------
>      52a:       32 09           mov     r9,32
>      52c:       02 92           mov     r2,r1
>      52e:       50 f4           stdsp   sp[0x3c],r4
>      530:       51 01           stdsp   sp[0x40],r1
>      532:       51 11           stdsp   sp[0x44],r1
>      534:       51 91           stdsp   sp[0x64],r1
>      536:       51 a9           stdsp   sp[0x68],r9
>      538:       e0 8f 00 00     bral    538 <byte_regex_compile+0xf8>
>      53c:       11 37           ld.ub   r7,r8++
>      53e:       54 08           stdsp   sp[0x100],r8
>      540:       40 e8           lddsp   r8,sp[0x38]
>      542:       58 08           cp.w    r8,0
>      544:       c0 00           breq    544 <byte_regex_compile+0x104>
>      546:       e0 6b 00 00     mov     r11,0
>      54a:       ec 0b 03 2b     ld.w    r11,r6[r11<<0x2]
>      54e:       30 2c           mov     r12,2
>      550:       e0 6e 00 00     mov     lr,0
>      554:       ec 0e 03 2e     ld.w    lr,r6[lr<<0x2]
>      558:       5d 1e           icall   lr
>      55a:       40 ee           lddsp   lr,sp[0x38]
>      55c:       fc 07 07 07     ld.ub   r7,lr[r7]
> 
> ===========================================================================
> 
> I think this is compiled with -Os which is standard for uClibc.
> 
> I don't know enough about the AVR32 instruction set to spot the problem but 
> again, it feels like a compiler bug to me.

I can't spot the problem either. If you send me the segfaulting binary
and associated core dump in private, I'll have a closer look.

Haavard
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to