0001
0002 #include <stdbool.h>
0003 #include <stdio.h>
0004 #include <stdlib.h>
0005 #include <stdarg.h>
0006 #include <string.h>
0007 #include <sys/types.h>
0008 #include <sys/stat.h>
0009 #include <sys/mman.h>
0010 #include <fcntl.h>
0011 #include <unistd.h>
0012 #include <elf.h>
0013
0014 #include "list.h"
0015 #include "elfconfig.h"
0016
0017
0018 #undef ELF_ST_BIND
0019 #undef ELF_ST_TYPE
0020 #undef ELF_R_SYM
0021 #undef ELF_R_TYPE
0022
0023 #if KERNEL_ELFCLASS == ELFCLASS32
0024
0025 #define Elf_Ehdr Elf32_Ehdr
0026 #define Elf_Shdr Elf32_Shdr
0027 #define Elf_Sym Elf32_Sym
0028 #define Elf_Addr Elf32_Addr
0029 #define Elf_Section Elf32_Half
0030 #define ELF_ST_BIND ELF32_ST_BIND
0031 #define ELF_ST_TYPE ELF32_ST_TYPE
0032
0033 #define Elf_Rel Elf32_Rel
0034 #define Elf_Rela Elf32_Rela
0035 #define ELF_R_SYM ELF32_R_SYM
0036 #define ELF_R_TYPE ELF32_R_TYPE
0037 #else
0038
0039 #define Elf_Ehdr Elf64_Ehdr
0040 #define Elf_Shdr Elf64_Shdr
0041 #define Elf_Sym Elf64_Sym
0042 #define Elf_Addr Elf64_Addr
0043 #define Elf_Section Elf64_Half
0044 #define ELF_ST_BIND ELF64_ST_BIND
0045 #define ELF_ST_TYPE ELF64_ST_TYPE
0046
0047 #define Elf_Rel Elf64_Rel
0048 #define Elf_Rela Elf64_Rela
0049 #define ELF_R_SYM ELF64_R_SYM
0050 #define ELF_R_TYPE ELF64_R_TYPE
0051 #endif
0052
0053
0054 typedef struct
0055 {
0056 Elf32_Word r_sym;
0057 unsigned char r_ssym;
0058 unsigned char r_type3;
0059 unsigned char r_type2;
0060 unsigned char r_type1;
0061 } _Elf64_Mips_R_Info;
0062
0063 typedef union
0064 {
0065 Elf64_Xword r_info_number;
0066 _Elf64_Mips_R_Info r_info_fields;
0067 } _Elf64_Mips_R_Info_union;
0068
0069 #define ELF64_MIPS_R_SYM(i) \
0070 ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
0071
0072 #define ELF64_MIPS_R_TYPE(i) \
0073 ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
0074
0075 #if KERNEL_ELFDATA != HOST_ELFDATA
0076
0077 static inline void __endian(const void *src, void *dest, unsigned int size)
0078 {
0079 unsigned int i;
0080 for (i = 0; i < size; i++)
0081 ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
0082 }
0083
0084 #define TO_NATIVE(x) \
0085 ({ \
0086 typeof(x) __x; \
0087 __endian(&(x), &(__x), sizeof(__x)); \
0088 __x; \
0089 })
0090
0091 #else
0092
0093 #define TO_NATIVE(x) (x)
0094
0095 #endif
0096
0097 #define NOFAIL(ptr) do_nofail((ptr), #ptr)
0098
0099 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
0100
0101 void *do_nofail(void *ptr, const char *expr);
0102
0103 struct buffer {
0104 char *p;
0105 int pos;
0106 int size;
0107 };
0108
0109 void __attribute__((format(printf, 2, 3)))
0110 buf_printf(struct buffer *buf, const char *fmt, ...);
0111
0112 void
0113 buf_write(struct buffer *buf, const char *s, int len);
0114
0115 struct module {
0116 struct list_head list;
0117 struct list_head exported_symbols;
0118 struct list_head unresolved_symbols;
0119 bool is_gpl_compatible;
0120 bool from_dump;
0121 bool is_vmlinux;
0122 bool seen;
0123 bool has_init;
0124 bool has_cleanup;
0125 struct buffer dev_table_buf;
0126 char srcversion[25];
0127
0128 struct list_head missing_namespaces;
0129
0130 struct list_head imported_namespaces;
0131 char name[];
0132 };
0133
0134 struct elf_info {
0135 size_t size;
0136 Elf_Ehdr *hdr;
0137 Elf_Shdr *sechdrs;
0138 Elf_Sym *symtab_start;
0139 Elf_Sym *symtab_stop;
0140 char *strtab;
0141 char *modinfo;
0142 unsigned int modinfo_len;
0143
0144
0145
0146 unsigned int num_sections;
0147 unsigned int secindex_strings;
0148
0149
0150 Elf32_Word *symtab_shndx_start;
0151 Elf32_Word *symtab_shndx_stop;
0152 };
0153
0154 static inline int is_shndx_special(unsigned int i)
0155 {
0156 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
0157 }
0158
0159
0160 static inline unsigned int get_secindex(const struct elf_info *info,
0161 const Elf_Sym *sym)
0162 {
0163 unsigned int index = sym->st_shndx;
0164
0165
0166
0167
0168
0169 if (index == SHN_XINDEX)
0170 return info->symtab_shndx_start[sym - info->symtab_start];
0171
0172
0173
0174
0175
0176
0177 if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE)
0178 return index - SHN_HIRESERVE - 1;
0179
0180 return index;
0181 }
0182
0183
0184 void handle_moddevtable(struct module *mod, struct elf_info *info,
0185 Elf_Sym *sym, const char *symname);
0186 void add_moddevtable(struct buffer *buf, struct module *mod);
0187
0188
0189 void get_src_version(const char *modname, char sum[], unsigned sumlen);
0190
0191
0192 char *read_text_file(const char *filename);
0193 char *get_line(char **stringp);
0194 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
0195
0196 enum loglevel {
0197 LOG_WARN,
0198 LOG_ERROR,
0199 LOG_FATAL
0200 };
0201
0202 void modpost_log(enum loglevel loglevel, const char *fmt, ...);
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 #define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
0218 #define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
0219 #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)