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