1  /* Reduced from coreutils's cksum.c: cksum_slice8 */
       2  
       3  typedef long unsigned int size_t;
       4  typedef unsigned int __uint32_t;
       5  typedef unsigned long int __uintmax_t;
       6  typedef struct _IO_FILE FILE;
       7  extern size_t
       8  fread_unlocked(void* __restrict __ptr,
       9                 size_t __size,
      10                 size_t __n,
      11                 FILE* __restrict __stream);
      12  extern int
      13  feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__));
      14  extern int
      15  ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__));
      16  static __inline __uint32_t
      17  __bswap_32(__uint32_t __bsx)
      18  {
      19  
      20    return __builtin_bswap32(__bsx);
      21  }
      22  typedef __uint32_t uint32_t;
      23  typedef unsigned long int uint_fast32_t;
      24  typedef __uintmax_t uintmax_t;
      25  extern int*
      26  __errno_location(void) __attribute__((__nothrow__, __leaf__))
      27  __attribute__((__const__));
      28  extern uint_fast32_t const crctab[8][256];
      29  
      30  static _Bool
      31  cksum_slice8(FILE* fp, uint_fast32_t* crc_out, uintmax_t* length_out)
      32  {
      33    uint32_t buf[(1 << 16) / sizeof(uint32_t)];
      34    uint_fast32_t crc = 0;
      35    uintmax_t length = 0;
      36    size_t bytes_read;
      37  
      38    if (!fp || !crc_out || !length_out)
      39      return 0;
      40  
      41    while ((bytes_read = fread_unlocked(buf, 1, (1 << 16), fp)) > 0) {
      42      uint32_t* datap;
      43  
      44      if (length + bytes_read < length) {
      45  
      46        (*__errno_location()) = 75;
      47        return 0;
      48      }
      49      length += bytes_read;
      50  
      51      if (bytes_read == 0) {
      52        if (ferror_unlocked(fp))
      53          return 0;
      54      }
      55  
      56      datap = (uint32_t*)buf;
      57      while (bytes_read >= 8) {
      58        uint32_t first = *datap++, second = *datap++; /* { dg-bogus "use of uninitialized value" "PR analyzer/108664" } */
      59        crc ^= __bswap_32(first);
      60        second = __bswap_32(second);
      61        crc =
      62          (crctab[7][(crc >> 24) & 0xFF] ^ crctab[6][(crc >> 16) & 0xFF] ^
      63           crctab[5][(crc >> 8) & 0xFF] ^ crctab[4][(crc)&0xFF] ^
      64           crctab[3][(second >> 24) & 0xFF] ^ crctab[2][(second >> 16) & 0xFF] ^
      65           crctab[1][(second >> 8) & 0xFF] ^ crctab[0][(second)&0xFF]);
      66        bytes_read -= 8;
      67      }
      68  
      69      unsigned char* cp = (unsigned char*)datap;
      70      while (bytes_read--)
      71        crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ *cp++) & 0xFF];
      72      if (feof_unlocked(fp))
      73        break;
      74    }
      75  
      76    *crc_out = crc;
      77    *length_out = length;
      78  
      79    return 1;
      80  }