From 9ce642f9746dfc29d119d0680b769677e3ea6da6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 27 Oct 2010 15:26:45 +0200 Subject: [PATCH] libbb: introduce and use common crc32 routine function old new delta crc32_block_endian1 - 37 +37 crc32_block_endian0 - 34 +34 global_crc32_table - 8 +8 file_read 82 87 +5 gzip_main 211 214 +3 xz_crc32 40 35 -5 crc32_table 8 - -8 calculate_gunzip_crc 54 34 -20 lzo_crc32 54 25 -29 cksum_main 298 211 -87 ------------------------------------------------------------------------------ (add/remove: 3/1 grow/shrink: 2/4 up/down: 87/-149) Total: -62 bytes Signed-off-by: Denys Vlasenko --- archival/gzip.c | 16 +++++----------- archival/libunarchive/decompress_unxz.c | 14 +++----------- archival/libunarchive/decompress_unzip.c | 5 +---- archival/lzop.c | 22 ++++++---------------- coreutils/cksum.c | 7 +------ include/libbb.h | 7 +++---- libbb/crc32.c | 24 ++++++++++++++++++++++++ miscutils/flash_eraseall.c | 14 +++----------- util-linux/fdisk_gpt.c | 13 +++---------- 9 files changed, 49 insertions(+), 73 deletions(-) diff --git a/archival/gzip.c b/archival/gzip.c index 32528d96b..4d399063d 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -340,7 +340,7 @@ struct globals { ulg bits_sent; /* bit length of the compressed data */ #endif - uint32_t *crc_32_tab; + /*uint32_t *crc_32_tab;*/ uint32_t crc; /* shift register contents */ }; @@ -393,15 +393,9 @@ static void put_32bit(ulg n) * pointer, then initialize the crc shift register contents instead. * Return the current crc in either case. */ -static uint32_t updcrc(uch * s, unsigned n) +static void updcrc(uch * s, unsigned n) { - uint32_t c = G1.crc; - while (n) { - c = G1.crc_32_tab[(uch)(c ^ *s++)] ^ (c >> 8); - n--; - } - G1.crc = c; - return c; + G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table /*G1.crc_32_tab*/); } @@ -2104,8 +2098,8 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) ALLOC(uch, G1.window, 2L * WSIZE); ALLOC(ush, G1.prev, 1L << BITS); - /* Initialise the CRC32 table */ - G1.crc_32_tab = crc32_filltable(NULL, 0); + /* Initialize the CRC32 table */ + global_crc32_table = crc32_filltable(NULL, 0); return bbunpack(argv, pack_gzip, append_ext, "gz"); } diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index faba9ca82..ca427231e 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c @@ -22,17 +22,9 @@ /* We use our own crc32 function */ #define XZ_INTERNAL_CRC32 0 -static uint32_t *crc32_table; static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) { - crc = ~crc; - - while (size != 0) { - crc = crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); - --size; - } - - return ~crc; + return ~crc32_block_endian0(~crc, buf, size, global_crc32_table); } /* We use arch-optimized unaligned accessors */ @@ -53,8 +45,8 @@ unpack_xz_stream(int src_fd, int dst_fd) unsigned char *membuf; IF_DESKTOP(long long) int total = 0; - if (!crc32_table) - crc32_table = crc32_filltable(NULL, /*endian:*/ 0); + if (!global_crc32_table) + global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); memset(&iobuf, 0, sizeof(iobuf)); /* Preload XZ file signature */ diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 20fda9d26..cb8a3d737 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c @@ -925,10 +925,7 @@ static int inflate_block(STATE_PARAM smallint *e) /* Two callsites, both in inflate_get_next_window */ static void calculate_gunzip_crc(STATE_PARAM_ONLY) { - unsigned n; - for (n = 0; n < gunzip_outbuf_count; n++) { - gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8); - } + gunzip_crc = crc32_block_endian0(gunzip_crc, gunzip_window, gunzip_outbuf_count, gunzip_crc_table); gunzip_bytes_out += gunzip_outbuf_count; } diff --git a/archival/lzop.c b/archival/lzop.c index c6e718ad7..acb34fe14 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -393,7 +393,7 @@ typedef struct header_t { } header_t; struct globals { - const uint32_t *lzo_crc32_table; + /*const uint32_t *lzo_crc32_table;*/ chksum_t chksum_in; chksum_t chksum_out; } FIX_ALIASING; @@ -468,19 +468,10 @@ lzo_adler32(uint32_t adler, const uint8_t* buf, unsigned len) static FAST_FUNC uint32_t lzo_crc32(uint32_t c, const uint8_t* buf, unsigned len) { - uint32_t crc; + //if (buf == NULL) - impossible + // return 0; - if (buf == NULL) - return 0; - - crc = ~c; - if (len != 0) do { - crc = G.lzo_crc32_table[(uint8_t)((int)crc ^ *buf)] ^ (crc >> 8); - buf += 1; - len -= 1; - } while (len > 0); - - return ~crc; + return ~crc32_block_endian0(~c, buf, len, global_crc32_table); } /**********************************************************************/ @@ -679,8 +670,7 @@ static NOINLINE smallint lzo_compress(const header_t *h) if (dst_len < src_len) { /* write checksum of compressed block */ if (h->flags & F_ADLER32_C) - write32(lzo_adler32(ADLER32_INIT_VALUE, b2, - dst_len)); + write32(lzo_adler32(ADLER32_INIT_VALUE, b2, dst_len)); if (h->flags & F_CRC32_C) write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); /* write compressed block data */ @@ -1080,6 +1070,6 @@ int lzop_main(int argc UNUSED_PARAM, char **argv) if (applet_name[0] == 'u') option_mask32 |= OPT_DECOMPRESS; - G.lzo_crc32_table = crc32_filltable(NULL, 0); + global_crc32_table = crc32_filltable(NULL, 0); return bbunpack(argv, pack_lzop, make_new_name_lzop, /*unused:*/ NULL); } diff --git a/coreutils/cksum.c b/coreutils/cksum.c index 7bf383e2d..7a37e6add 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c @@ -18,7 +18,6 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) off_t length, filesize; int bytes_read; int exit_code = EXIT_SUCCESS; - uint8_t *cp; #if ENABLE_DESKTOP getopt32(argv, ""); /* coreutils 6.9 compat */ @@ -39,11 +38,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) #define read_buf bb_common_bufsiz1 while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { - cp = (uint8_t *) read_buf; - length += bytes_read; - do { - crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *cp++]; - } while (--bytes_read); + crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); } close(fd); diff --git a/include/libbb.h b/include/libbb.h index d14728ed0..587a5f952 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1543,11 +1543,10 @@ void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; -/* TODO: add global crc32_table pointer and create - * LE and BE functions to calculate crc32 over given bytes. - * Currently we have about five reimplementations... - */ +extern uint32_t *global_crc32_table; uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; +uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC; +uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC; typedef struct masks_labels_t { const char *labels; diff --git a/libbb/crc32.c b/libbb/crc32.c index 520b1ffb9..2cc6ea779 100644 --- a/libbb/crc32.c +++ b/libbb/crc32.c @@ -18,6 +18,8 @@ #include "libbb.h" +uint32_t *global_crc32_table; + uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian) { uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; @@ -40,3 +42,25 @@ uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian) return crc_table - 256; } + +uint32_t FAST_FUNC crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) +{ + const void *end = (uint8_t*)buf + len; + + while (buf != end) { + val = (val << 8) ^ crc_table[(val >> 24) ^ *(uint8_t*)buf]; + buf = (uint8_t*)buf + 1; + } + return val; +} + +uint32_t FAST_FUNC crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) +{ + const void *end = (uint8_t*)buf + len; + + while (buf != end) { + val = crc_table [(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8); + buf = (uint8_t*)buf + 1; + } + return val; +} diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c index 53aad3d52..b832cc1dd 100644 --- a/miscutils/flash_eraseall.c +++ b/miscutils/flash_eraseall.c @@ -42,15 +42,6 @@ but mtd/jffs2-user.h is gone now (at least 2.6.31.6 does not have it anymore) #define cpu_to_je16(v) ((jint16_t){(v)}) #define cpu_to_je32(v) ((jint32_t){(v)}) -static uint32_t crc32(uint32_t val, const void *ss, int len, - uint32_t *crc32_table) -{ - const unsigned char *s = ss; - while (--len >= 0) - val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8); - return val; -} - static void show_progress(mtd_info_t *meminfo, erase_info_t *erase) { printf("\rErasing %u Kibyte @ %x - %2u%% complete.", @@ -131,8 +122,9 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv) cleanmarker.totlen = cpu_to_je32(8); } - cleanmarker.hdr_crc = cpu_to_je32(crc32(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4, - crc32_table)); + cleanmarker.hdr_crc = cpu_to_je32( + crc32_block_endian0(0, &cleanmarker, sizeof(struct jffs2_unknown_node) - 4, crc32_table) + ); } /* Don't want to destroy progress indicator by bb_error_msg's */ diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 98803ec88..4dfb5b227 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c @@ -46,8 +46,6 @@ static unsigned int n_parts; static unsigned int part_array_len; static unsigned int part_entry_len; -static uint32_t *crc32_table; - static inline gpt_partition * gpt_part(int i) { @@ -61,12 +59,7 @@ gpt_part(int i) static uint32_t gpt_crc32(void *buf, int len) { - uint32_t crc = 0xffffffff; - - for (; len > 0; len--, buf++) { - crc = crc32_table[(crc ^ *((char *)buf)) & 0xff] ^ (crc >> 8); - } - return crc ^ 0xffffffff; + return 0xffffffff ^ crc32_block_endian0(0xffffffff, buf, len, global_crc32_table); } static void @@ -160,8 +153,8 @@ check_gpt_label(void) return 0; } - if (!crc32_table) { - crc32_table = crc32_filltable(NULL, 0); + if (!global_crc32_table) { + global_crc32_table = crc32_filltable(NULL, 0); } crc = SWAP_LE32(gpt_hdr->hdr_crc32); -- 2.25.1