This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Wrongfully compiled code


Hello,

I am trying to port eCos into my target on Cygwin environment.

I am encountered next wrongfully compiled code and I am very in deep trouble.
It happens when sending back TCP SYN-ACK packet to peer,
and it happens in
packages\net\bsd_tcpip\current\src\sys\netinet\tcp_output.c
tcp_output()function.


I asked eCos mailing  list first,
but it says it's a problem of compiler per se,
I shoud ask tool chain mailing list.

My target CPU is SH7709S.

I installed toolchain by downloading ecos-install.tcl.
That I got using next command on Cygwin.
$ wget --passive-ftp ftp://ecos.sourceware.org/pub/ecos/ecos-install.tcl

I checked sh-elf-gcc version and it was version 3.2.1.
$ sh-elf-gcc -v
Reading specs from
/opt/ecos/gnutools/sh-elf/bin/../lib/gcc-lib/sh-elf/3.2.1/spe
cs
Configured with:
/local/demonweb/tools/ecos-gnutools-v1.4/r2/sh-elf/cygwin/tar_b
z2/source/gcc-3.2.1/configure --target=sh-elf --prefix=/local/demonweb/tools/eco
s-gnutools-v1.4/r2/sh-elf/cygwin/tar_bz2/opt/ecos/gnutools/sh-elf --enable-langu
ages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-gxx-include-dir=/loc
al/demonweb/tools/ecos-gnutools-v1.4/r2/sh-elf/cygwin/tar_bz2/opt/ecos/gnutools/
sh-elf/sh-elf/include
Thread model: single
gcc version 3.2.1

