1 /* The nasty work of reading 32 and 64-bit modules is in here. */
14 #include "zlibsupport.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] == '.')
32 #include "elfops_core.c"
36 #include "elfops_core.c"
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 */
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
));
72 file
->pathname
= strdup(pathname
);
73 if (!file
->pathname
) {
77 file
->data
= grab_file(pathname
, &file
->len
);
79 goto fail_free_pathname
;
81 switch (elf_ident(file
->data
, file
->len
, &file
->conv
)) {
83 file
->ops
= &mod_ops32
;
86 file
->ops
= &mod_ops64
;
88 case -ENOEXEC
: /* Not an ELF object */
89 case -EINVAL
: /* Unknown endianness */
90 default: /* Unknown word size */
104 void release_elf_file(struct elf_file
*file
)
111 release_file(file
->data
, file
->len
);
112 free(file
->pathname
);