aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Robinson <andr345@gmail.com>2009-05-10 11:38:11 +0200
committerAndreas Robinson <andr345@gmail.com>2009-05-12 12:55:40 +0200
commit4ac9bc5b709b8a665e828e9543fdf65119beba7e (patch)
tree83bc4b6664dba2415f71fb86dd475a7f41aecd92
parent90822ab233d2bbd347bdfaac4be407e924dbd5ae (diff)
downloadmodule-init-tools-4ac9bc5b709b8a665e828e9543fdf65119beba7e.tar.gz
move ELF-related code into elfops
Specifically depmod.h => elfops.h: struct module_tables and struct elf_file elfops.c => elfops_core.c: X-macros (eg PERBIT) elf_core.c => elfops_core.c: get_section() util.[ch] => elfops.[ch]: elf_ident() and get_section() Additionally, elf_core.c is deleted, being replaced by elfops_core.c Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r--depmod.h39
-rw-r--r--elf_core.c43
-rw-r--r--elfops.c46
-rw-r--r--elfops.h46
-rw-r--r--elfops_core.c63
-rw-r--r--modinfo.c1
-rw-r--r--modprobe.c1
-rw-r--r--util.c45
-rw-r--r--util.h8
9 files changed, 149 insertions, 143 deletions
diff --git a/depmod.h b/depmod.h
index f661808..be06b7c 100644
--- a/depmod.h
+++ b/depmod.h
@@ -1,44 +1,7 @@
#ifndef MODINITTOOLS_DEPMOD_H
#define MODINITTOOLS_DEPMOD_H
#include "list.h"
-
-/* Tables extracted from module by ops->fetch_tables(). */
-struct module_tables {
- unsigned int pci_size;
- void *pci_table;
- unsigned int usb_size;
- void *usb_table;
- unsigned int ieee1394_size;
- void *ieee1394_table;
- unsigned int ccw_size;
- void *ccw_table;
- unsigned int pnp_size;
- void *pnp_table;
- unsigned int pnp_card_size;
- unsigned int pnp_card_offset;
- void *pnp_card_table;
- unsigned int input_size;
- void *input_table;
- unsigned int input_table_size;
- unsigned int serio_size;
- void *serio_table;
- unsigned int of_size;
- void *of_table;
-};
-
-struct elf_file
-{
- /* File operations */
- struct module_ops *ops;
-
- /* Convert endian? */
- int conv;
-
- /* File contents and length. */
- void *data;
- unsigned long len;
-};
-
+#include "elfops.h"
struct module;
diff --git a/elf_core.c b/elf_core.c
deleted file mode 100644
index 1525c36..0000000
--- a/elf_core.c
+++ /dev/null
@@ -1,43 +0,0 @@
-void *PERBIT(get_section)(void *file,
- unsigned long fsize,
- const char *secname,
- unsigned long *secsize,
- int conv)
-{
- ElfPERBIT(Ehdr) *hdr;
- ElfPERBIT(Shdr) *sechdrs;
- ElfPERBIT(Off) e_shoff;
- ElfPERBIT(Half) e_shnum, e_shstrndx;
-
- const char *secnames;
- unsigned int i;
-
- if (fsize > 0 && fsize < sizeof(*hdr))
- return NULL;
-
- hdr = file;
- e_shoff = END(hdr->e_shoff, conv);
- e_shnum = END(hdr->e_shnum, conv);
- e_shstrndx = END(hdr->e_shstrndx, conv);
-
- if (fsize > 0 && fsize < e_shoff + e_shnum * sizeof(sechdrs[0]))
- return NULL;
-
- sechdrs = file + e_shoff;
-
- if (fsize > 0 && fsize < END(sechdrs[e_shstrndx].sh_offset, conv))
- return NULL;
-
- /* Find section by name, return pointer and size. */
-
- secnames = file + END(sechdrs[e_shstrndx].sh_offset, conv);
- for (i = 1; i < e_shnum; i++) {
- if (streq(secnames + END(sechdrs[i].sh_name, conv), secname)) {
- *secsize = END(sechdrs[i].sh_size, conv);
- return file + END(sechdrs[i].sh_offset, conv);
- }
- }
- *secsize = 0;
- return NULL;
-}
-
diff --git a/elfops.c b/elfops.c
index e9d74ef..2d38051 100644
--- a/elfops.c
+++ b/elfops.c
@@ -11,15 +11,43 @@
#include "elfops.h"
#include "tables.h"
-#define PERBIT(x) x##32
-#define ElfPERBIT(x) Elf32_##x
-#define ELFPERBIT(x) ELF32_##x
+#define ELF32BIT
#include "elfops_core.c"
+#undef ELF32BIT
-#undef PERBIT
-#undef ElfPERBIT
-#undef ELFPERBIT
-#define PERBIT(x) x##64
-#define ElfPERBIT(x) Elf64_##x
-#define ELFPERBIT(x) ELF64_##x
+#define ELF64BIT
#include "elfops_core.c"
+#undef ELF64BIT
+
+/*
+ * Check ELF file header.
+ */
+int elf_ident(void *file, unsigned long fsize, int *conv)
+{
+ /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
+ unsigned char *ident = file;
+
+ if (fsize < EI_CLASS || memcmp(file, ELFMAG, SELFMAG) != 0)
+ return -ENOEXEC; /* Not an ELF object */
+ if (ident[EI_DATA] == 0 || ident[EI_DATA] > 2)
+ return -EINVAL; /* Unknown endianness */
+
+ if (conv != NULL)
+ *conv = native_endianness() != ident[EI_DATA];
+ return ident[EI_CLASS];
+}
+
+void *get_section(void *file, unsigned long filesize,
+ const char *secname, unsigned long *secsize)
+{
+ int conv;
+
+ switch (elf_ident(file, filesize, &conv)) {
+ case ELFCLASS32:
+ return get_section32(file, filesize, secname, secsize, conv);
+ case ELFCLASS64:
+ return get_section64(file, filesize, secname, secsize, conv);
+ default:
+ return NULL;
+ }
+}
diff --git a/elfops.h b/elfops.h
index dd74432..dc10c3d 100644
--- a/elfops.h
+++ b/elfops.h
@@ -14,6 +14,44 @@ struct kernel_symbol64 {
char name[64 - 8];
};
+struct elf_file
+{
+ /* File operations */
+ struct module_ops *ops;
+
+ /* Convert endian? */
+ int conv;
+
+ /* File contents and length. */
+ void *data;
+ unsigned long len;
+};
+
+/* Tables extracted from module by ops->fetch_tables(). */
+struct module_tables
+{
+ unsigned int pci_size;
+ void *pci_table;
+ unsigned int usb_size;
+ void *usb_table;
+ unsigned int ieee1394_size;
+ void *ieee1394_table;
+ unsigned int ccw_size;
+ void *ccw_table;
+ unsigned int pnp_size;
+ void *pnp_table;
+ unsigned int pnp_card_size;
+ unsigned int pnp_card_offset;
+ void *pnp_card_table;
+ unsigned int input_size;
+ void *input_table;
+ unsigned int input_table_size;
+ unsigned int serio_size;
+ void *serio_table;
+ unsigned int of_size;
+ void *of_table;
+};
+
struct module_ops
{
struct string_table *(*load_strings)(struct elf_file *module,
@@ -29,4 +67,12 @@ struct module_ops
extern struct module_ops mod_ops32, mod_ops64;
+int elf_ident(void *file, unsigned long fsize, int *conv);
+void *get_section(void *file, unsigned long filesize,
+ const char *secname, unsigned long *secsize);
+void *get_section32(void *file, unsigned long filesize,
+ const char *secname, unsigned long *secsize, int conv);
+void *get_section64(void *file, unsigned long filesize,
+ const char *secname, unsigned long *secsize, int conv);
+
#endif /* MODINITTOOLS_MODULEOPS_H */
diff --git a/elfops_core.c b/elfops_core.c
index 4649b3f..8e6f37e 100644
--- a/elfops_core.c
+++ b/elfops_core.c
@@ -1,3 +1,62 @@
+#if defined(ELF32BIT)
+
+#define PERBIT(x) x##32
+#define ElfPERBIT(x) Elf32_##x
+#define ELFPERBIT(x) ELF32_##x
+
+#elif defined(ELF64BIT)
+
+#define PERBIT(x) x##64
+#define ElfPERBIT(x) Elf64_##x
+#define ELFPERBIT(x) ELF64_##x
+
+#else
+# error "Undefined ELF word length"
+#endif
+
+void *PERBIT(get_section)(void *file,
+ unsigned long fsize,
+ const char *secname,
+ unsigned long *secsize,
+ int conv)
+{
+ ElfPERBIT(Ehdr) *hdr;
+ ElfPERBIT(Shdr) *sechdrs;
+ ElfPERBIT(Off) e_shoff;
+ ElfPERBIT(Half) e_shnum, e_shstrndx;
+
+ const char *secnames;
+ unsigned int i;
+
+ if (fsize > 0 && fsize < sizeof(*hdr))
+ return NULL;
+
+ hdr = file;
+ e_shoff = END(hdr->e_shoff, conv);
+ e_shnum = END(hdr->e_shnum, conv);
+ e_shstrndx = END(hdr->e_shstrndx, conv);
+
+ if (fsize > 0 && fsize < e_shoff + e_shnum * sizeof(sechdrs[0]))
+ return NULL;
+
+ sechdrs = file + e_shoff;
+
+ if (fsize > 0 && fsize < END(sechdrs[e_shstrndx].sh_offset, conv))
+ return NULL;
+
+ /* Find section by name, return pointer and size. */
+
+ secnames = file + END(sechdrs[e_shstrndx].sh_offset, conv);
+ for (i = 1; i < e_shnum; i++) {
+ if (streq(secnames + END(sechdrs[i].sh_name, conv), secname)) {
+ *secsize = END(sechdrs[i].sh_size, conv);
+ return file + END(sechdrs[i].sh_offset, conv);
+ }
+ }
+ *secsize = 0;
+ return NULL;
+}
+
/* Load the given section: NULL on error. */
static void *PERBIT(load_section)(struct elf_file *module,
const char *secname,
@@ -238,3 +297,7 @@ struct module_ops PERBIT(mod_ops) = {
.get_aliases = PERBIT(get_aliases),
.get_modinfo = PERBIT(get_modinfo),
};
+
+#undef PERBIT
+#undef ElfPERBIT
+#undef ELFPERBIT
diff --git a/modinfo.c b/modinfo.c
index 07199c2..4f16c78 100644
--- a/modinfo.c
+++ b/modinfo.c
@@ -14,6 +14,7 @@
#include <sys/mman.h>
#include "util.h"
+#include "elfops.h"
#include "zlibsupport.h"
#include "testing.h"
diff --git a/modprobe.c b/modprobe.c
index c2d0ef6..c0680a7 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -40,6 +40,7 @@
#include <syslog.h>
#include "util.h"
+#include "elfops.h"
#include "zlibsupport.h"
#include "logging.h"
#include "index.h"
diff --git a/util.c b/util.c
index d3342df..07ac2b1 100644
--- a/util.c
+++ b/util.c
@@ -190,48 +190,3 @@ int __attribute__ ((pure)) native_endianness()
return (char) *((uint32_t*)("\1\0\0\2"));
}
-/*
- * Check ELF file header.
- */
-int elf_ident(void *file, unsigned long fsize, int *conv)
-{
- /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
- unsigned char *ident = file;
-
- if (fsize < EI_CLASS || memcmp(file, ELFMAG, SELFMAG) != 0)
- return -ENOEXEC; /* Not an ELF object */
- if (ident[EI_DATA] == 0 || ident[EI_DATA] > 2)
- return -EINVAL; /* Unknown endianness */
-
- if (conv != NULL)
- *conv = native_endianness() != ident[EI_DATA];
- return ident[EI_CLASS];
-}
-
-#define PERBIT(x) x##32
-#define ElfPERBIT(x) Elf32_##x
-#define ELFPERBIT(x) ELF32_##x
-#include "elf_core.c"
-
-#undef PERBIT
-#undef ElfPERBIT
-#undef ELFPERBIT
-#define PERBIT(x) x##64
-#define ElfPERBIT(x) Elf64_##x
-#define ELFPERBIT(x) ELF64_##x
-#include "elf_core.c"
-
-void *get_section(void *file, unsigned long filesize,
- const char *secname, unsigned long *secsize)
-{
- int conv;
-
- switch (elf_ident(file, filesize, &conv)) {
- case ELFCLASS32:
- return get_section32(file, filesize, secname, secsize, conv);
- case ELFCLASS64:
- return get_section64(file, filesize, secname, secsize, conv);
- default:
- return NULL;
- }
-}
diff --git a/util.h b/util.h
index 7eef1d6..d6112b0 100644
--- a/util.h
+++ b/util.h
@@ -40,14 +40,6 @@ static inline void __swap_bytes(const void *src, void *dest, unsigned int size)
int native_endianness(void);
-int elf_ident(void *file, unsigned long fsize, int *conv);
-void *get_section(void *file, unsigned long filesize,
- const char *secname, unsigned long *secsize);
-void *get_section32(void *file, unsigned long filesize,
- const char *secname, unsigned long *secsize, int conv);
-void *get_section64(void *file, unsigned long filesize,
- const char *secname, unsigned long *secsize, int conv);
-
#define streq(a,b) (strcmp((a),(b)) == 0)
#define strstarts(a,start) (strncmp((a),(start), strlen(start)) == 0)