blob: adbe7dfff4b57b2f745735f19592bb6a4c91a760 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 8a6e43726ad0ae41bd1cc2c248d91deb31459357 Mon Sep 17 00:00:00 2001
2From: Lei Maohui <leimaohui@cn.fujitsu.com>
3Date: Tue, 9 Jun 2015 11:11:48 +0900
4Subject: [PATCH] packlib.c: support dictionary byte order dependent
5
6The previous dict files are NOT byte-order independent, in fact they are
7probably ARCHITECTURE SPECIFIC.
8Create the dict files in big endian, and convert to host endian while
9load them. This could fix the endian issue on multiple platform.
10
11Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
12Upstream-Status: Pending
13
14We can't use the endian.h, htobe* and be*toh functions because they are
15not available on older versions of glibc, such as that found in RHEL
165.9.
17
18Change to checking endian and directly calling bswap_* as defined in
19byteswap.h.
20
21Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
22
23Signed-off-by: Lei Maohui <leimaohui@cn.fujitsu.com>
24---
25 lib/packlib.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
26 1 file changed, 210 insertions(+), 4 deletions(-)
27
28diff --git a/lib/packlib.c b/lib/packlib.c
29index f851424..3aac805 100644
30--- a/lib/packlib.c
31+++ b/lib/packlib.c
32@@ -16,6 +16,12 @@
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h>
35 #endif
36+
37+#ifndef _BSD_SOURCE
38+#define _BSD_SOURCE /* See feature_test_macros(7) */
39+#endif
40+#include <endian.h>
41+#include <byteswap.h>
42 #include "packer.h"
43
44 static const char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
45@@ -45,6 +51,185 @@ typedef struct
46 char data_get[NUMWORDS][MAXWORDLEN];
47 } PWDICT64;
48
49+enum{
50+ en_is32,
51+ en_is64
52+};
53+
54+static int
55+IheaderHostToBigEndian(char *pHeader, int nBitType)
56+{
57+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN)
58+ {
59+ struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader;
60+
61+ pHeader64->pih_magic = bswap_64(pHeader64->pih_magic);
62+ pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords);
63+ pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen);
64+ pHeader64->pih_pad = bswap_16(pHeader64->pih_pad);
65+
66+#if DEBUG
67+ printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n",
68+ pHeader64->pih_magic, pHeader64->pih_numwords,
69+ pHeader64->pih_blocklen, pHeader64->pih_pad);
70+#endif
71+ }
72+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN)
73+ {
74+ struct pi_header *pHeader32 = (struct pi_header*)pHeader;
75+
76+ pHeader32->pih_magic = bswap_32(pHeader32->pih_magic);
77+ pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords);
78+ pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen);
79+ pHeader32->pih_pad = bswap_16(pHeader32->pih_pad);
80+
81+#if DEBUG
82+ printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n",
83+ pHeader32->pih_magic, pHeader32->pih_numwords,
84+ pHeader32->pih_blocklen, pHeader32->pih_pad);
85+#endif
86+ }
87+ else if (__BYTE_ORDER == __LITTLE_ENDIAN)
88+ {
89+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType);
90+ return (-1);
91+ }
92+
93+ return 0;
94+}
95+
96+static int
97+IheaderBigEndianToHost(char *pHeader, int nBitType)
98+{
99+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN)
100+ {
101+ struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader;
102+
103+ pHeader64->pih_magic = bswap_64(pHeader64->pih_magic);
104+ pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords);
105+ pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen);
106+ pHeader64->pih_pad = bswap_16(pHeader64->pih_pad);
107+
108+#if DEBUG
109+ printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n",
110+ pHeader64->pih_magic, pHeader64->pih_numwords,
111+ pHeader64->pih_blocklen, pHeader64->pih_pad);
112+#endif
113+ }
114+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN)
115+ {
116+ struct pi_header *pHeader32 = (struct pi_header*)pHeader;
117+
118+ pHeader32->pih_magic = bswap_32(pHeader32->pih_magic);
119+ pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords);
120+ pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen);
121+ pHeader32->pih_pad = bswap_16(pHeader32->pih_pad);
122+
123+#if DEBUG
124+ printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n",
125+ pHeader32->pih_magic, pHeader32->pih_numwords,
126+ pHeader32->pih_blocklen, pHeader32->pih_pad);
127+#endif
128+ }
129+ else if (__BYTE_ORDER == __LITTLE_ENDIAN)
130+ {
131+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType);
132+ return (-1);
133+ }
134+
135+ return 0;
136+}
137+
138+static int
139+HwmsHostToBigEndian(char *pHwms, int nLen,int nBitType)
140+{
141+ int i = 0;
142+
143+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN)
144+ {
145+ uint64_t *pHwms64 = (uint64_t*)pHwms;
146+
147+ for (i = 0; i < nLen / sizeof(uint64_t); i++)
148+ {
149+ *pHwms64 = bswap_64(*pHwms64);
150+ *pHwms64++;
151+ }
152+
153+ }
154+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN)
155+ {
156+ uint32_t *pHwms32 = (uint32_t*)pHwms;
157+
158+ for (i = 0; i < nLen / sizeof(uint32_t); i++)
159+ {
160+ *pHwms32 = bswap_32(*pHwms32);
161+ *pHwms32++;
162+ }
163+
164+ }
165+ else if (__BYTE_ORDER == __LITTLE_ENDIAN)
166+ {
167+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType);
168+ return (-1);
169+ }
170+
171+#if DEBUG
172+ for (i = 0; i < nLen; i+=8)
173+ {
174+ printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n",
175+ nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF,
176+ pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF,
177+ pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF);
178+ }
179+#endif
180+
181+ return 0;
182+}
183+
184+static int
185+HwmsBigEndianToHost(char *pHwms, int nLen, int nBitType)
186+{
187+ int i = 0;
188+
189+ if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN)
190+ {
191+ uint64_t *pHwms64 = (uint64_t*)pHwms;
192+
193+ for (i = 0; i < nLen / sizeof(uint64_t); i++)
194+ {
195+ *pHwms64++ = bswap_64(*pHwms64);
196+ }
197+
198+ }
199+ else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN)
200+ {
201+ uint32_t *pHwms32 = (uint32_t*)pHwms;
202+
203+ for (i = 0; i < nLen / sizeof(uint32_t); i++)
204+ {
205+ *pHwms32 = bswap_32(*pHwms32);
206+ *pHwms32++;
207+ }
208+
209+ }
210+ else if (__BYTE_ORDER == __LITTLE_ENDIAN)
211+ {
212+ fprintf(stderr, "Neither 32 or 64: %d\n", nBitType);
213+ return (-1);
214+ }
215+
216+#if DEBUG
217+ for (i = 0; i < nLen; i+=8)
218+ {
219+ printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n",
220+ nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF,
221+ pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF,
222+ pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF);
223+ }
224+#endif
225+
226+ return 0;
227+}
228
229 static int
230 _PWIsBroken64(FILE *ifp)
231@@ -57,6 +242,7 @@ _PWIsBroken64(FILE *ifp)
232 return 0;
233 }
234
235+ IheaderBigEndianToHost((char *) &pdesc64.header, en_is64);
236 return (pdesc64.header.pih_magic == PIH_MAGIC);
237 }
238
239@@ -149,7 +335,11 @@ PWOpen(prefix, mode)
240 pdesc.header.pih_blocklen = NUMWORDS;
241 pdesc.header.pih_numwords = 0;
242
243- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
244+ struct pi_header tmpheader32;
245+
246+ memcpy(&tmpheader32, &pdesc.header, sizeof(pdesc.header));
247+ IheaderHostToBigEndian((char *) &tmpheader32, en_is32);
248+ fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, ifp);
249 } else
250 {
251 pdesc.flags &= ~PFOR_WRITE;
252@@ -173,6 +363,7 @@ PWOpen(prefix, mode)
253 return NULL;
254 }
255
256+ IheaderBigEndianToHost((char *) &pdesc.header, en_is32);
257 if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0))
258 {
259 /* uh-oh. either a broken "64-bit" file or a garbage file. */
260@@ -195,6 +386,7 @@ PWOpen(prefix, mode)
261 }
262 return NULL;
263 }
264+ IheaderBigEndianToHost((char *) &pdesc64.header, en_is64);
265 if (pdesc64.header.pih_magic != PIH_MAGIC)
266 {
267 /* nope, not "64-bit" after all */
268@@ -290,6 +482,7 @@ PWOpen(prefix, mode)
269 {
270 pdesc.flags &= ~PFOR_USEHWMS;
271 }
272+ HwmsBigEndianToHost((char*)pdesc64.hwms, sizeof(pdesc64.hwms), en_is64);
273 for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++)
274 {
275 pdesc.hwms[i] = pdesc64.hwms[i];
276@@ -299,6 +492,7 @@ PWOpen(prefix, mode)
277 {
278 pdesc.flags &= ~PFOR_USEHWMS;
279 }
280+ HwmsBigEndianToHost((char*)pdesc.hwms, sizeof(pdesc.hwms), en_is32);
281 #if DEBUG
282 for (i=1; i<=0xff; i++)
283 {
284@@ -332,7 +526,11 @@ PWClose(pwp)
285 return (-1);
286 }
287
288- if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp))
289+ struct pi_header tmpheader32;
290+
291+ memcpy(&tmpheader32, &pwp->header, sizeof(pwp->header));
292+ IheaderHostToBigEndian((char *) &tmpheader32, en_is32);
293+ if (!fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, pwp->ifp))
294 {
295 fprintf(stderr, "index magic fwrite failed\n");
296 return (-1);
297@@ -351,7 +549,12 @@ PWClose(pwp)
298 printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
299 #endif
300 }
301- fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
302+
303+ PWDICT tmp_pwp;
304+
305+ memcpy(&tmp_pwp, pwp, sizeof(PWDICT));
306+ HwmsHostToBigEndian(tmp_pwp.hwms, sizeof(tmp_pwp.hwms), en_is32);
307+ fwrite(tmp_pwp.hwms, 1, sizeof(tmp_pwp.hwms), pwp->wfp);
308 }
309 }
310
311@@ -405,7 +608,8 @@ PutPW(pwp, string)
312
313 datum = (uint32_t) ftell(pwp->dfp);
314
315- fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp);
316+ uint32_t tmpdatum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum;
317+ fwrite((char *) &tmpdatum, sizeof(tmpdatum), 1, pwp->ifp);
318
319 fputs(pwp->data_put[0], pwp->dfp);
320 putc(0, pwp->dfp);
321@@ -464,6 +668,7 @@ GetPW(pwp, number)
322 perror("(index fread failed)");
323 return NULL;
324 }
325+ datum64 = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_64(datum64) : datum64;
326 datum = datum64;
327 } else {
328 if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0))
329@@ -477,6 +682,7 @@ GetPW(pwp, number)
330 perror("(index fread failed)");
331 return NULL;
332 }
333+ datum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum;
334 }
335
336 int r = 1;
337--
3381.8.4.2
339