1b725ae77Skettenis /*
2b725ae77Skettenis * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis *
4b725ae77Skettenis * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis * software.
7b725ae77Skettenis */
8b725ae77Skettenis
9b725ae77Skettenis /* -*-C-*-
10b725ae77Skettenis *
11*63addd46Skettenis * $Revision: 1.3 $
12*63addd46Skettenis * $Date: 2004/12/27 14:00:54 $
13b725ae77Skettenis *
14b725ae77Skettenis *
15b725ae77Skettenis * crc.c - provides some "standard" CRC calculation routines.
16b725ae77Skettenis *
17b725ae77Skettenis */
18b725ae77Skettenis #include "crc.h" /* describes this code */
19b725ae77Skettenis
20b725ae77Skettenis /**********************************************************************/
21b725ae77Skettenis
22b725ae77Skettenis /*
23b725ae77Skettenis * crc32 IEEE-802.3 32bit CRC
24b725ae77Skettenis * ----- --------------------
25b725ae77Skettenis */
26b725ae77Skettenis
27b725ae77Skettenis /* This table was generated by the "crctable" program */
28b725ae77Skettenis static const unsigned int crc32table[256] = {
29b725ae77Skettenis /* 0x00 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
30b725ae77Skettenis /* 0x04 */ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
31b725ae77Skettenis /* 0x08 */ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
32b725ae77Skettenis /* 0x0C */ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
33b725ae77Skettenis /* 0x10 */ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
34b725ae77Skettenis /* 0x14 */ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
35b725ae77Skettenis /* 0x18 */ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
36b725ae77Skettenis /* 0x1C */ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
37b725ae77Skettenis /* 0x20 */ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
38b725ae77Skettenis /* 0x24 */ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
39b725ae77Skettenis /* 0x28 */ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
40b725ae77Skettenis /* 0x2C */ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
41b725ae77Skettenis /* 0x30 */ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
42b725ae77Skettenis /* 0x34 */ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
43b725ae77Skettenis /* 0x38 */ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
44b725ae77Skettenis /* 0x3C */ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
45b725ae77Skettenis /* 0x40 */ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
46b725ae77Skettenis /* 0x44 */ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
47b725ae77Skettenis /* 0x48 */ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
48b725ae77Skettenis /* 0x4C */ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
49b725ae77Skettenis /* 0x50 */ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
50b725ae77Skettenis /* 0x54 */ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
51b725ae77Skettenis /* 0x58 */ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
52b725ae77Skettenis /* 0x5C */ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
53b725ae77Skettenis /* 0x60 */ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
54b725ae77Skettenis /* 0x64 */ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
55b725ae77Skettenis /* 0x68 */ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
56b725ae77Skettenis /* 0x6C */ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
57b725ae77Skettenis /* 0x70 */ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
58b725ae77Skettenis /* 0x74 */ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
59b725ae77Skettenis /* 0x78 */ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
60b725ae77Skettenis /* 0x7C */ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
61b725ae77Skettenis /* 0x80 */ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
62b725ae77Skettenis /* 0x84 */ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
63b725ae77Skettenis /* 0x88 */ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
64b725ae77Skettenis /* 0x8C */ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
65b725ae77Skettenis /* 0x90 */ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
66b725ae77Skettenis /* 0x94 */ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
67b725ae77Skettenis /* 0x98 */ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
68b725ae77Skettenis /* 0x9C */ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
69b725ae77Skettenis /* 0xA0 */ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
70b725ae77Skettenis /* 0xA4 */ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
71b725ae77Skettenis /* 0xA8 */ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
72b725ae77Skettenis /* 0xAC */ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
73b725ae77Skettenis /* 0xB0 */ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
74b725ae77Skettenis /* 0xB4 */ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
75b725ae77Skettenis /* 0xB8 */ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
76b725ae77Skettenis /* 0xBC */ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
77b725ae77Skettenis /* 0xC0 */ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
78b725ae77Skettenis /* 0xC4 */ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
79b725ae77Skettenis /* 0xC8 */ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
80b725ae77Skettenis /* 0xCC */ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
81b725ae77Skettenis /* 0xD0 */ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
82b725ae77Skettenis /* 0xD4 */ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
83b725ae77Skettenis /* 0xD8 */ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
84b725ae77Skettenis /* 0xDC */ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
85b725ae77Skettenis /* 0xE0 */ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
86b725ae77Skettenis /* 0xE4 */ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
87b725ae77Skettenis /* 0xE8 */ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
88b725ae77Skettenis /* 0xEC */ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
89b725ae77Skettenis /* 0xF0 */ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
90b725ae77Skettenis /* 0xF4 */ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
91b725ae77Skettenis /* 0xF8 */ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
92b725ae77Skettenis /* 0xFC */ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
93b725ae77Skettenis };
crc32(unsigned char * address,unsigned int size,unsigned int crc)94b725ae77Skettenis unsigned int crc32(unsigned char *address, unsigned int size, unsigned int crc)
95b725ae77Skettenis {
96b725ae77Skettenis #if 0
97b725ae77Skettenis /* FAST, but bigger and only good for word-aligned data */
98b725ae77Skettenis unsigned int *daddr = (unsigned int *)address;
99b725ae77Skettenis unsigned int data = FALSE; /* little-endian by default */
100b725ae77Skettenis
101b725ae77Skettenis /*
102b725ae77Skettenis * TODO: We should really get the current processor big- or
103b725ae77Skettenis * little-endian state and set "data" accordingly.
104b725ae77Skettenis */
105b725ae77Skettenis
106b725ae77Skettenis /* Perform word loop to save on memory accesses */
107b725ae77Skettenis if (data)
108b725ae77Skettenis /* big-endian */
109b725ae77Skettenis for (; (size > 0); size -= sizeof(unsigned int))
110b725ae77Skettenis {
111b725ae77Skettenis data = *daddr++;
112b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
113b725ae77Skettenis crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
114b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
115b725ae77Skettenis crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
116b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
117b725ae77Skettenis crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
118b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
119b725ae77Skettenis crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
120b725ae77Skettenis }
121b725ae77Skettenis else
122b725ae77Skettenis for (; (size > 0); size -= sizeof(unsigned int))
123b725ae77Skettenis {
124b725ae77Skettenis data = *daddr++;
125b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
126b725ae77Skettenis crc32table[(crc ^ ((data >> 0) & 0xFF)) & 0xFF]);
127b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
128b725ae77Skettenis crc32table[(crc ^ ((data >> 8) & 0xFF)) & 0xFF]);
129b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
130b725ae77Skettenis crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
131b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
132b725ae77Skettenis crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
133b725ae77Skettenis }
134b725ae77Skettenis #else
135b725ae77Skettenis for (; (size > 0); size--)
136b725ae77Skettenis /* byte loop */
137b725ae77Skettenis crc = (((crc >> 8) & 0x00FFFFFF) ^
138b725ae77Skettenis crc32table[(crc ^ *address++) & 0x000000FF]);
139b725ae77Skettenis #endif
140b725ae77Skettenis
141b725ae77Skettenis return(crc);
142b725ae77Skettenis }
143b725ae77Skettenis
144b725ae77Skettenis /**********************************************************************/
145b725ae77Skettenis
146b725ae77Skettenis /*
147b725ae77Skettenis * crc16 16bit CRC-CCITT
148b725ae77Skettenis * ----- ---------------
149b725ae77Skettenis * This function provides a table driven 16bit CRC generation for byte data.
150b725ae77Skettenis * This CRC is also known as the HDLC CRC.
151b725ae77Skettenis */
152b725ae77Skettenis /*
153b725ae77Skettenis * 960201 KWelton
154b725ae77Skettenis *
155b725ae77Skettenis *TODO: Is this correct? The compiler predefines __arm, *not* __ARM
156b725ae77Skettenis */
157b725ae77Skettenis #ifdef __ARM
158b725ae77Skettenis /*
159b725ae77Skettenis * To make the code quicker on the ARM, we double the table size and
160b725ae77Skettenis * use integer slots rather than short slots for the table.
161b725ae77Skettenis */
162b725ae77Skettenis static const unsigned int crctableA[16] = {
163b725ae77Skettenis #else
164b725ae77Skettenis static const unsigned short crctableA[16] = {
165b725ae77Skettenis #endif
166b725ae77Skettenis 0x0000,
167b725ae77Skettenis 0x1081,
168b725ae77Skettenis 0x2102,
169b725ae77Skettenis 0x3183,
170b725ae77Skettenis 0x4204,
171b725ae77Skettenis 0x5285,
172b725ae77Skettenis 0x6306,
173b725ae77Skettenis 0x7387,
174b725ae77Skettenis 0x8408,
175b725ae77Skettenis 0x9489,
176b725ae77Skettenis 0xA50A,
177b725ae77Skettenis 0xB58B,
178b725ae77Skettenis 0xC60C,
179b725ae77Skettenis 0xD68D,
180b725ae77Skettenis 0xE70E,
181b725ae77Skettenis 0xF78F
182b725ae77Skettenis };
183b725ae77Skettenis
184b725ae77Skettenis #ifdef __ARM
185b725ae77Skettenis /* See comments above */
186b725ae77Skettenis static const unsigned int crctableB[16] = {
187b725ae77Skettenis #else
188b725ae77Skettenis static const unsigned short crctableB[16] = {
189b725ae77Skettenis #endif
190b725ae77Skettenis 0x0000,
191b725ae77Skettenis 0x1189,
192b725ae77Skettenis 0x2312,
193b725ae77Skettenis 0x329B,
194b725ae77Skettenis 0x4624,
195b725ae77Skettenis 0x57AD,
196b725ae77Skettenis 0x6536,
197b725ae77Skettenis 0x74BF,
198b725ae77Skettenis 0x8C48,
199b725ae77Skettenis 0x9DC1,
200b725ae77Skettenis 0xAF5A,
201b725ae77Skettenis 0xBED3,
202b725ae77Skettenis 0xCA6C,
203b725ae77Skettenis 0xDBE5,
204b725ae77Skettenis 0xE97E,
205b725ae77Skettenis 0xF8F7
206b725ae77Skettenis };
207b725ae77Skettenis
crc16(unsigned char * address,unsigned int size,unsigned short crc)208b725ae77Skettenis unsigned short crc16(unsigned char *address, unsigned int size,
209b725ae77Skettenis unsigned short crc)
210b725ae77Skettenis {
211b725ae77Skettenis for (; (size > 0); size--)
212b725ae77Skettenis {
213b725ae77Skettenis /* byte loop */
214b725ae77Skettenis unsigned char data = *address++; /* fetch the next data byte */
215b725ae77Skettenis
216b725ae77Skettenis data ^= crc; /* EOR data with current CRC value */
217b725ae77Skettenis crc = ((crctableA[(data & 0xF0) >> 4] ^ crctableB[data & 0x0F]) ^
218b725ae77Skettenis (crc >> 8));
219b725ae77Skettenis }
220b725ae77Skettenis
221b725ae77Skettenis return(crc);
222b725ae77Skettenis }
223b725ae77Skettenis
224b725ae77Skettenis /**********************************************************************/
225b725ae77Skettenis
226b725ae77Skettenis #if 0 /* not required at the moment */
227b725ae77Skettenis
228b725ae77Skettenis /*
229b725ae77Skettenis * elf_hash
230b725ae77Skettenis * --------
231b725ae77Skettenis * This function is derived from the one on page 68 of chapter of the "Unix
232b725ae77Skettenis * SVR4 Programmer's Guide". It is used to generate a hash-code from a
233b725ae77Skettenis * symbol name.
234b725ae77Skettenis */
235b725ae77Skettenis unsigned int elf_hash(const unsigned char *name)
236b725ae77Skettenis {
237b725ae77Skettenis unsigned int h = 0;
238b725ae77Skettenis unsigned int g;
239b725ae77Skettenis
240b725ae77Skettenis /* NULL pointer returns a hash of zero */
241b725ae77Skettenis while (name && (*name))
242b725ae77Skettenis {
243b725ae77Skettenis h = ((h << 4) + *name++);
244b725ae77Skettenis
245b725ae77Skettenis if (g = (h & 0xF0000000))
246b725ae77Skettenis h ^= (g >> 24);
247b725ae77Skettenis
248b725ae77Skettenis h &= ~g;
249b725ae77Skettenis }
250b725ae77Skettenis
251b725ae77Skettenis return(h);
252b725ae77Skettenis }
253b725ae77Skettenis #endif
254b725ae77Skettenis
255b725ae77Skettenis /**********************************************************************/
256b725ae77Skettenis
257b725ae77Skettenis /* EOF crc.c */
258