NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-sh3/56311: GCC 9 and 10 miscompile lint1 for sh3 (improper use of scratch register)



>Number:         56311
>Category:       port-sh3
>Synopsis:       GCC 9 and 10 miscompile lint1 for sh3 (improper use of scratch register)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sh3-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 15 07:55:00 +0000 2021
>Originator:     Rin Okuyama
>Release:        9.99.86
>Organization:
Department of Physics, Meiji University
>Environment:
NetBSD hdlu 9.99.86 NetBSD 9.99.86 (HDL-U) #19: Thu Jul 15 14:37:34 JST 2021  rin@latipes:/sys/arch/landisk/compile/HDL-U landisk
>Description:
GCC 9 and 10 miscompile lint1 for sh3, which results in SIGSEGV:

----
$ lint hello.c
hello.c:
lint: /usr/libexec/lint1 got SIGSEGV
----

This turned out to be due to initdecl() in src/usr.bin/xlint/lint1/decl.c:

----
    88  void
    89  initdecl(void)
    90  {
    91          int i;
    92
    93          /* declaration stack */
    94          dcs = xcalloc(1, sizeof(*dcs));
    95          dcs->d_ctx = EXTERN;
    96          dcs->d_ldlsym = &dcs->d_dlsyms;
    97
    98          /* type information and classification */
    99          inittyp();
...
----

Here, compiled binary fails to initialize dcs->d_ldlsym:

----
$ gdb lint1
...
Reading symbols from ./lint1...
Reading symbols from /home/rin/lint1.debug...
(gdb) b decl.c:130
Breakpoint 1 at 0x407f8a: file /usr/src/usr.bin/xlint/lint1/decl.c, line 130.
(gdb) r hello.c out
Starting program: /home/rin/lint1 hello.c out

Breakpoint 1, initdecl () at /usr/src/usr.bin/xlint/lint1/decl.c:130
130             typetab[UNSIGN].t_tspec = UNSIGN;
(gdb) p dcs
$1 = (dinfo_t *) 0x76fb6000
(gdb) p dcs->d_ldlsym
$2 = (sym_t **) 0x0
----

Note that if initdecl() is compiled with -O0, dcs->d_ldlsym is correctly
initialized.

This failure occurs as follows. objdump for initdecl() is:

----
00407eae <initdecl>:
    407eae:       c6 2f           mov.l   r12,@-r15
    407eb0:       40 c7           mova    407fb4 <initdecl+0x106>,r0
    407eb2:       40 dc           mov.l   407fb4 <initdecl+0x106>,r12     ! 3a9b8
    407eb4:       22 4f           sts.l   pr,@-r15
    407eb6:       0c 3c           add     r0,r12
    407eb8:       3f d1           mov.l   407fb8 <initdecl+0x10a>,r1      ! 96d4
    407eba:       50 e5           mov     #80,r5
    407ebc:       03 01           bsrf    r1
    407ebe:       01 e4           mov     #1,r4
    407ec0:       3e d1           mov.l   407fbc <initdecl+0x10e>,r1      ! 2f0
    407ec2:       03 62           mov     r0,r2
    407ec4:       c3 60           mov     r12,r0
    407ec6:       26 01           mov.l   r2,@(r0,r1)
    407ec8:       01 e1           mov     #1,r1
    407eca:       19 12           mov.l   r1,@(36,r2)
(1) 407ecc:       40 72           add     #64,r2
    407ece:       3c d1           mov.l   407fc0 <initdecl+0x112>,r1      ! 7954
(a) 407ed0:       03 01           bsrf    r1
(2) 407ed2:       21 1c           mov.l   r2,@(4,r12)
...
----

Here, &dcs->d_dlsyms is prepared to r2 at (1), and r2 is stored to
dcs->ldlsym at (2). However, GCC arranges function call to inittyp() at (a).
Since r2 is scratch register, its value is not conserved after return from
inittyp().
>How-To-Repeat:
``lint hello.c'' on sh3.
>Fix:
Not known. As a workaround, compile initdecl() with -O0, with which lint(1)
works just fine on sh3.



Home | Main Index | Thread Index | Old Index