depmod: export static device node information to modules.devname
[mit.git] / elfops.c
blob10e80ea487d430f65b9aa81318277b34011d59fe
1 /* The nasty work of reading 32 and 64-bit modules is in here. */
2 #include <elf.h>
3 #include <sys/types.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include "depmod.h"
10 #include "util.h"
11 #include "logging.h"
12 #include "elfops.h"
13 #include "tables.h"
14 #include "zlibsupport.h"
16 #include "testing.h"
18 /* Symbol types, returned by load_dep_syms */
19 static const char *weak_sym = "W";
20 static const char *undef_sym = "U";
22 /* dump_modversions helper */
23 static const char *skip_dot(const char *str)
25 /* For our purposes, .foo matches foo. PPC64 needs this. */
26 if (str && str[0] == '.')
27 return str + 1;
28 return str;
31 #define ELF32BIT
32 #include "elfops_core.c"
33 #undef ELF32BIT
35 #define ELF64BIT
36 #include "elfops_core.c"
37 #undef ELF64BIT
40 * Check ELF file header.
42 static int elf_ident(void *file, unsigned long fsize, int *conv)
44 /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
45 unsigned char *ident = file;
47 if (fsize < EI_CLASS || memcmp(file, ELFMAG, SELFMAG) != 0)
48 return -ENOEXEC; /* Not an ELF object */
49 if (ident[EI_DATA] == 0 || ident[EI_DATA] > 2)
50 return -EINVAL; /* Unknown endianness */
52 if (conv != NULL)
53 *conv = native_endianness() != ident[EI_DATA];
54 return ident[EI_CLASS];
58 * grab_elf_file - read ELF file into memory
59 * @pathame: file to load
61 * Returns NULL, and errno set on error.
63 struct elf_file *grab_elf_file(const char *pathname)
65 struct elf_file *file;
67 file = malloc(sizeof(*file));
68 if (!file) {
69 errno = ENOMEM;
70 goto fail;
72 file->pathname = strdup(pathname);
73 if (!file->pathname) {
74 errno = ENOMEM;
75 goto fail_free_file;
77 file->data = grab_file(pathname, &file->len);
78 if (!file->data)
79 goto fail_free_pathname;
81 switch (elf_ident(file->data, file->len, &file->conv)) {
82 case ELFCLASS32:
83 file->ops = &mod_ops32;
84 break;
85 case ELFCLASS64:
86 file->ops = &mod_ops64;
87 break;
88 case -ENOEXEC: /* Not an ELF object */
89 case -EINVAL: /* Unknown endianness */
90 default: /* Unknown word size */
91 errno = ENOEXEC;
92 goto fail;
94 return file;
96 fail_free_pathname:
97 free(file->pathname);
98 fail_free_file:
99 free(file);
100 fail:
101 return NULL;
104 void release_elf_file(struct elf_file *file)
106 int err = errno;
108 if (!file)
109 return;
111 release_file(file->data, file->len);
112 free(file->pathname);
113 free(file);
115 errno = err;