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