Signed-off-by: Alexey Gladkov <[email protected]>
---
 elfops.c      |    8 +++---
 elfops.h      |    4 +-
 elfops_core.c |    8 +++---
 modinfo.c     |   15 ++++++-----
 modprobe.c    |    2 +-
 zlibsupport.c |   69 ++++++++++++++++++++++++++++++--------------------------
 zlibsupport.h |   17 ++++++++++++-
 7 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/elfops.c b/elfops.c
index 10e80ea..3468265 100644
--- a/elfops.c
+++ b/elfops.c
@@ -74,11 +74,11 @@ struct elf_file *grab_elf_file(const char *pathname)
                errno = ENOMEM;
                goto fail_free_file;
        }
-       file->data = grab_file(pathname, &file->len);
-       if (!file->data)
+
+       if (grab_file(pathname, &file->fdata) < 0)
                goto fail_free_pathname;
 
-       switch (elf_ident(file->data, file->len, &file->conv)) {
+       switch (elf_ident(file->fdata.data, file->fdata.size, &file->conv)) {
        case ELFCLASS32:
                file->ops = &mod_ops32;
                break;
@@ -108,7 +108,7 @@ void release_elf_file(struct elf_file *file)
        if (!file)
                return;
 
-       release_file(file->data, file->len);
+       release_file(&file->fdata);
        free(file->pathname);
        free(file);
 
diff --git a/elfops.h b/elfops.h
index 52c1fd7..fd4b014 100644
--- a/elfops.h
+++ b/elfops.h
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include "logging.h"
+#include "zlibsupport.h"
 
 /* All the icky stuff to do with manipulating 64 and 32-bit modules
    belongs here. */
@@ -29,8 +30,7 @@ struct elf_file
        int conv;
 
        /* File contents and length. */
-       void *data;
-       unsigned long len;
+       struct grab_data fdata;
 };
 
 /* Tables extracted from module by ops->fetch_tables(). */
diff --git a/elfops_core.c b/elfops_core.c
index 7150d39..8b8ed77 100644
--- a/elfops_core.c
+++ b/elfops_core.c
@@ -23,8 +23,8 @@ static void *PERBIT(get_section)(struct elf_file *module,
                                 ElfPERBIT(Shdr) **sechdr,
                                 unsigned long *secsize)
 {
-       void *data = module->data;
-       unsigned long len = module->len;
+       void *data = module->fdata.data;
+       unsigned long len = module->fdata.size;
        int conv = module->conv;
 
        ElfPERBIT(Ehdr) *hdr;
@@ -229,7 +229,7 @@ static struct string_table *PERBIT(load_dep_syms)(struct 
elf_file *module,
        }
 
        num_syms = size / sizeof(syms[0]);
-       hdr = module->data;
+       hdr = module->fdata.data;
        conv = module->conv;
        if (versions) {
                versions_size = num_syms;
@@ -332,7 +332,7 @@ static void PERBIT(fetch_tables)(struct elf_file *module,
        ElfPERBIT(Shdr) *sechdrs;
        int conv;
 
-       hdr = module->data;
+       hdr = module->fdata.data;
        conv = module->conv;
 
        sechdrs = (void *)hdr + END(hdr->e_shoff, conv);
diff --git a/modinfo.c b/modinfo.c
index 1dd8469..9ae40f2 100644
--- a/modinfo.c
+++ b/modinfo.c
@@ -189,7 +189,7 @@ static struct elf_file *grab_module(const char *name,
                                    const char *basedir)
 {
        char *data;
-       unsigned long size;
+       struct grab_data fdata;
        struct utsname buf;
        char *depname, *p, *moddir;
        struct elf_file *module;
@@ -213,16 +213,17 @@ static struct elf_file *grab_module(const char *name,
 
        /* Search for it in modules.dep. */
        nofail_asprintf(&depname, "%s/%s", moddir, "modules.dep");
-       data = grab_file(depname, &size);
-       if (!data) {
+       if (grab_file(depname, &fdata) < 0) {
                error("modinfo: could not open %s\n", depname);
                free(depname);
                return NULL;
        }
        free(depname);
 
-       for (p = data; p < data + size; p = next_line(p, data + size)) {
-               if (name_matches(p, data + size, name)) {
+       data = fdata.data;
+
+       for (p = data; p < data + fdata.size; p = next_line(p, data + 
fdata.size)) {
+               if (name_matches(p, data + fdata.size, name)) {
                        int namelen = strcspn(p, ":");
                        const char *dir;
                        char *filename;
@@ -238,7 +239,7 @@ static struct elf_file *grab_module(const char *name,
                        } else {
                                filename = strndup(p, namelen);
                        }
-                       release_file(data, size);
+                       release_file(&fdata);
                        module = grab_elf_file(filename);
                        if (!module)
                                error("modinfo: could not open %s: %s\n",
@@ -247,7 +248,7 @@ static struct elf_file *grab_module(const char *name,
                        return module;
                }
        }
-       release_file(data, size);
+       release_file(&fdata);
        error("modinfo: could not find module %s\n", name);
        return NULL;
 }
diff --git a/modprobe.c b/modprobe.c
index 5464f45..edf60d6 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -1792,7 +1792,7 @@ static int insmod(struct list_head *list,
                goto out_elf_file;
 
        /* request kernel linkage */
-       ret = init_module(module->data, module->len, opts);
+       ret = init_module(module->fdata.data, module->fdata.size, opts);
        if (ret != 0) {
                if (errno == EEXIST) {
                        if (flags & mit_first_time)
diff --git a/zlibsupport.c b/zlibsupport.c
index fc58f16..8936c7f 100644
--- a/zlibsupport.c
+++ b/zlibsupport.c
@@ -20,81 +20,86 @@
 #ifdef CONFIG_USE_ZLIB
 #include <zlib.h>
 
-static void *grab_contents(gzFile *gzfd, unsigned long *size)
+static int grab_contents(gzFile *gzfd, struct grab_data *fdata)
 {
        unsigned int max = 16384;
-       void *buffer = NOFAIL(malloc(max));
        int ret;
 
-       *size = 0;
-       while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
-               *size += ret;
-               if (*size == max)
-                       buffer = NOFAIL(realloc(buffer, max *= 2));
+       fdata->data = NOFAIL(malloc(max));
+       fdata->size = 0;
+
+       while ((ret = gzread(gzfd, fdata->data + fdata->size, max - 
fdata->size)) > 0) {
+               fdata->size += ret;
+               if (fdata->size == max)
+                       fdata->data = NOFAIL(realloc(fdata->data, max *= 2));
        }
        if (ret < 0) {
-               free(buffer);
-               buffer = NULL;
+               free(fdata->data);
+               fdata->data = NULL;
+               return -1;
        }
 
-       return buffer;
+       return 0;
 }
 
 /* gzopen handles uncompressed files transparently. */
-void *grab_file(const char *filename, unsigned long *size)
+int grab_file(const char *filename, struct grab_data *fdata)
 {
        gzFile gzfd;
-       void *buffer;
 
        errno = 0;
        gzfd = gzopen(filename, "rb");
        if (!gzfd) {
                if (errno == ENOMEM)
                        fatal("Memory allocation failure in gzopen\n");
-               return NULL;
+               return -1;
+       }
+       if (grab_contents(gzfd, fdata) < 0) {
+               gzclose(gzfd);
+               return -1;
        }
-       buffer = grab_contents(gzfd, size);
+       fdata->type = GZIP_FILE;
        gzclose(gzfd);
-       return buffer;
+       return 0;
 }
 
-void release_file(void *data, unsigned long size)
+void release_file(struct grab_data *fdata)
 {
-       free(data);
+       free(fdata->data);
 }
 #else /* ... !CONFIG_USE_ZLIB */
 
-static void *grab_fd(int fd, unsigned long *size)
+static void *grab_fd(int fd, struct grab_data *fdata)
 {
        struct stat st;
-       void *map;
        int ret;
 
        ret = fstat(fd, &st);
        if (ret < 0)
-               return NULL;
-       *size = st.st_size;
-       map = mmap(0, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-       if (map == MAP_FAILED)
-               map = NULL;
-       return map;
+               return -1;
+       fdata->size = st.st_size;
+       fdata->data = mmap(0, fdata->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, 
fd, 0);
+       if (fdata->data == MAP_FAILED)
+               fdata->data = NULL;
+       return 0;
 }
 
-void *grab_file(const char *filename, unsigned long *size)
+int grab_file(const char *filename, struct grab_data *fdata)
 {
        int fd;
-       void *map;
 
        fd = open(filename, O_RDONLY, 0);
        if (fd < 0)
-               return NULL;
-       map = grab_fd(fd, size);
+               return -1;
+       if (grab_fd(fd, fdata) < 0)
+               return -1;
+       fdata->type = PLAIN_FILE;
        close(fd);
-       return map;
+       return 0;
 }
 
-void release_file(void *data, unsigned long size)
+void release_file(struct grab_data *fdata)
 {
-       munmap(data, size);
+       munmap(fdata->data, fdata->size);
 }
 #endif
diff --git a/zlibsupport.h b/zlibsupport.h
index 9ab0703..3eb4c2d 100644
--- a/zlibsupport.h
+++ b/zlibsupport.h
@@ -1,10 +1,23 @@
 #ifndef _ZLIB_SUPPORT_H
 #define _ZLIB_SUPPORT_H
 
+enum file_type
+{
+       PLAIN_FILE,
+       GZIP_FILE
+};
+
+struct grab_data
+{
+       enum file_type type;
+       unsigned long size;
+       void *data;
+};
+
 /* Grab file.  Decompresses if that is supported.  Returns NULL on error. */
-extern void *grab_file(const char *filename, unsigned long *size);
+extern int grab_file(const char *filename, struct grab_data *fdata);
 
 /* Free it up. */
-extern void release_file(void *data, unsigned long size);
+extern void release_file(struct grab_data *fdata);
 
 #endif /* _ZLIB_SUPPORT_H */
-- 
1.7.3.5

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to