Patching p -> scond = q -> scond in /sys/src/cmd/5l/noop.c fixes this 
unfortunate linker bug.

On Sunday, April 28, 2013 10:54:18 PM UTC-7, Paul Patience wrote:
> Mischief reported a crash with on arm with
> 
> winwatch when closing all windows excluding those
> 
> ignored through the -e flag. Cinap_lenrek
> 
> narrowed the problem down to a bug in the 5l
> 
> linker: it generates incorrect code when using
> 
> the conditional operator and dividing.
> 
> A minimal test case is the following:
> 
> 
> 
> term% cat foo.c
> 
> #include <u.h>
> 
> #include <libc.h>
> 
> 
> 
> void
> 
> main(void)
> 
> {
> 
>       int i, j, k;
> 
> 
> 
>       i = 1;
> 
>       j = 0;
> 
>       k = j <= 0 ? 1 : 2/i;
> 
>       print("%d\n", k);
> 
>       exits(nil);
> 
> }
> 
> 
> 
> The output of asm(main) in acid is:
> 
> 
> 
> acid: asm(main)
> 
> main 0x00001020       MOVW.W  R14,#-0x18(R13)
> 
> main+0x4 0x00001024   MOVW    $#0x1,R1
> 
> main+0x8 0x00001028   MOVW    $#0x0,R2
> 
> main+0xc 0x0000102c   CMP.S   $#0x0,R2
> 
> main+0x10 0x00001030  MOVW.LE R1,R3
> 
> main+0x14 0x00001034  MOVW.GT $#0x2,R3
> 
> main+0x18 0x00001038  SUB.GT  $#0x8,R13,R13
> 
> main+0x1c 0x0000103c  MOVW    R1,#0x4(R13)
> 
> main+0x20 0x00001040  MOVW    R3,R11
> 
> main+0x24 0x00001044  BL      _div
> 
> main+0x28 0x00001048  MOVW    R11,R3
> 
> main+0x2c 0x0000104c  ADD     $#0x8,R13,R13
> 
> main+0x30 0x00001050  MOVW    $#0x7080,R0
> 
> main+0x34 0x00001054  MOVW    R3,#0x8(R13)
> 
> main+0x38 0x00001058  BL      print
> 
> main+0x3c 0x0000105c  MOVW    $#0x0,R0
> 
> main+0x40 0x00001060  BL      exits
> 
> main+0x44 0x00001064  RET.P   #0x18(R13)
> 
> 
> 
> The problem is that the division at main+0x24
> 
> happens regardless of the comparison. The output
> 
> from the compiler is correct, however:
> 
> 
> 
> term% 5c -S foo.c
> 
>       TEXT    main+0(SB),0,$20
> 
>       MOVW    $1,R1
> 
>       MOVW    $0,R2
> 
>       CMP     $0,R2,
> 
>       MOVW.LE R1,R3
> 
>       MOVW.GT $2,R3
> 
>       DIV.GT  R1,R3,R3
> 
>       MOVW    $.string<>+0(SB),R0
> 
>       MOVW    R3,8(R13)
> 
>       BL      ,print+0(SB)
> 
>       MOVW    $0,R0
> 
>       BL      ,exits+0(SB)
> 
>       RET     ,
> 
>       DATA    .string<>+0(SB)/8,$"%d\n\z\z\z\z\z"
> 
>       GLOBL   .string<>+0(SB),$8
> 
>       END     ,
> 
> 
> 
> A (temporary) workaround for this is using an
> 
> if-else statement, for which the linker generates
> 
> correct code.
> 
> 
> 
> --
> 
> pap

Reply via email to