]> granicus.if.org Git - file/commitdiff
Deal with 64 bit machines (structure packing)
authorChristos Zoulas <christos@zoulas.com>
Sun, 12 Oct 2008 19:06:36 +0000 (19:06 +0000)
committerChristos Zoulas <christos@zoulas.com>
Sun, 12 Oct 2008 19:06:36 +0000 (19:06 +0000)
src/cdf.c
src/cdf.h
src/readelf.c

index 6c1393d0e29378ea917846d04660817206c61702..1d609aaaafaef91b85ff5b08d9aec61c6ebfdfd5 100644 (file)
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -117,6 +117,10 @@ cdf_need_swap(void)
        return NEED_SWAP;
 }
 
+#define CDF_UNPACK(a)  \
+    (void)memcpy(&(a), &buf[len], sizeof(a)), len += sizeof(a)
+#define CDF_UNPACKA(a) \
+    (void)memcpy((a), &buf[len], sizeof(a)), len += sizeof(a)
 
 void
 cdf_swap_header(cdf_header_t *h)
@@ -145,6 +149,32 @@ cdf_swap_header(cdf_header_t *h)
                h->h_master_sat[i] = CDF_TOLE4(h->h_master_sat[i]);
 }
 
+void
+cdf_unpack_header(cdf_header_t *h, char *buf)
+{
+       size_t i;
+       size_t len = 0;
+
+       CDF_UNPACK(h->h_magic);
+       CDF_UNPACKA(h->h_uuid);
+       CDF_UNPACK(h->h_revision);
+       CDF_UNPACK(h->h_version);
+       CDF_UNPACK(h->h_byte_order);
+       CDF_UNPACK(h->h_sec_size_p2);
+       CDF_UNPACK(h->h_short_sec_size_p2);
+       CDF_UNPACKA(h->h_unused0);
+       CDF_UNPACK(h->h_num_sectors_in_sat);
+       CDF_UNPACK(h->h_secid_first_directory);
+       CDF_UNPACKA(h->h_unused1);
+       CDF_UNPACK(h->h_min_size_standard_stream);
+       CDF_UNPACK(h->h_secid_first_sector_in_short_sat);
+       CDF_UNPACK(h->h_num_sectors_in_short_sat);
+       CDF_UNPACK(h->h_secid_first_sector_in_master_sat);
+       CDF_UNPACK(h->h_num_sectors_in_master_sat);
+       for (i = 0; i < __arraycount(h->h_master_sat); i++)
+               CDF_UNPACK(h->h_master_sat[i]);
+}
+
 void
 cdf_swap_dir(cdf_directory_t *d)
 {
@@ -161,15 +191,36 @@ cdf_swap_dir(cdf_directory_t *d)
        d->d_size = CDF_TOLE4(d->d_size);
 }
 
