11da177e4SLinus Torvalds #include <stdio.h> 21da177e4SLinus Torvalds #include <stdlib.h> 31da177e4SLinus Torvalds #include <stdarg.h> 41da177e4SLinus Torvalds #include <string.h> 51da177e4SLinus Torvalds #include <sys/types.h> 61da177e4SLinus Torvalds #include <sys/stat.h> 71da177e4SLinus Torvalds #include <sys/mman.h> 81da177e4SLinus Torvalds #include <fcntl.h> 91da177e4SLinus Torvalds #include <unistd.h> 101da177e4SLinus Torvalds #include <elf.h> 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include "elfconfig.h" 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #if KERNEL_ELFCLASS == ELFCLASS32 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds #define Elf_Ehdr Elf32_Ehdr 171da177e4SLinus Torvalds #define Elf_Shdr Elf32_Shdr 181da177e4SLinus Torvalds #define Elf_Sym Elf32_Sym 19b39927cfSSam Ravnborg #define Elf_Addr Elf32_Addr 20b39927cfSSam Ravnborg #define Elf_Section Elf32_Section 211da177e4SLinus Torvalds #define ELF_ST_BIND ELF32_ST_BIND 221da177e4SLinus Torvalds #define ELF_ST_TYPE ELF32_ST_TYPE 231da177e4SLinus Torvalds 242c1a51f3SAtsushi Nemoto #define Elf_Rel Elf32_Rel 25b39927cfSSam Ravnborg #define Elf_Rela Elf32_Rela 26b39927cfSSam Ravnborg #define ELF_R_SYM ELF32_R_SYM 27b39927cfSSam Ravnborg #define ELF_R_TYPE ELF32_R_TYPE 281da177e4SLinus Torvalds #else 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds #define Elf_Ehdr Elf64_Ehdr 311da177e4SLinus Torvalds #define Elf_Shdr Elf64_Shdr 321da177e4SLinus Torvalds #define Elf_Sym Elf64_Sym 33b39927cfSSam Ravnborg #define Elf_Addr Elf64_Addr 34b39927cfSSam Ravnborg #define Elf_Section Elf64_Section 351da177e4SLinus Torvalds #define ELF_ST_BIND ELF64_ST_BIND 361da177e4SLinus Torvalds #define ELF_ST_TYPE ELF64_ST_TYPE 371da177e4SLinus Torvalds 382c1a51f3SAtsushi Nemoto #define Elf_Rel Elf64_Rel 39b39927cfSSam Ravnborg #define Elf_Rela Elf64_Rela 40b39927cfSSam Ravnborg #define ELF_R_SYM ELF64_R_SYM 41b39927cfSSam Ravnborg #define ELF_R_TYPE ELF64_R_TYPE 421da177e4SLinus Torvalds #endif 431da177e4SLinus Torvalds 44eae07ac6SAtsushi Nemoto /* The 64-bit MIPS ELF ABI uses an unusual reloc format. */ 45eae07ac6SAtsushi Nemoto typedef struct 46eae07ac6SAtsushi Nemoto { 47eae07ac6SAtsushi Nemoto Elf32_Word r_sym; /* Symbol index */ 48eae07ac6SAtsushi Nemoto unsigned char r_ssym; /* Special symbol for 2nd relocation */ 49eae07ac6SAtsushi Nemoto unsigned char r_type3; /* 3rd relocation type */ 50eae07ac6SAtsushi Nemoto unsigned char r_type2; /* 2nd relocation type */ 51eae07ac6SAtsushi Nemoto unsigned char r_type1; /* 1st relocation type */ 52eae07ac6SAtsushi Nemoto } _Elf64_Mips_R_Info; 53eae07ac6SAtsushi Nemoto 54eae07ac6SAtsushi Nemoto typedef union 55eae07ac6SAtsushi Nemoto { 56eae07ac6SAtsushi Nemoto Elf64_Xword r_info_number; 57eae07ac6SAtsushi Nemoto _Elf64_Mips_R_Info r_info_fields; 58eae07ac6SAtsushi Nemoto } _Elf64_Mips_R_Info_union; 59eae07ac6SAtsushi Nemoto 60eae07ac6SAtsushi Nemoto #define ELF64_MIPS_R_SYM(i) \ 61eae07ac6SAtsushi Nemoto ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) 62eae07ac6SAtsushi Nemoto 631da177e4SLinus Torvalds #if KERNEL_ELFDATA != HOST_ELFDATA 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds static inline void __endian(const void *src, void *dest, unsigned int size) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds unsigned int i; 681da177e4SLinus Torvalds for (i = 0; i < size; i++) 691da177e4SLinus Torvalds ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1]; 701da177e4SLinus Torvalds } 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds #define TO_NATIVE(x) \ 731da177e4SLinus Torvalds ({ \ 741da177e4SLinus Torvalds typeof(x) __x; \ 751da177e4SLinus Torvalds __endian(&(x), &(__x), sizeof(__x)); \ 761da177e4SLinus Torvalds __x; \ 771da177e4SLinus Torvalds }) 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds #else /* endianness matches */ 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds #define TO_NATIVE(x) (x) 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds #endif 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds #define NOFAIL(ptr) do_nofail((ptr), #ptr) 861da177e4SLinus Torvalds void *do_nofail(void *ptr, const char *expr); 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds struct buffer { 891da177e4SLinus Torvalds char *p; 901da177e4SLinus Torvalds int pos; 911da177e4SLinus Torvalds int size; 921da177e4SLinus Torvalds }; 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds void __attribute__((format(printf, 2, 3))) 951da177e4SLinus Torvalds buf_printf(struct buffer *buf, const char *fmt, ...); 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds void 981da177e4SLinus Torvalds buf_write(struct buffer *buf, const char *s, int len); 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds struct module { 1011da177e4SLinus Torvalds struct module *next; 1021da177e4SLinus Torvalds const char *name; 1031da177e4SLinus Torvalds struct symbol *unres; 1041da177e4SLinus Torvalds int seen; 1051da177e4SLinus Torvalds int skip; 1061da177e4SLinus Torvalds int has_init; 1071da177e4SLinus Torvalds int has_cleanup; 1081da177e4SLinus Torvalds struct buffer dev_table_buf; 1091da177e4SLinus Torvalds char srcversion[25]; 1101da177e4SLinus Torvalds }; 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds struct elf_info { 1131da177e4SLinus Torvalds unsigned long size; 1141da177e4SLinus Torvalds Elf_Ehdr *hdr; 1151da177e4SLinus Torvalds Elf_Shdr *sechdrs; 1161da177e4SLinus Torvalds Elf_Sym *symtab_start; 1171da177e4SLinus Torvalds Elf_Sym *symtab_stop; 118*bd5cbcedSRam Pai Elf_Section export_sec; 119*bd5cbcedSRam Pai Elf_Section export_gpl_sec; 120*bd5cbcedSRam Pai Elf_Section export_gpl_future_sec; 1211da177e4SLinus Torvalds const char *strtab; 1221da177e4SLinus Torvalds char *modinfo; 1231da177e4SLinus Torvalds unsigned int modinfo_len; 1241da177e4SLinus Torvalds }; 1251da177e4SLinus Torvalds 126cb80514dSSam Ravnborg /* file2alias.c */ 1271da177e4SLinus Torvalds void handle_moddevtable(struct module *mod, struct elf_info *info, 1281da177e4SLinus Torvalds Elf_Sym *sym, const char *symname); 1291da177e4SLinus Torvalds void add_moddevtable(struct buffer *buf, struct module *mod); 1301da177e4SLinus Torvalds 131cb80514dSSam Ravnborg /* sumversion.c */ 1321da177e4SLinus Torvalds void maybe_frob_rcs_version(const char *modfilename, 1331da177e4SLinus Torvalds char *version, 1341da177e4SLinus Torvalds void *modinfo, 1351da177e4SLinus Torvalds unsigned long modinfo_offset); 1361da177e4SLinus Torvalds void get_src_version(const char *modname, char sum[], unsigned sumlen); 1371da177e4SLinus Torvalds 138cb80514dSSam Ravnborg /* from modpost.c */ 1391da177e4SLinus Torvalds void *grab_file(const char *filename, unsigned long *size); 1401da177e4SLinus Torvalds char* get_next_line(unsigned long *pos, void *file, unsigned long size); 1411da177e4SLinus Torvalds void release_file(void *file, unsigned long size); 142cb80514dSSam Ravnborg 143cb80514dSSam Ravnborg void fatal(const char *fmt, ...); 144cb80514dSSam Ravnborg void warn(const char *fmt, ...); 145