My compile option is same as eCos CVS downloaded version for se77x9,
       cdl_option CYGBLD_GLOBAL_CFLAGS {
           display "Global compiler flags"
           flavor  data
           no_define
           default_value { CYGHWR_HAL_SH_BIGENDIAN ?
"-D_KERNEL -D__ECOS -mb -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline
-Wundef -Woverloaded-virtual -ggdb -O1 -ffunction-sections -fdata-sections
-fno-rtti -fno-exceptions -fvtable-gc -finit-priority" :
"-D_KERNEL -D__ECOS -ml -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline
-Wundef -Woverloaded-virtual -ggdb -O1 -ffunction-sections -fdata-sections
-fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
           description   "
               This option controls the global compiler flags which
               are used to compile all packages by
               default. Individual packages may define
               options which override these global flags."
       }

       cdl_option CYGBLD_GLOBAL_LDFLAGS {
           display "Global linker flags"
           flavor  data
           no_define
           default_value { CYGHWR_HAL_SH_BIGENDIAN ?
"-mb -m3 -ggdb -nostdlib -Wl,--gc-sections -Wl,-static" :
"-ml -m3 -ggdb -nostdlib -Wl,--gc-sections -Wl,-static" }
           description   "
               This option controls the global linker flags. Individual
               packages may define options which override these global
flags."
       }

CYGHWR_HAL_SH_BIGENDIAN is valid.

I attach eCos C source code,and corresponding mixed source code below.
Please refer to them.

I traced source code using ICE. (numbers are source line numbers)
First,on line 398 hdrlen becomes 0x28.And optlen becomes 4 on line 408.
Althoug it should execute
      512:     hdrlen += optlen;
but looks it passed in C code trace.

And on line
|      643:         m->m_len = hdrlen;      -- hdrlen is still 0x28
hdrlen is 0x28,although it should be 0x2c.

I could have traced same part in mixed source mode,and I discovered it was
wrongfully compiled.
I explain in detail after the source code.
Below are C code source and corresponding mixed source(from 445 line onward
in C source).
-- tcp_output() C source code
      383: send:
      384:     /*
      385:      * Before ESTABLISHED, force sending of initial options
      386:      * unless TCP set not to do any options.
      387:      * NOTE: we assume that the IP/TCP header plus TCP options
      388:      * always fit in a single mbuf, leaving room for a maximum
      389:      * link header, i.e.
      390:      *  max_linkhdr + sizeof (struct tcpiphdr) + optlen <=
MCLBYTES
      391:      */
      392:     optlen = 0;
      393: #ifdef INET6
      394:     if (isipv6)
      395:         hdrlen = sizeof (struct ip6_hdr) + sizeof (struct
tcphdr);
      396:     else
      397: #endif
->     398:     hdrlen = sizeof (struct tcpiphdr);   -- here hdrlen becomes
0x28
|      399:     if (flags & TH_SYN) {
|      400:         tp->snd_nxt = tp->iss;
|      401:         if ((tp->t_flags & TF_NOOPT) == 0) {
      402:             u_short mss;
      403:
|      404:             opt[0] = TCPOPT_MAXSEG;
|      405:             opt[1] = TCPOLEN_MAXSEG;
|      406:             mss = htons((u_short) tcp_mssopt(tp));
|      407:             (void)memcpy(opt + 2, &mss, sizeof(mss));
|      408:             optlen = TCPOLEN_MAXSEG;
      409:
|      410:             if ((tp->t_flags & TF_REQ_SCALE) &&  --428,E"n,O
      411:                 ((flags & TH_ACK) == 0 ||
      412:                 (tp->t_flags & TF_RCVD_SCALE))) {
      413:                 *((u_int32_t *)(opt + optlen)) = htonl(
      414:                     TCPOPT_NOP << 24 |
      415:                     TCPOPT_WINDOW << 16 |
      416:                     TCPOLEN_WINDOW << 8 |
      417:                     tp->request_r_scale);
      418:                 optlen += 4;
      419:             }
      420:         }
      421:     }
      422:
      423:     /*
      424:      * Send a timestamp and echo-reply if this is a SYN and our
side
      425:      * wants to use timestamps (TF_REQ_TSTMP is set) or both our
side
      426:      * and our peer have sent timestamps in our SYN's.
      427:      */
->     428:     if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP
&&
      429:         (flags & TH_RST) == 0 &&
      430:         ((flags & TH_ACK) == 0 ||
      431:          (tp->t_flags & TF_RCVD_TSTMP))) {
      432:         u_int32_t *lp = (u_int32_t *)(opt + optlen);
      433:
      434:         /* Form timestamp option as shown in appendix A of RFC
1323. */
      435:         *lp++ = htonl(TCPOPT_TSTAMP_HDR);
      436:         *lp++ = htonl(ticks);
      437:         *lp   = htonl(tp->ts_recent);
      438:         optlen += TCPOLEN_TSTAMP_APPA;
      439:     }
      440:
      441:     /*
      442:      * Send `CC-family' options if our side wants to use them
(TF_REQ_CC),
      443:      * options are allowed (!TF_NOOPT) and it's not a RST.
      444:      */