+void
+cdf_unpack_dir(cdf_directory_t *d, char *buf)
+{
+       size_t len = 0;
+
+       CDF_UNPACKA(d->d_name);
+       CDF_UNPACK(d->d_namelen);
+       CDF_UNPACK(d->d_type);
+       CDF_UNPACK(d->d_color);
+       CDF_UNPACK(d->d_left_child);
+       CDF_UNPACK(d->d_right_child);
+       CDF_UNPACK(d->d_storage);
+       CDF_UNPACKA(d->d_storage_uuid);
+       CDF_UNPACK(d->d_flags);
+       CDF_UNPACK(d->d_created);
+       CDF_UNPACK(d->d_modified);
+       CDF_UNPACK(d->d_stream_first_sector);
+       CDF_UNPACK(d->d_size);
+       CDF_UNPACK(d->d_unused0);
+}
 int
 cdf_read_header(int fd, cdf_header_t *h)
 {
        (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
-       assert(sizeof(*h) == 512);
+       char buf[512];
        if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1)
                return -1;
-       if (read(fd, h, sizeof(*h)) != sizeof(*h))
+       if (read(fd, buf, sizeof(buf)) != sizeof(buf))
                return -1;
+       cdf_unpack_header(h, buf);
        cdf_swap_header(h);
        if (h->h_magic != CDF_MAGIC) {
                errno = EFTYPE;
@@ -296,8 +347,9 @@ int
 cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
     cdf_dir_t *dir)
 {
-       size_t i;
+       size_t i, j;
        size_t ss = CDF_SEC_SIZE(h), ns;
+       char *buf;
        cdf_secid_t sid = h->h_secid_first_directory;
 
        ns = cdf_count_chain(h, sat, sid);
@@ -307,15 +359,25 @@ cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat,
        dir->dir_tab = calloc(ns, sizeof(dir->dir_tab[0]));
        if (dir->dir_tab == NULL)
                return -1;
-       dir->dir_len = ns * ss / sizeof(dir->dir_tab[0]);
+       dir->dir_len = ns * ss / CDF_DIRECTORY_SIZE;
+
+       if ((buf = malloc(ss)) == NULL) {
+               free(dir->dir_tab);
+               return -1;
+       }
 
        for (i = 0; i < ns; i++) {
-               if (cdf_read_sector(fd, dir->dir_tab, i * ss, ss, h, sid) !=
-                   (ssize_t)ss) {
+               if (cdf_read_sector(fd, buf, 0, ss, h, sid) != (ssize_t)ss) {
                        warnx("Reading directory sector %d", sid);
                        free(dir->dir_tab);
+                       free(buf);
                        return -1;
                }
+               for (j = 0; j < ss / CDF_DIRECTORY_SIZE; j++) {
+                       cdf_unpack_dir(&dir->dir_tab[j],
+                           &buf[j * CDF_DIRECTORY_SIZE]);
+
+               }
                sid = CDF_TOLE4(sat->sat_tab[sid]);
        }
        if (NEED_SWAP)
index d399be8fe582add6c940b3120ae94a9cc97bd8d4..7ba4980dfc84d80715ebc60035af117b45f0cfd5 100644 (file)
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -96,6 +96,8 @@ typedef struct {
        uint32_t        d_unused0;
 } cdf_directory_t;
 
+#define CDF_DIRECTORY_SIZE     128
+
 typedef struct {
        cdf_secid_t *sat_tab;
        size_t sat_len;
@@ -182,7 +184,9 @@ int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
 int cdf_need_swap(void);
 int cdf_read_header(int, cdf_header_t *);
 void cdf_swap_header(cdf_header_t *);
+void cdf_unpack_header(cdf_header_t *, char *);
 void cdf_swap_dir(cdf_directory_t *);
+void cdf_unpack_dir(cdf_directory_t *, char *);
 ssize_t cdf_read_sector(int, void *, size_t, size_t, const cdf_header_t *,
     cdf_secid_t);
 int cdf_read_sat(int, cdf_header_t *, cdf_sat_t *);
index 811c29fded771ce0d4bf4dcf72eb84d7fd443a6c..d2ddb19f071207b2275b71fbf6bcc42465ef0ef6 100644 (file)
@@ -38,7 +38,7 @@
 #include "magic.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.77 2008/08/30 17:51:09 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.78 2008/08/31 07:58:00 christos Exp $")
 #endif
 
 #ifdef ELFCORE
@@ -875,7 +875,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
 
                        noff = 0;
                        for (;;) {
-                               if (noff >= (size_t)xsh_size)
+                               if (noff >= (off_t)xsh_size)
                                        break;
                                noff = donote(ms, nbuf, (size_t)noff,
                                    (size_t)xsh_size, clazz, swap, 4,
@@ -909,7 +909,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
                                Elf64_Cap cap64;
                                char cbuf[/*CONSTCOND*/
                                    MAX(sizeof cap32, sizeof cap64)];
-                               if ((coff += xcap_sizeof) >= (size_t)xsh_size)
+                               if ((coff += xcap_sizeof) >= (off_t)xsh_size)
                                        break;
                                if (read(fd, cbuf, (size_t)xcap_sizeof) !=
                                    (ssize_t)xcap_sizeof) {