1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
/* SPDX-License-Identifier: GPL-2.0 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
#include "elfconfig.h"
/* On BSD-alike OSes elf.h defines these according to host's word size */
#undef ELF_ST_BIND
#undef ELF_ST_TYPE
#undef ELF_R_SYM
#undef ELF_R_TYPE
#if KERNEL_ELFCLASS == ELFCLASS32
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Addr Elf32_Addr
#define Elf_Sword Elf64_Sword
#define Elf_Section Elf32_Half
#define ELF_ST_BIND ELF32_ST_BIND
#define ELF_ST_TYPE ELF32_ST_TYPE
#define Elf_Rel Elf32_Rel
#define Elf_Rela Elf32_Rela
#define ELF_R_SYM ELF32_R_SYM
#define ELF_R_TYPE ELF32_R_TYPE
#else
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Addr Elf64_Addr
#define Elf_Sword Elf64_Sxword
#define Elf_Section Elf64_Half
#define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE
#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
#define ELF_R_SYM ELF64_R_SYM
#define ELF_R_TYPE ELF64_R_TYPE
#endif
/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
typedef struct
{
Elf32_Word r_sym; /* Symbol index */
unsigned char r_ssym; /* Special symbol for 2nd relocation */
unsigned char r_type3; /* 3rd relocation type */
unsigned char r_type2; /* 2nd relocation type */
unsigned char r_type1; /* 1st relocation type */
} _Elf64_Mips_R_Info;
typedef union
{
Elf64_Xword r_info_number;
_Elf64_Mips_R_Info r_info_fields;
} _Elf64_Mips_R_Info_union;
#define ELF64_MIPS_R_SYM(i) \
((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
#define ELF64_MIPS_R_TYPE(i) \
((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1)
#if KERNEL_ELFDATA != HOST_ELFDATA
static inline void __endian(const void *src, void *dest, unsigned int size)
{
unsigned int i;
for (i = 0; i < size; i++)
((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
}
#define TO_NATIVE(x) \
({ \
typeof(x) __x; \
__endian(&(x), &(__x), sizeof(__x)); \
__x; \
})
#else /* endianness matches */
#define TO_NATIVE(x) (x)
#endif
#define NOFAIL(ptr) do_nofail((ptr), #ptr)
void *do_nofail(void *ptr, const char *expr);
struct buffer {
char *p;
int pos;
int size;
};
void __attribute__((format(printf, 2, 3)))
buf_printf(struct buffer *buf, const char *fmt, ...);
void
buf_write(struct buffer *buf, const char *s, int len);
struct namespace_list {
struct namespace_list *next;
char namespace[];
};
struct module {
struct module *next;
const char *name;
int gpl_compatible;
struct symbol *unres;
int from_dump; /* 1 if module was loaded from *.symvers */
int seen;
int skip;
int has_init;
int has_cleanup;
struct buffer dev_table_buf;
char srcversion[25];
int is_dot_o;
// Missing namespace dependencies
struct namespace_list *missing_namespaces;
// Actual imported namespaces
struct namespace_list *imported_namespaces;
};
struct elf_info {
unsigned long size;
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
Elf_Sym *symtab_start;
Elf_Sym *symtab_stop;
Elf_Section export_sec;
Elf_Section export_unused_sec;
Elf_Section export_gpl_sec;
Elf_Section export_unused_gpl_sec;
Elf_Section export_gpl_future_sec;
char *strtab;
char *modinfo;
unsigned int modinfo_len;
/* support for 32bit section numbers */
unsigned int num_sections; /* max_secindex + 1 */
unsigned int secindex_strings;
/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
* take shndx from symtab_shndx_start[N] instead */
Elf32_Word *symtab_shndx_start;
Elf32_Word *symtab_shndx_stop;
};
static inline int is_shndx_special(unsigned int i)
{
return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
}
/*
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
* the way to -256..-1, to avoid conflicting with real section
* indices.
*/
#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
static inline unsigned int get_secindex(const struct elf_info *info,
const Elf_Sym *sym)
{
if (is_shndx_special(sym->st_shndx))
return SPECIAL(sym->st_shndx);
if (sym->st_shndx != SHN_XINDEX)
return sym->st_shndx;
return info->symtab_shndx_start[sym - info->symtab_start];
}
/* file2alias.c */
extern unsigned int cross_build;
void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod);
/* sumversion.c */
void maybe_frob_rcs_version(const char *modfilename,
char *version,
void *modinfo,
unsigned long modinfo_offset);
void get_src_version(const char *modname, char sum[], unsigned sumlen);
/* from modpost.c */
void *grab_file(const char *filename, unsigned long *size);
char* get_next_line(unsigned long *pos, void *file, unsigned long size);
void release_file(void *file, unsigned long size);
enum loglevel {
LOG_WARN,
LOG_ERROR,
LOG_FATAL
};
void modpost_log(enum loglevel loglevel, const char *fmt, ...);
#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
#define merror(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
#define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)
|