->     445:     if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
      446:          (flags & TH_RST) == 0) {
      447:         switch (flags & (TH_SYN|TH_ACK)) {
      448:         /*
      449:          * This is a normal ACK, send CC if we received CC
before
      450:          * from our peer.
      451:          */
      452:         case TH_ACK:
      453:             if (!(tp->t_flags & TF_RCVD_CC))
      454:                 break;
      455:             /*FALLTHROUGH*/
      456:
      457:         /*
      458:          * We can only get here in T/TCP's SYN_SENT* state, when
      459:          * we're a sending a non-SYN segment without waiting for
      460:          * the ACK of our SYN.  A check above assures that we
only
      461:          * do this if our peer understands T/TCP.
      462:          */
      463:         case 0:
      464:             opt[optlen++] = TCPOPT_NOP;
      465:             opt[optlen++] = TCPOPT_NOP;
      466:             opt[optlen++] = TCPOPT_CC;
      467:             opt[optlen++] = TCPOLEN_CC;
      468:             *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
      469:
      470:             optlen += 4;
      471:             break;
      472:
      473:         /*
      474:          * This is our initial SYN, check whether we have to use
      475:          * CC or CC.new.
      476:          */
      477:         case TH_SYN:
      478:             opt[optlen++] = TCPOPT_NOP;
      479:             opt[optlen++] = TCPOPT_NOP;
      480:             opt[optlen++] = tp->t_flags & TF_SENDCCNEW ?
      481:                         TCPOPT_CCNEW : TCPOPT_CC;
      482:             opt[optlen++] = TCPOLEN_CC;
      483:             *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
      484:             optlen += 4;
      485:             break;
      486:
      487:         /*
      488:          * This is a SYN,ACK; send CC and CC.echo if we received
      489:          * CC from our peer.
      490:          */
      491:         case (TH_SYN|TH_ACK):
      492:             if (tp->t_flags & TF_RCVD_CC) {
      493:                 opt[optlen++] = TCPOPT_NOP;
      494:                 opt[optlen++] = TCPOPT_NOP;
      495:                 opt[optlen++] = TCPOPT_CC;
      496:                 opt[optlen++] = TCPOLEN_CC;
      497:                 *(u_int32_t *)&opt[optlen] =
      498:                     htonl(tp->cc_send);
      499:                 optlen += 4;
      500:                 opt[optlen++] = TCPOPT_NOP;
      501:                 opt[optlen++] = TCPOPT_NOP;
      502:                 opt[optlen++] = TCPOPT_CCECHO;
      503:                 opt[optlen++] = TCPOLEN_CC;
      504:                 *(u_int32_t *)&opt[optlen] =
      505:                     htonl(tp->cc_recv);
      506:                 optlen += 4;
      507:             }
      508:             break;
      509:         }
      510:     }
      511:
      512:     hdrlen += optlen;

and try to convert m->m_len,
->     642:         m->m_data += max_linkhdr;
|      643:         m->m_len = hdrlen;        -- hdrlen is still 0x28

--- Mix source code corresponding to C code
tcp_output.c (445):    if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC
&&
           8C048BA4            51AA      MOV.L      @(28,R10 tp ),R1
           8C048BA6            9214      MOV.W      8C048BD2,R2
           8C048BA8            2129      AND        R2,R1
           8C048BAA            72F8      ADD        #F8,R2
           8C048BAC            3120      CMP/EQ     R2,R1
           8C048BAE            8F51      BF/S
4              ->1
           8C048BB0            60D3      MOV        R13 flags ,R0
           8C048BB2            C904      AND        #4,R0
           8C048BB4            2008      TST        R0,R0
           8C048BB6            8F4D      BF/S       8C048C54
           8C048BB8            E212      MOV        #12,R2
