| From 8a6e43726ad0ae41bd1cc2c248d91deb31459357 Mon Sep 17 00:00:00 2001 |
| From: Lei Maohui <leimaohui@cn.fujitsu.com> |
| Date: Tue, 9 Jun 2015 11:11:48 +0900 |
| Subject: [PATCH] packlib.c: support dictionary byte order dependent |
| |
| The previous dict files are NOT byte-order independent, in fact they are |
| probably ARCHITECTURE SPECIFIC. |
| Create the dict files in big endian, and convert to host endian while |
| load them. This could fix the endian issue on multiple platform. |
| |
| Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> |
| Upstream-Status: Pending |
| |
| We can't use the endian.h, htobe* and be*toh functions because they are |
| not available on older versions of glibc, such as that found in RHEL |
| 5.9. |
| |
| Change to checking endian and directly calling bswap_* as defined in |
| byteswap.h. |
| |
| Signed-off-by: Mark Hatle <mark.hatle@windriver.com> |
| |
| Signed-off-by: Lei Maohui <leimaohui@cn.fujitsu.com> |
| --- |
| lib/packlib.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
| 1 file changed, 210 insertions(+), 4 deletions(-) |
| |
| diff --git a/lib/packlib.c b/lib/packlib.c |
| index f851424..3aac805 100644 |
| --- a/lib/packlib.c |
| +++ b/lib/packlib.c |
| @@ -16,6 +16,12 @@ |
| #ifdef HAVE_STDINT_H |
| #include <stdint.h> |
| #endif |
| + |
| +#ifndef _BSD_SOURCE |
| +#define _BSD_SOURCE /* See feature_test_macros(7) */ |
| +#endif |
| +#include <endian.h> |
| +#include <byteswap.h> |
| #include "packer.h" |
| |
| static const char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993"; |
| @@ -45,6 +51,185 @@ typedef struct |
| char data_get[NUMWORDS][MAXWORDLEN]; |
| } PWDICT64; |
| |
| +enum{ |
| + en_is32, |
| + en_is64 |
| +}; |
| + |
| +static int |
| +IheaderHostToBigEndian(char *pHeader, int nBitType) |
| +{ |
| + if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader; |
| + |
| + pHeader64->pih_magic = bswap_64(pHeader64->pih_magic); |
| + pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords); |
| + pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen); |
| + pHeader64->pih_pad = bswap_16(pHeader64->pih_pad); |
| + |
| +#if DEBUG |
| + printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n", |
| + pHeader64->pih_magic, pHeader64->pih_numwords, |
| + pHeader64->pih_blocklen, pHeader64->pih_pad); |
| +#endif |
| + } |
| + else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + struct pi_header *pHeader32 = (struct pi_header*)pHeader; |
| + |
| + pHeader32->pih_magic = bswap_32(pHeader32->pih_magic); |
| + pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords); |
| + pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen); |
| + pHeader32->pih_pad = bswap_16(pHeader32->pih_pad); |
| + |
| +#if DEBUG |
| + printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n", |
| + pHeader32->pih_magic, pHeader32->pih_numwords, |
| + pHeader32->pih_blocklen, pHeader32->pih_pad); |
| +#endif |
| + } |
| + else if (__BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); |
| + return (-1); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static int |
| +IheaderBigEndianToHost(char *pHeader, int nBitType) |
| +{ |
| + if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + struct pi_header64 *pHeader64 = (struct pi_header64*)pHeader; |
| + |
| + pHeader64->pih_magic = bswap_64(pHeader64->pih_magic); |
| + pHeader64->pih_numwords = bswap_64(pHeader64->pih_numwords); |
| + pHeader64->pih_blocklen = bswap_16(pHeader64->pih_blocklen); |
| + pHeader64->pih_pad = bswap_16(pHeader64->pih_pad); |
| + |
| +#if DEBUG |
| + printf("Header64: magic %x, numwords %x, blocklen %x, pad %x\n", |
| + pHeader64->pih_magic, pHeader64->pih_numwords, |
| + pHeader64->pih_blocklen, pHeader64->pih_pad); |
| +#endif |
| + } |
| + else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + struct pi_header *pHeader32 = (struct pi_header*)pHeader; |
| + |
| + pHeader32->pih_magic = bswap_32(pHeader32->pih_magic); |
| + pHeader32->pih_numwords = bswap_32(pHeader32->pih_numwords); |
| + pHeader32->pih_blocklen = bswap_16(pHeader32->pih_blocklen); |
| + pHeader32->pih_pad = bswap_16(pHeader32->pih_pad); |
| + |
| +#if DEBUG |
| + printf("Header32: magic %x, numwords %x, blocklen %x, pad %x\n", |
| + pHeader32->pih_magic, pHeader32->pih_numwords, |
| + pHeader32->pih_blocklen, pHeader32->pih_pad); |
| +#endif |
| + } |
| + else if (__BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); |
| + return (-1); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static int |
| +HwmsHostToBigEndian(char *pHwms, int nLen,int nBitType) |
| +{ |
| + int i = 0; |
| + |
| + if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + uint64_t *pHwms64 = (uint64_t*)pHwms; |
| + |
| + for (i = 0; i < nLen / sizeof(uint64_t); i++) |
| + { |
| + *pHwms64 = bswap_64(*pHwms64); |
| + *pHwms64++; |
| + } |
| + |
| + } |
| + else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + uint32_t *pHwms32 = (uint32_t*)pHwms; |
| + |
| + for (i = 0; i < nLen / sizeof(uint32_t); i++) |
| + { |
| + *pHwms32 = bswap_32(*pHwms32); |
| + *pHwms32++; |
| + } |
| + |
| + } |
| + else if (__BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); |
| + return (-1); |
| + } |
| + |
| +#if DEBUG |
| + for (i = 0; i < nLen; i+=8) |
| + { |
| + printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", |
| + nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF, |
| + pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF, |
| + pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF); |
| + } |
| +#endif |
| + |
| + return 0; |
| +} |
| + |
| +static int |
| +HwmsBigEndianToHost(char *pHwms, int nLen, int nBitType) |
| +{ |
| + int i = 0; |
| + |
| + if (nBitType == en_is64 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + uint64_t *pHwms64 = (uint64_t*)pHwms; |
| + |
| + for (i = 0; i < nLen / sizeof(uint64_t); i++) |
| + { |
| + *pHwms64++ = bswap_64(*pHwms64); |
| + } |
| + |
| + } |
| + else if (nBitType == en_is32 && __BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + uint32_t *pHwms32 = (uint32_t*)pHwms; |
| + |
| + for (i = 0; i < nLen / sizeof(uint32_t); i++) |
| + { |
| + *pHwms32 = bswap_32(*pHwms32); |
| + *pHwms32++; |
| + } |
| + |
| + } |
| + else if (__BYTE_ORDER == __LITTLE_ENDIAN) |
| + { |
| + fprintf(stderr, "Neither 32 or 64: %d\n", nBitType); |
| + return (-1); |
| + } |
| + |
| +#if DEBUG |
| + for (i = 0; i < nLen; i+=8) |
| + { |
| + printf("hwms%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", |
| + nBitType==en_is64?"64":"32", pHwms[i+0]&0xFF, pHwms[i+1]&0xFF, |
| + pHwms[i+2]&0xFF, pHwms[i+3]&0xFF, pHwms[i+4]&0xFF, |
| + pHwms[i+5]&0xFF, pHwms[i+6]&0xFF, pHwms[i+7]&0xFF); |
| + } |
| +#endif |
| + |
| + return 0; |
| +} |
| |
| static int |
| _PWIsBroken64(FILE *ifp) |
| @@ -57,6 +242,7 @@ _PWIsBroken64(FILE *ifp) |
| return 0; |
| } |
| |
| + IheaderBigEndianToHost((char *) &pdesc64.header, en_is64); |
| return (pdesc64.header.pih_magic == PIH_MAGIC); |
| } |
| |
| @@ -149,7 +335,11 @@ PWOpen(prefix, mode) |
| pdesc.header.pih_blocklen = NUMWORDS; |
| pdesc.header.pih_numwords = 0; |
| |
| - fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp); |
| + struct pi_header tmpheader32; |
| + |
| + memcpy(&tmpheader32, &pdesc.header, sizeof(pdesc.header)); |
| + IheaderHostToBigEndian((char *) &tmpheader32, en_is32); |
| + fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, ifp); |
| } else |
| { |
| pdesc.flags &= ~PFOR_WRITE; |
| @@ -173,6 +363,7 @@ PWOpen(prefix, mode) |
| return NULL; |
| } |
| |
| + IheaderBigEndianToHost((char *) &pdesc.header, en_is32); |
| if ((pdesc.header.pih_magic == 0) || (pdesc.header.pih_numwords == 0)) |
| { |
| /* uh-oh. either a broken "64-bit" file or a garbage file. */ |
| @@ -195,6 +386,7 @@ PWOpen(prefix, mode) |
| } |
| return NULL; |
| } |
| + IheaderBigEndianToHost((char *) &pdesc64.header, en_is64); |
| if (pdesc64.header.pih_magic != PIH_MAGIC) |
| { |
| /* nope, not "64-bit" after all */ |
| @@ -290,6 +482,7 @@ PWOpen(prefix, mode) |
| { |
| pdesc.flags &= ~PFOR_USEHWMS; |
| } |
| + HwmsBigEndianToHost((char*)pdesc64.hwms, sizeof(pdesc64.hwms), en_is64); |
| for (i = 0; i < sizeof(pdesc.hwms) / sizeof(pdesc.hwms[0]); i++) |
| { |
| pdesc.hwms[i] = pdesc64.hwms[i]; |
| @@ -299,6 +492,7 @@ PWOpen(prefix, mode) |
| { |
| pdesc.flags &= ~PFOR_USEHWMS; |
| } |
| + HwmsBigEndianToHost((char*)pdesc.hwms, sizeof(pdesc.hwms), en_is32); |
| #if DEBUG |
| for (i=1; i<=0xff; i++) |
| { |
| @@ -332,7 +526,11 @@ PWClose(pwp) |
| return (-1); |
| } |
| |
| - if (!fwrite((char *) &pwp->header, sizeof(pwp->header), 1, pwp->ifp)) |
| + struct pi_header tmpheader32; |
| + |
| + memcpy(&tmpheader32, &pwp->header, sizeof(pwp->header)); |
| + IheaderHostToBigEndian((char *) &tmpheader32, en_is32); |
| + if (!fwrite((char *) &tmpheader32, sizeof(tmpheader32), 1, pwp->ifp)) |
| { |
| fprintf(stderr, "index magic fwrite failed\n"); |
| return (-1); |
| @@ -351,7 +549,12 @@ PWClose(pwp) |
| printf("hwm[%02x] = %d\n", i, pwp->hwms[i]); |
| #endif |
| } |
| - fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp); |
| + |
| + PWDICT tmp_pwp; |
| + |
| + memcpy(&tmp_pwp, pwp, sizeof(PWDICT)); |
| + HwmsHostToBigEndian(tmp_pwp.hwms, sizeof(tmp_pwp.hwms), en_is32); |
| + fwrite(tmp_pwp.hwms, 1, sizeof(tmp_pwp.hwms), pwp->wfp); |
| } |
| } |
| |
| @@ -405,7 +608,8 @@ PutPW(pwp, string) |
| |
| datum = (uint32_t) ftell(pwp->dfp); |
| |
| - fwrite((char *) &datum, sizeof(datum), 1, pwp->ifp); |
| + uint32_t tmpdatum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum; |
| + fwrite((char *) &tmpdatum, sizeof(tmpdatum), 1, pwp->ifp); |
| |
| fputs(pwp->data_put[0], pwp->dfp); |
| putc(0, pwp->dfp); |
| @@ -464,6 +668,7 @@ GetPW(pwp, number) |
| perror("(index fread failed)"); |
| return NULL; |
| } |
| + datum64 = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_64(datum64) : datum64; |
| datum = datum64; |
| } else { |
| if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(uint32_t)), 0)) |
| @@ -477,6 +682,7 @@ GetPW(pwp, number) |
| perror("(index fread failed)"); |
| return NULL; |
| } |
| + datum = (__BYTE_ORDER == __LITTLE_ENDIAN) ? bswap_32(datum) : datum; |
| } |
| |
| int r = 1; |
| -- |
| 1.8.4.2 |
| |