I have gcc-4.1 configured with ../gcc-4.1.0/configure --prefix=/usr
--libexecdir=/usr/lib --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-c99 --enable-long-long --enable-clocale=gnu
--enable-languages=c,c++ --disable-multilib --disable-libstdcxx-pch

The following test generates the checksum of a dummy sun disk label.
cat > test.c << "EOF"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned short __be16;
typedef unsigned int __be32;

struct sun_disklabel {
        unsigned char info[128];   /* Informative text string */
        unsigned char spare0[14];
        struct sun_info {
                unsigned char spare1;
                unsigned char id;
                unsigned char spare2;
                unsigned char flags;
        } infos[8];
        unsigned char spare[246];  /* Boot information etc. */
        __be16 rspeed;     /* Disk rotational speed */
        __be16 pcylcount;  /* Physical cylinder count */
        __be16 sparecyl;   /* extra sects per cylinder */
        unsigned char spare2[4];   /* More magic... */
        __be16 ilfact;     /* Interleave factor */
        __be16 ncyl;       /* Data cylinder count */
        __be16 nacyl;      /* Alt. cylinder count */
        __be16 ntrks;      /* Tracks per cylinder */
        __be16 nsect;      /* Sectors per track */
        unsigned char spare3[4];   /* Even more magic... */
        struct sun_partition {
                __be32 start_cylinder;
                __be32 num_sectors;
        } partitions[8];
        __be16 magic;      /* Magic number */
        __be16 csum;       /* Label xor'd checksum */
};

int main(void)
{
        struct sun_disklabel label;
        __be16 csum, *ush;

        memset(&label, 0xff, sizeof(label));

        ush = ((__be16 *) (&label + 1)) - 1;
        for (csum = 0; ush >= ((__be16 *) &label); )
                csum ^= *ush--;

        printf("Test checksum is %x\n", csum);

        exit(0);
}
EOF

When this test is compiled with 'gcc test.c' or 'gcc -Os test.c' the checksum
is 0. The checksum is supposed to be 0. When the test is compiled with 'gcc -O2
test.c' the checksum is 0xffff. The same goes for -O1 and -O3. Compiling with
-Wall doesn't ouput any warnings. The last known version to work is gcc-4.0.2.

As far as I know the problem is in this loop:
 for (csum = 0; ush >= ((__be16 *) &label); )
The problem also exists if the loop is changed to this:
  while (ush >= ((__be16 *) &label))


-- 
           Summary: Sun disklabel checksum code isn't being generated
                    properly.
           Product: gcc
           Version: 4.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jciccone at gmail dot com
 GCC build triplet: sparc64-unknown-linux-gnu
  GCC host triplet: sparc64-unknown-linux-gnu
GCC target triplet: sparc64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27176

Reply via email to