tcp_output.c (447):        switch (flags & (TH_SYN|TH_ACK)) {
           8C048BBA            22D9      AND        R13 flags ,R2
           8C048BBC            E112      MOV        #12,R1
           8C048BBE            3216      CMP/HI     R1,R2
           8C048BC0            8948      BT         8C048C54
           8C048BC2            C70A      MOVA       8C048BEC,R0
           8C048BC4            322C      ADD        R2,R2
           8C048BC6            012D      MOV.W      @(R0,R2),R1
           8C048BC8            0123      BRAF       R1
           8C048BCA            0009      NOP
           8C048BCC            00AC      MOV.B      @(R0,R10 tp ),R0
           8C048BCE            0080      ???
           8C048BD0            0100      ???
           8C048BD2            2008      TST        R0,R0
           8C048BD4            8C02      ???
           8C048BD6            9D60      MOV.W      8C048C9A,R13 flags
           8C048BD8            8C04      ???
           8C048BDA            94A0      MOV.W      8C048D1E,R4
           8C048BDC            8C04      ???
           8C048BDE            8600      ???
           8C048BE0            0103      BSRF       R1
           8C048BE2            0300      ???
           8C048BE4            0101      ???
           8C048BE6            080A      STS        MACH,R8 error
           8C048BE8            8C02      ???
           8C048BEA            8BF0      BF         8C048BCE
           8C048BEC            005C      MOV.B      @(R0,R5),R0
           8C048BEE            0124      MOV.B      R2,@(R0,R1)
           8C048BF0            0094      MOV.B      R9,@(R0,R0)
           8C048BF2            0124      MOV.B      R2,@(R0,R1)
           8C048BF4            0124      MOV.B      R2,@(R0,R1)
           8C048BF6            0124      MOV.B      R2,@(R0,R1)
           8C048BF8            0124      MOV.B      R2,@(R0,R1)
           8C048BFA            0124      MOV.B      R2,@(R0,R1)
           8C048BFC            0124      MOV.B      R2,@(R0,R1)
           8C048BFE            0124      MOV.B      R2,@(R0,R1)
           8C048C00            0124      MOV.B      R2,@(R0,R1)
           8C048C02            0124      MOV.B      R2,@(R0,R1)
           8C048C04            0124      MOV.B      R2,@(R0,R1)
           8C048C06            0124      MOV.B      R2,@(R0,R1)
           8C048C08            0124      MOV.B      R2,@(R0,R1)
           8C048C0A            0124      MOV.B      R2,@(R0,R1)
           8C048C0C            0054      MOV.B      R5,@(R0,R0)
           8C048C0E            0124      MOV.B      R2,@(R0,R1)
           8C048C10            00D4      MOV.B      R13 flags ,@(R0,R0)
           8C048C12            0009      NOP
           8C048C14            0009      NOP
           8C048C16            0009      NOP
           8C048C18            0009      NOP
           8C048C1A            0009      NOP
           8C048C1C            0009      NOP
           8C048C1E            0009      NOP
tcp_output.c (453):            if (!(tp->t_flags & TF_RCVD_CC))
           8C048C20            52AA      MOV.L      @(28,R10 tp ),R2
           8C048C22            91B2      MOV.W      8C048D8A,R1
           8C048C24            2218      TST        R1,R2
           8C048C26            8963      BT         8C048CF0
tcp_output.c (464):            opt[optlen++] = TCPOPT_NOP;
           8C048C28            E101      MOV        #1,R1
           8C048C2A            E048      MOV        #48,R0
           8C048C2C            00EE      MOV.L      @(R0,R14),R0
           8C048C2E            0E14      MOV.B      R1,@(R0,R14)
           8C048C30            7001      ADD        #1,R0
           8C048C32            E240      MOV        #40,R2
           8C048C34            32EC      ADD        R14,R2
tcp_output.c (465):            opt[optlen++] = TCPOPT_NOP;
           8C048C36            0E14      MOV.B      R1,@(R0,R14)
           8C048C38            7001      ADD        #1,R0
tcp_output.c (466):            opt[optlen++] = TCPOPT_CC;
           8C048C3A            E10B      MOV        #B,R1
           8C048C3C            0E14      MOV.B      R1,@(R0,R14)
           8C048C3E            7001      ADD        #1,R0
tcp_output.c (467):            opt[optlen++] = TCPOLEN_CC;
           8C048C40            E106      MOV        #6,R1
           8C048C42            0E14      MOV.B      R1,@(R0,R14)
           8C048C44            7001      ADD        #1,R0
           8C048C46            1202      MOV.L      R0,@(8,R2)
tcp_output.c (468):            *(u_int32_t *)&opt[optlen] =
htonl(tp->cc_send);
           8C048C48            90A0      MOV.W      8C048D8C,R0
           8C048C4A            01AE      MOV.L      @(R0,R10 tp ),R1
           8C048C4C            5022      MOV.L      @(8,R2),R0
           8C048C4E            0E16      MOV.L      R1,@(R0,R14)
tcp_output.c (470):            optlen += 4;
           8C048C50            7004      ADD        #4,R0
           8C048C52            1202      MOV.L      R0,@(8,R2)
->1         8C048C54            A04D      BRA        8C048CF2   ->2
tcp_output.c (471):            break;
           8C048C56            E740      MOV        #40,R7
           8C048C58            0009      NOP
           8C048C5A            0009      NOP
           8C048C5C            0009      NOP
           8C048C5E            0009      NOP
tcp_output.c (478):            opt[optlen++] = TCPOPT_NOP;
           8C048C60            E101      MOV        #1,R1
           8C048C62            E048      MOV        #48,R0
           8C048C64            00EE      MOV.L      @(R0,R14),R0
           8C048C66            0E14      MOV.B      R1,@(R0,R14)
           8C048C68            7001      ADD        #1,R0
tcp_output.c (479):            opt[optlen++] = TCPOPT_NOP;
           8C048C6A            0E14      MOV.B      R1,@(R0,R14)
           8C048C6C            7001      ADD        #1,R0
tcp_output.c (480):            opt[optlen++] = tp->t_flags & TF_SENDCCNEW ?
           8C048C6E            6303      MOV        R0,R3 ipoptlen
           8C048C70            33EC      ADD        R14,R3 ipoptlen
           8C048C72            7001      ADD        #1,R0
           8C048C74            52AA      MOV.L      @(28,R10 tp ),R2
           8C048C76            D146      MOV.L      8C048D90,R1
           8C048C78            2218      TST        R1,R2
           8C048C7A            0129      MOVT       R1
           8C048C7C            611B      NEG        R1,R1
           8C048C7E            710C      ADD        #C,R1
           8C048C80            2310      MOV.B      R1,@R3 ipoptlen
tcp_output.c (482):            opt[optlen++] = TCPOLEN_CC;
           8C048C82            E106      MOV        #6,R1
           8C048C84            0E14      MOV.B      R1,@(R0,R14)
           8C048C86            7001      ADD        #1,R0
           8C048C88            E640      MOV        #40,R6
           8C048C8A            36EC      ADD        R14,R6
           8C048C8C            1602      MOV.L      R0,@(8,R6)
tcp_output.c (483):            *(u_int32_t *)&opt[optlen] =
htonl(tp->cc_send);
           8C048C8E            907D      MOV.W      8C048D8C,R0
           8C048C90            01AE      MOV.L      @(R0,R10 tp ),R1
           8C048C92            A029      BRA        8C048CE8
tcp_output.c (485):            break;
           8C048C94            5062      MOV.L      @(8,R6),R0
           8C048C96            0009      NOP
           8C048C98            0009      NOP
           8C048C9A            0009      NOP
           8C048C9C            0009      NOP
           8C048C9E            0009      NOP
tcp_output.c (492):            if (tp->t_flags & TF_RCVD_CC) {
           8C048CA0            52AA      MOV.L      @(28,R10 tp ),R2
           8C048CA2            9172      MOV.W      8C048D8A,R1
           8C048CA4            2218      TST        R1,R2
           8C048CA6            8D24      BT/S       8C048CF2
           8C048CA8            E740      MOV        #40,R7
tcp_output.c (493):                opt[optlen++] = TCPOPT_NOP;
           8C048CAA            E201      MOV        #1,R2
           8C048CAC            E048      MOV        #48,R0
           8C048CAE            00EE      MOV.L      @(R0,R14),R0
           8C048CB0            0E24      MOV.B      R2,@(R0,R14)
           8C048CB2            7001      ADD        #1,R0
tcp_output.c (494):                opt[optlen++] = TCPOPT_NOP;
           8C048CB4            0E24      MOV.B      R2,@(R0,R14)
           8C048CB6            7001      ADD        #1,R0
tcp_output.c (495):                opt[optlen++] = TCPOPT_CC;
           8C048CB8            E10B      MOV        #B,R1
           8C048CBA            0E14      MOV.B      R1,@(R0,R14)
           8C048CBC            7001      ADD        #1,R0
           8C048CBE            E640      MOV        #40,R6
           8C048CC0            36EC      ADD        R14,R6
tcp_output.c (496):                opt[optlen++] = TCPOLEN_CC;
           8C048CC2            E706      MOV        #6,R7
           8C048CC4            0E74      MOV.B      R7,@(R0,R14)
           8C048CC6            7001      ADD        #1,R0
tcp_output.c (497):                *(u_int32_t *)&opt[optlen] =
           8C048CC8            9160      MOV.W      8C048D8C,R1
           8C048CCA            63A3      MOV        R10 tp ,R3 ipoptlen
           8C048CCC            331C      ADD        R1,R3 ipoptlen
           8C048CCE            5130      MOV.L      @(0,R3 ipoptlen ),R1
           8C048CD0            0E16      MOV.L      R1,@(R0,R14)
tcp_output.c (499):                optlen += 4;
           8C048CD2            7004      ADD        #4,R0
tcp_output.c (500):                opt[optlen++] = TCPOPT_NOP;
           8C048CD4            0E24      MOV.B      R2,@(R0,R14)
           8C048CD6            7001      ADD        #1,R0
tcp_output.c (501):                opt[optlen++] = TCPOPT_NOP;
           8C048CD8            0E24      MOV.B      R2,@(R0,R14)
           8C048CDA            7001      ADD        #1,R0
tcp_output.c (502):                opt[optlen++] = TCPOPT_CCECHO;
           8C048CDC            E10D      MOV        #D,R1
           8C048CDE            0E14      MOV.B      R1,@(R0,R14)
           8C048CE0            7001      ADD        #1,R0
tcp_output.c (503):                opt[optlen++] = TCPOLEN_CC;
           8C048CE2            0E74      MOV.B      R7,@(R0,R14)
           8C048CE4            7001      ADD        #1,R0
tcp_output.c (504):                *(u_int32_t *)&opt[optlen] =
           8C048CE6            5131      MOV.L      @(4,R3 ipoptlen ),R1
           8C048CE8            0E16      MOV.L      R1,@(R0,R14)
tcp_output.c (506):                optlen += 4;
           8C048CEA            7004      ADD        #4,R0
           8C048CEC            1602      MOV.L      R0,@(8,R6)
           8C048CEE            0009      NOP
tcp_output.c (512):    hdrlen += optlen;
           8C048CF0            E740      MOV        #40,R7
->2         8C048CF2            37EC      ADD        R14,R7
           8C048CF4            5073      MOV.L      @(C,R7),R0
           8C048CF6            5772      MOV.L      @(8,R7),R7
           8C048CF8            307C      ADD        R7,R0
           8C048CFA            1703      MOV.L      R0,@(C,R7)
tcp_output.c (520):    if (tp->t_inpcb->inp_options) {
           8C048CFC            51A8      MOV.L      @(20,R10 tp ),R1
           8C048CFE            9046      MOV.W      8C048D8E,R0
           8C048D00            011E      MOV.L      @(R0,R1),R1
           8C048D02            2118      TST        R1,R1
           8C048D04            8904      BT         8C048D10
           8C048D06            5113      MOV.L      @(C,R1),R1
tcp_output.c (521):        ipoptlen = tp->t_inpcb->inp_options->m_len -

In detail.
Like I said,at line-445 hdrlen is 0x28,and optlen is 4.
After that it jump to address 8C048CF2(->2).

About @(disp:4,Rn) assembler operation,next is from SH assembler manual,
"The effective address is Rn plus a 4-bit displacement
(disp). The value of disp is zero-extended, and
remains the same for a byte operation, is doubled for
a word operation, and is quadrupled for a longword
operation."

When jumped to 8C048CF2, R14=8c081458,R7=00000040.
Added,R7 becomes 8c081498.
After executing (MOV.L  @(C,R7),R0),R0 becomes 0x28.
But here it acts qeerly,according to manual,0x28 should be retrieved
from 8c081498+c*4=8c0814c8, but really it was retreived from 8c0814a4.
It looks there's no extension according to operand size.But this is minor
point.
Anyway,after executing next line(MOV.L      @(8,R7),R7),R7 becomes 4.
By (ADD R7,R0),R0 becomes 0x2c,this is expected value for hdrlen.
But,by (MOV.L R0,@(C,R7)),content of R0 is reserved into 0x00000010.(really
it can't be written).
Content of hdrlen(8c0814a4) remains 0x28.

I executed without ICE but resulted in IP packet size being 0x28,although it
should be 0x2c.

I am perplexed why this phenomenon happens.
Please enlighten me what do you think causes this mishappening.

My ICE works on Windows so I would like to develop on Cygwin environment.

I bessech you to help me.
Thanks in advance.

Masahiro Ariga


-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]