Commit fa95eb1f17a5fe7b3593cff4bf27dbe9ae6cac89

Authored by Sam Ravnborg
1 parent 125e564582

kbuild: do not warn about __*init/__*exit symbols being exported

We have several legitimate uses where we export symbols
annotated with one of:
__devinit, __cpuinit, __meminit and their exit counterpart.
So let's stop warning about those being exported in favour
of adding all sorts of workaround to silence the warning.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

scripts/mod/modpost.c
1 /* Postprocess module symbol versions 1 /* Postprocess module symbol versions
2 * 2 *
3 * Copyright 2003 Kai Germaschewski 3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation 4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5 * Copyright 2006-2008 Sam Ravnborg 5 * Copyright 2006-2008 Sam Ravnborg
6 * Based in part on module-init-tools/depmod.c,file2alias 6 * Based in part on module-init-tools/depmod.c,file2alias
7 * 7 *
8 * This software may be used and distributed according to the terms 8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference. 9 * of the GNU General Public License, incorporated herein by reference.
10 * 10 *
11 * Usage: modpost vmlinux module1.o module2.o ... 11 * Usage: modpost vmlinux module1.o module2.o ...
12 */ 12 */
13 13
14 #include <ctype.h> 14 #include <ctype.h>
15 #include "modpost.h" 15 #include "modpost.h"
16 #include "../../include/linux/license.h" 16 #include "../../include/linux/license.h"
17 17
18 /* Are we using CONFIG_MODVERSIONS? */ 18 /* Are we using CONFIG_MODVERSIONS? */
19 int modversions = 0; 19 int modversions = 0;
20 /* Warn about undefined symbols? (do so if we have vmlinux) */ 20 /* Warn about undefined symbols? (do so if we have vmlinux) */
21 int have_vmlinux = 0; 21 int have_vmlinux = 0;
22 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ 22 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
23 static int all_versions = 0; 23 static int all_versions = 0;
24 /* If we are modposting external module set to 1 */ 24 /* If we are modposting external module set to 1 */
25 static int external_module = 0; 25 static int external_module = 0;
26 /* Warn about section mismatch in vmlinux if set to 1 */ 26 /* Warn about section mismatch in vmlinux if set to 1 */
27 static int vmlinux_section_warnings = 1; 27 static int vmlinux_section_warnings = 1;
28 /* Only warn about unresolved symbols */ 28 /* Only warn about unresolved symbols */
29 static int warn_unresolved = 0; 29 static int warn_unresolved = 0;
30 /* How a symbol is exported */ 30 /* How a symbol is exported */
31 static int sec_mismatch_count = 0; 31 static int sec_mismatch_count = 0;
32 static int sec_mismatch_verbose = 1; 32 static int sec_mismatch_verbose = 1;
33 33
34 enum export { 34 enum export {
35 export_plain, export_unused, export_gpl, 35 export_plain, export_unused, export_gpl,
36 export_unused_gpl, export_gpl_future, export_unknown 36 export_unused_gpl, export_gpl_future, export_unknown
37 }; 37 };
38 38
39 #define PRINTF __attribute__ ((format (printf, 1, 2))) 39 #define PRINTF __attribute__ ((format (printf, 1, 2)))
40 40
41 PRINTF void fatal(const char *fmt, ...) 41 PRINTF void fatal(const char *fmt, ...)
42 { 42 {
43 va_list arglist; 43 va_list arglist;
44 44
45 fprintf(stderr, "FATAL: "); 45 fprintf(stderr, "FATAL: ");
46 46
47 va_start(arglist, fmt); 47 va_start(arglist, fmt);
48 vfprintf(stderr, fmt, arglist); 48 vfprintf(stderr, fmt, arglist);
49 va_end(arglist); 49 va_end(arglist);
50 50
51 exit(1); 51 exit(1);
52 } 52 }
53 53
54 PRINTF void warn(const char *fmt, ...) 54 PRINTF void warn(const char *fmt, ...)
55 { 55 {
56 va_list arglist; 56 va_list arglist;
57 57
58 fprintf(stderr, "WARNING: "); 58 fprintf(stderr, "WARNING: ");
59 59
60 va_start(arglist, fmt); 60 va_start(arglist, fmt);
61 vfprintf(stderr, fmt, arglist); 61 vfprintf(stderr, fmt, arglist);
62 va_end(arglist); 62 va_end(arglist);
63 } 63 }
64 64
65 PRINTF void merror(const char *fmt, ...) 65 PRINTF void merror(const char *fmt, ...)
66 { 66 {
67 va_list arglist; 67 va_list arglist;
68 68
69 fprintf(stderr, "ERROR: "); 69 fprintf(stderr, "ERROR: ");
70 70
71 va_start(arglist, fmt); 71 va_start(arglist, fmt);
72 vfprintf(stderr, fmt, arglist); 72 vfprintf(stderr, fmt, arglist);
73 va_end(arglist); 73 va_end(arglist);
74 } 74 }
75 75
76 static int is_vmlinux(const char *modname) 76 static int is_vmlinux(const char *modname)
77 { 77 {
78 const char *myname; 78 const char *myname;
79 79
80 myname = strrchr(modname, '/'); 80 myname = strrchr(modname, '/');
81 if (myname) 81 if (myname)
82 myname++; 82 myname++;
83 else 83 else
84 myname = modname; 84 myname = modname;
85 85
86 return (strcmp(myname, "vmlinux") == 0) || 86 return (strcmp(myname, "vmlinux") == 0) ||
87 (strcmp(myname, "vmlinux.o") == 0); 87 (strcmp(myname, "vmlinux.o") == 0);
88 } 88 }
89 89
90 void *do_nofail(void *ptr, const char *expr) 90 void *do_nofail(void *ptr, const char *expr)
91 { 91 {
92 if (!ptr) 92 if (!ptr)
93 fatal("modpost: Memory allocation failure: %s.\n", expr); 93 fatal("modpost: Memory allocation failure: %s.\n", expr);
94 94
95 return ptr; 95 return ptr;
96 } 96 }
97 97
98 /* A list of all modules we processed */ 98 /* A list of all modules we processed */
99 static struct module *modules; 99 static struct module *modules;
100 100
101 static struct module *find_module(char *modname) 101 static struct module *find_module(char *modname)
102 { 102 {
103 struct module *mod; 103 struct module *mod;
104 104
105 for (mod = modules; mod; mod = mod->next) 105 for (mod = modules; mod; mod = mod->next)
106 if (strcmp(mod->name, modname) == 0) 106 if (strcmp(mod->name, modname) == 0)
107 break; 107 break;
108 return mod; 108 return mod;
109 } 109 }
110 110
111 static struct module *new_module(char *modname) 111 static struct module *new_module(char *modname)
112 { 112 {
113 struct module *mod; 113 struct module *mod;
114 char *p, *s; 114 char *p, *s;
115 115
116 mod = NOFAIL(malloc(sizeof(*mod))); 116 mod = NOFAIL(malloc(sizeof(*mod)));
117 memset(mod, 0, sizeof(*mod)); 117 memset(mod, 0, sizeof(*mod));
118 p = NOFAIL(strdup(modname)); 118 p = NOFAIL(strdup(modname));
119 119
120 /* strip trailing .o */ 120 /* strip trailing .o */
121 s = strrchr(p, '.'); 121 s = strrchr(p, '.');
122 if (s != NULL) 122 if (s != NULL)
123 if (strcmp(s, ".o") == 0) 123 if (strcmp(s, ".o") == 0)
124 *s = '\0'; 124 *s = '\0';
125 125
126 /* add to list */ 126 /* add to list */
127 mod->name = p; 127 mod->name = p;
128 mod->gpl_compatible = -1; 128 mod->gpl_compatible = -1;
129 mod->next = modules; 129 mod->next = modules;
130 modules = mod; 130 modules = mod;
131 131
132 return mod; 132 return mod;
133 } 133 }
134 134
135 /* A hash of all exported symbols, 135 /* A hash of all exported symbols,
136 * struct symbol is also used for lists of unresolved symbols */ 136 * struct symbol is also used for lists of unresolved symbols */
137 137
138 #define SYMBOL_HASH_SIZE 1024 138 #define SYMBOL_HASH_SIZE 1024
139 139
140 struct symbol { 140 struct symbol {
141 struct symbol *next; 141 struct symbol *next;
142 struct module *module; 142 struct module *module;
143 unsigned int crc; 143 unsigned int crc;
144 int crc_valid; 144 int crc_valid;
145 unsigned int weak:1; 145 unsigned int weak:1;
146 unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ 146 unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
147 unsigned int kernel:1; /* 1 if symbol is from kernel 147 unsigned int kernel:1; /* 1 if symbol is from kernel
148 * (only for external modules) **/ 148 * (only for external modules) **/
149 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ 149 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
150 enum export export; /* Type of export */ 150 enum export export; /* Type of export */
151 char name[0]; 151 char name[0];
152 }; 152 };
153 153
154 static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; 154 static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
155 155
156 /* This is based on the hash agorithm from gdbm, via tdb */ 156 /* This is based on the hash agorithm from gdbm, via tdb */
157 static inline unsigned int tdb_hash(const char *name) 157 static inline unsigned int tdb_hash(const char *name)
158 { 158 {
159 unsigned value; /* Used to compute the hash value. */ 159 unsigned value; /* Used to compute the hash value. */
160 unsigned i; /* Used to cycle through random values. */ 160 unsigned i; /* Used to cycle through random values. */
161 161
162 /* Set the initial value from the key size. */ 162 /* Set the initial value from the key size. */
163 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) 163 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
164 value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); 164 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
165 165
166 return (1103515243 * value + 12345); 166 return (1103515243 * value + 12345);
167 } 167 }
168 168
169 /** 169 /**
170 * Allocate a new symbols for use in the hash of exported symbols or 170 * Allocate a new symbols for use in the hash of exported symbols or
171 * the list of unresolved symbols per module 171 * the list of unresolved symbols per module
172 **/ 172 **/
173 static struct symbol *alloc_symbol(const char *name, unsigned int weak, 173 static struct symbol *alloc_symbol(const char *name, unsigned int weak,
174 struct symbol *next) 174 struct symbol *next)
175 { 175 {
176 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); 176 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
177 177
178 memset(s, 0, sizeof(*s)); 178 memset(s, 0, sizeof(*s));
179 strcpy(s->name, name); 179 strcpy(s->name, name);
180 s->weak = weak; 180 s->weak = weak;
181 s->next = next; 181 s->next = next;
182 return s; 182 return s;
183 } 183 }
184 184
185 /* For the hash of exported symbols */ 185 /* For the hash of exported symbols */
186 static struct symbol *new_symbol(const char *name, struct module *module, 186 static struct symbol *new_symbol(const char *name, struct module *module,
187 enum export export) 187 enum export export)
188 { 188 {
189 unsigned int hash; 189 unsigned int hash;
190 struct symbol *new; 190 struct symbol *new;
191 191
192 hash = tdb_hash(name) % SYMBOL_HASH_SIZE; 192 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
193 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); 193 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
194 new->module = module; 194 new->module = module;
195 new->export = export; 195 new->export = export;
196 return new; 196 return new;
197 } 197 }
198 198
199 static struct symbol *find_symbol(const char *name) 199 static struct symbol *find_symbol(const char *name)
200 { 200 {
201 struct symbol *s; 201 struct symbol *s;
202 202
203 /* For our purposes, .foo matches foo. PPC64 needs this. */ 203 /* For our purposes, .foo matches foo. PPC64 needs this. */
204 if (name[0] == '.') 204 if (name[0] == '.')
205 name++; 205 name++;
206 206
207 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { 207 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
208 if (strcmp(s->name, name) == 0) 208 if (strcmp(s->name, name) == 0)
209 return s; 209 return s;
210 } 210 }
211 return NULL; 211 return NULL;
212 } 212 }
213 213
214 static struct { 214 static struct {
215 const char *str; 215 const char *str;
216 enum export export; 216 enum export export;
217 } export_list[] = { 217 } export_list[] = {
218 { .str = "EXPORT_SYMBOL", .export = export_plain }, 218 { .str = "EXPORT_SYMBOL", .export = export_plain },
219 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused }, 219 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
220 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, 220 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
221 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl }, 221 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
222 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, 222 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
223 { .str = "(unknown)", .export = export_unknown }, 223 { .str = "(unknown)", .export = export_unknown },
224 }; 224 };
225 225
226 226
227 static const char *export_str(enum export ex) 227 static const char *export_str(enum export ex)
228 { 228 {
229 return export_list[ex].str; 229 return export_list[ex].str;
230 } 230 }
231 231
232 static enum export export_no(const char *s) 232 static enum export export_no(const char *s)
233 { 233 {
234 int i; 234 int i;
235 235
236 if (!s) 236 if (!s)
237 return export_unknown; 237 return export_unknown;
238 for (i = 0; export_list[i].export != export_unknown; i++) { 238 for (i = 0; export_list[i].export != export_unknown; i++) {
239 if (strcmp(export_list[i].str, s) == 0) 239 if (strcmp(export_list[i].str, s) == 0)
240 return export_list[i].export; 240 return export_list[i].export;
241 } 241 }
242 return export_unknown; 242 return export_unknown;
243 } 243 }
244 244
245 static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) 245 static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
246 { 246 {
247 if (sec == elf->export_sec) 247 if (sec == elf->export_sec)
248 return export_plain; 248 return export_plain;
249 else if (sec == elf->export_unused_sec) 249 else if (sec == elf->export_unused_sec)
250 return export_unused; 250 return export_unused;
251 else if (sec == elf->export_gpl_sec) 251 else if (sec == elf->export_gpl_sec)
252 return export_gpl; 252 return export_gpl;
253 else if (sec == elf->export_unused_gpl_sec) 253 else if (sec == elf->export_unused_gpl_sec)
254 return export_unused_gpl; 254 return export_unused_gpl;
255 else if (sec == elf->export_gpl_future_sec) 255 else if (sec == elf->export_gpl_future_sec)
256 return export_gpl_future; 256 return export_gpl_future;
257 else 257 else
258 return export_unknown; 258 return export_unknown;
259 } 259 }
260 260
261 /** 261 /**
262 * Add an exported symbol - it may have already been added without a 262 * Add an exported symbol - it may have already been added without a
263 * CRC, in this case just update the CRC 263 * CRC, in this case just update the CRC
264 **/ 264 **/
265 static struct symbol *sym_add_exported(const char *name, struct module *mod, 265 static struct symbol *sym_add_exported(const char *name, struct module *mod,
266 enum export export) 266 enum export export)
267 { 267 {
268 struct symbol *s = find_symbol(name); 268 struct symbol *s = find_symbol(name);
269 269
270 if (!s) { 270 if (!s) {
271 s = new_symbol(name, mod, export); 271 s = new_symbol(name, mod, export);
272 } else { 272 } else {
273 if (!s->preloaded) { 273 if (!s->preloaded) {
274 warn("%s: '%s' exported twice. Previous export " 274 warn("%s: '%s' exported twice. Previous export "
275 "was in %s%s\n", mod->name, name, 275 "was in %s%s\n", mod->name, name,
276 s->module->name, 276 s->module->name,
277 is_vmlinux(s->module->name) ?"":".ko"); 277 is_vmlinux(s->module->name) ?"":".ko");
278 } else { 278 } else {
279 /* In case Modules.symvers was out of date */ 279 /* In case Modules.symvers was out of date */
280 s->module = mod; 280 s->module = mod;
281 } 281 }
282 } 282 }
283 s->preloaded = 0; 283 s->preloaded = 0;
284 s->vmlinux = is_vmlinux(mod->name); 284 s->vmlinux = is_vmlinux(mod->name);
285 s->kernel = 0; 285 s->kernel = 0;
286 s->export = export; 286 s->export = export;
287 return s; 287 return s;
288 } 288 }
289 289
290 static void sym_update_crc(const char *name, struct module *mod, 290 static void sym_update_crc(const char *name, struct module *mod,
291 unsigned int crc, enum export export) 291 unsigned int crc, enum export export)
292 { 292 {
293 struct symbol *s = find_symbol(name); 293 struct symbol *s = find_symbol(name);
294 294
295 if (!s) 295 if (!s)
296 s = new_symbol(name, mod, export); 296 s = new_symbol(name, mod, export);
297 s->crc = crc; 297 s->crc = crc;
298 s->crc_valid = 1; 298 s->crc_valid = 1;
299 } 299 }
300 300
301 void *grab_file(const char *filename, unsigned long *size) 301 void *grab_file(const char *filename, unsigned long *size)
302 { 302 {
303 struct stat st; 303 struct stat st;
304 void *map; 304 void *map;
305 int fd; 305 int fd;
306 306
307 fd = open(filename, O_RDONLY); 307 fd = open(filename, O_RDONLY);
308 if (fd < 0 || fstat(fd, &st) != 0) 308 if (fd < 0 || fstat(fd, &st) != 0)
309 return NULL; 309 return NULL;
310 310
311 *size = st.st_size; 311 *size = st.st_size;
312 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); 312 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
313 close(fd); 313 close(fd);
314 314
315 if (map == MAP_FAILED) 315 if (map == MAP_FAILED)
316 return NULL; 316 return NULL;
317 return map; 317 return map;
318 } 318 }
319 319
320 /** 320 /**
321 * Return a copy of the next line in a mmap'ed file. 321 * Return a copy of the next line in a mmap'ed file.
322 * spaces in the beginning of the line is trimmed away. 322 * spaces in the beginning of the line is trimmed away.
323 * Return a pointer to a static buffer. 323 * Return a pointer to a static buffer.
324 **/ 324 **/
325 char *get_next_line(unsigned long *pos, void *file, unsigned long size) 325 char *get_next_line(unsigned long *pos, void *file, unsigned long size)
326 { 326 {
327 static char line[4096]; 327 static char line[4096];
328 int skip = 1; 328 int skip = 1;
329 size_t len = 0; 329 size_t len = 0;
330 signed char *p = (signed char *)file + *pos; 330 signed char *p = (signed char *)file + *pos;
331 char *s = line; 331 char *s = line;
332 332
333 for (; *pos < size ; (*pos)++) { 333 for (; *pos < size ; (*pos)++) {
334 if (skip && isspace(*p)) { 334 if (skip && isspace(*p)) {
335 p++; 335 p++;
336 continue; 336 continue;
337 } 337 }
338 skip = 0; 338 skip = 0;
339 if (*p != '\n' && (*pos < size)) { 339 if (*p != '\n' && (*pos < size)) {
340 len++; 340 len++;
341 *s++ = *p++; 341 *s++ = *p++;
342 if (len > 4095) 342 if (len > 4095)
343 break; /* Too long, stop */ 343 break; /* Too long, stop */
344 } else { 344 } else {
345 /* End of string */ 345 /* End of string */
346 *s = '\0'; 346 *s = '\0';
347 return line; 347 return line;
348 } 348 }
349 } 349 }
350 /* End of buffer */ 350 /* End of buffer */
351 return NULL; 351 return NULL;
352 } 352 }
353 353
354 void release_file(void *file, unsigned long size) 354 void release_file(void *file, unsigned long size)
355 { 355 {
356 munmap(file, size); 356 munmap(file, size);
357 } 357 }
358 358
359 static int parse_elf(struct elf_info *info, const char *filename) 359 static int parse_elf(struct elf_info *info, const char *filename)
360 { 360 {
361 unsigned int i; 361 unsigned int i;
362 Elf_Ehdr *hdr; 362 Elf_Ehdr *hdr;
363 Elf_Shdr *sechdrs; 363 Elf_Shdr *sechdrs;
364 Elf_Sym *sym; 364 Elf_Sym *sym;
365 365
366 hdr = grab_file(filename, &info->size); 366 hdr = grab_file(filename, &info->size);
367 if (!hdr) { 367 if (!hdr) {
368 perror(filename); 368 perror(filename);
369 exit(1); 369 exit(1);
370 } 370 }
371 info->hdr = hdr; 371 info->hdr = hdr;
372 if (info->size < sizeof(*hdr)) { 372 if (info->size < sizeof(*hdr)) {
373 /* file too small, assume this is an empty .o file */ 373 /* file too small, assume this is an empty .o file */
374 return 0; 374 return 0;
375 } 375 }
376 /* Is this a valid ELF file? */ 376 /* Is this a valid ELF file? */
377 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || 377 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
378 (hdr->e_ident[EI_MAG1] != ELFMAG1) || 378 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
379 (hdr->e_ident[EI_MAG2] != ELFMAG2) || 379 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
380 (hdr->e_ident[EI_MAG3] != ELFMAG3)) { 380 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
381 /* Not an ELF file - silently ignore it */ 381 /* Not an ELF file - silently ignore it */
382 return 0; 382 return 0;
383 } 383 }
384 /* Fix endianness in ELF header */ 384 /* Fix endianness in ELF header */
385 hdr->e_shoff = TO_NATIVE(hdr->e_shoff); 385 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
386 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); 386 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
387 hdr->e_shnum = TO_NATIVE(hdr->e_shnum); 387 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
388 hdr->e_machine = TO_NATIVE(hdr->e_machine); 388 hdr->e_machine = TO_NATIVE(hdr->e_machine);
389 hdr->e_type = TO_NATIVE(hdr->e_type); 389 hdr->e_type = TO_NATIVE(hdr->e_type);
390 sechdrs = (void *)hdr + hdr->e_shoff; 390 sechdrs = (void *)hdr + hdr->e_shoff;
391 info->sechdrs = sechdrs; 391 info->sechdrs = sechdrs;
392 392
393 /* Check if file offset is correct */ 393 /* Check if file offset is correct */
394 if (hdr->e_shoff > info->size) { 394 if (hdr->e_shoff > info->size) {
395 fatal("section header offset=%lu in file '%s' is bigger than " 395 fatal("section header offset=%lu in file '%s' is bigger than "
396 "filesize=%lu\n", (unsigned long)hdr->e_shoff, 396 "filesize=%lu\n", (unsigned long)hdr->e_shoff,
397 filename, info->size); 397 filename, info->size);
398 return 0; 398 return 0;
399 } 399 }
400 400
401 /* Fix endianness in section headers */ 401 /* Fix endianness in section headers */
402 for (i = 0; i < hdr->e_shnum; i++) { 402 for (i = 0; i < hdr->e_shnum; i++) {
403 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); 403 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
404 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); 404 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
405 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); 405 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
406 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); 406 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
407 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); 407 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
408 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); 408 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
409 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); 409 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
410 } 410 }
411 /* Find symbol table. */ 411 /* Find symbol table. */
412 for (i = 1; i < hdr->e_shnum; i++) { 412 for (i = 1; i < hdr->e_shnum; i++) {
413 const char *secstrings 413 const char *secstrings
414 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 414 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
415 const char *secname; 415 const char *secname;
416 416
417 if (sechdrs[i].sh_offset > info->size) { 417 if (sechdrs[i].sh_offset > info->size) {
418 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > " 418 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
419 "sizeof(*hrd)=%zu\n", filename, 419 "sizeof(*hrd)=%zu\n", filename,
420 (unsigned long)sechdrs[i].sh_offset, 420 (unsigned long)sechdrs[i].sh_offset,
421 sizeof(*hdr)); 421 sizeof(*hdr));
422 return 0; 422 return 0;
423 } 423 }
424 secname = secstrings + sechdrs[i].sh_name; 424 secname = secstrings + sechdrs[i].sh_name;
425 if (strcmp(secname, ".modinfo") == 0) { 425 if (strcmp(secname, ".modinfo") == 0) {
426 info->modinfo = (void *)hdr + sechdrs[i].sh_offset; 426 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
427 info->modinfo_len = sechdrs[i].sh_size; 427 info->modinfo_len = sechdrs[i].sh_size;
428 } else if (strcmp(secname, "__ksymtab") == 0) 428 } else if (strcmp(secname, "__ksymtab") == 0)
429 info->export_sec = i; 429 info->export_sec = i;
430 else if (strcmp(secname, "__ksymtab_unused") == 0) 430 else if (strcmp(secname, "__ksymtab_unused") == 0)
431 info->export_unused_sec = i; 431 info->export_unused_sec = i;
432 else if (strcmp(secname, "__ksymtab_gpl") == 0) 432 else if (strcmp(secname, "__ksymtab_gpl") == 0)
433 info->export_gpl_sec = i; 433 info->export_gpl_sec = i;
434 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0) 434 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
435 info->export_unused_gpl_sec = i; 435 info->export_unused_gpl_sec = i;
436 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 436 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
437 info->export_gpl_future_sec = i; 437 info->export_gpl_future_sec = i;
438 438
439 if (sechdrs[i].sh_type != SHT_SYMTAB) 439 if (sechdrs[i].sh_type != SHT_SYMTAB)
440 continue; 440 continue;
441 441
442 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; 442 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
443 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset 443 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
444 + sechdrs[i].sh_size; 444 + sechdrs[i].sh_size;
445 info->strtab = (void *)hdr + 445 info->strtab = (void *)hdr +
446 sechdrs[sechdrs[i].sh_link].sh_offset; 446 sechdrs[sechdrs[i].sh_link].sh_offset;
447 } 447 }
448 if (!info->symtab_start) 448 if (!info->symtab_start)
449 fatal("%s has no symtab?\n", filename); 449 fatal("%s has no symtab?\n", filename);
450 450
451 /* Fix endianness in symbols */ 451 /* Fix endianness in symbols */
452 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { 452 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
453 sym->st_shndx = TO_NATIVE(sym->st_shndx); 453 sym->st_shndx = TO_NATIVE(sym->st_shndx);
454 sym->st_name = TO_NATIVE(sym->st_name); 454 sym->st_name = TO_NATIVE(sym->st_name);
455 sym->st_value = TO_NATIVE(sym->st_value); 455 sym->st_value = TO_NATIVE(sym->st_value);
456 sym->st_size = TO_NATIVE(sym->st_size); 456 sym->st_size = TO_NATIVE(sym->st_size);
457 } 457 }
458 return 1; 458 return 1;
459 } 459 }
460 460
461 static void parse_elf_finish(struct elf_info *info) 461 static void parse_elf_finish(struct elf_info *info)
462 { 462 {
463 release_file(info->hdr, info->size); 463 release_file(info->hdr, info->size);
464 } 464 }
465 465
466 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" 466 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
467 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" 467 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
468 468
469 static void handle_modversions(struct module *mod, struct elf_info *info, 469 static void handle_modversions(struct module *mod, struct elf_info *info,
470 Elf_Sym *sym, const char *symname) 470 Elf_Sym *sym, const char *symname)
471 { 471 {
472 unsigned int crc; 472 unsigned int crc;
473 enum export export = export_from_sec(info, sym->st_shndx); 473 enum export export = export_from_sec(info, sym->st_shndx);
474 474
475 switch (sym->st_shndx) { 475 switch (sym->st_shndx) {
476 case SHN_COMMON: 476 case SHN_COMMON:
477 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); 477 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
478 break; 478 break;
479 case SHN_ABS: 479 case SHN_ABS:
480 /* CRC'd symbol */ 480 /* CRC'd symbol */
481 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 481 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
482 crc = (unsigned int) sym->st_value; 482 crc = (unsigned int) sym->st_value;
483 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 483 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
484 export); 484 export);
485 } 485 }
486 break; 486 break;
487 case SHN_UNDEF: 487 case SHN_UNDEF:
488 /* undefined symbol */ 488 /* undefined symbol */
489 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && 489 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
490 ELF_ST_BIND(sym->st_info) != STB_WEAK) 490 ELF_ST_BIND(sym->st_info) != STB_WEAK)
491 break; 491 break;
492 /* ignore global offset table */ 492 /* ignore global offset table */
493 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) 493 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
494 break; 494 break;
495 /* ignore __this_module, it will be resolved shortly */ 495 /* ignore __this_module, it will be resolved shortly */
496 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) 496 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
497 break; 497 break;
498 /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */ 498 /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
499 #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER) 499 #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
500 /* add compatibility with older glibc */ 500 /* add compatibility with older glibc */
501 #ifndef STT_SPARC_REGISTER 501 #ifndef STT_SPARC_REGISTER
502 #define STT_SPARC_REGISTER STT_REGISTER 502 #define STT_SPARC_REGISTER STT_REGISTER
503 #endif 503 #endif
504 if (info->hdr->e_machine == EM_SPARC || 504 if (info->hdr->e_machine == EM_SPARC ||
505 info->hdr->e_machine == EM_SPARCV9) { 505 info->hdr->e_machine == EM_SPARCV9) {
506 /* Ignore register directives. */ 506 /* Ignore register directives. */
507 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) 507 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
508 break; 508 break;
509 if (symname[0] == '.') { 509 if (symname[0] == '.') {
510 char *munged = strdup(symname); 510 char *munged = strdup(symname);
511 munged[0] = '_'; 511 munged[0] = '_';
512 munged[1] = toupper(munged[1]); 512 munged[1] = toupper(munged[1]);
513 symname = munged; 513 symname = munged;
514 } 514 }
515 } 515 }
516 #endif 516 #endif
517 517
518 if (memcmp(symname, MODULE_SYMBOL_PREFIX, 518 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
519 strlen(MODULE_SYMBOL_PREFIX)) == 0) { 519 strlen(MODULE_SYMBOL_PREFIX)) == 0) {
520 mod->unres = 520 mod->unres =
521 alloc_symbol(symname + 521 alloc_symbol(symname +
522 strlen(MODULE_SYMBOL_PREFIX), 522 strlen(MODULE_SYMBOL_PREFIX),
523 ELF_ST_BIND(sym->st_info) == STB_WEAK, 523 ELF_ST_BIND(sym->st_info) == STB_WEAK,
524 mod->unres); 524 mod->unres);
525 } 525 }
526 break; 526 break;
527 default: 527 default:
528 /* All exported symbols */ 528 /* All exported symbols */
529 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 529 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
530 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 530 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
531 export); 531 export);
532 } 532 }
533 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) 533 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
534 mod->has_init = 1; 534 mod->has_init = 1;
535 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0) 535 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
536 mod->has_cleanup = 1; 536 mod->has_cleanup = 1;
537 break; 537 break;
538 } 538 }
539 } 539 }
540 540
541 /** 541 /**
542 * Parse tag=value strings from .modinfo section 542 * Parse tag=value strings from .modinfo section
543 **/ 543 **/
544 static char *next_string(char *string, unsigned long *secsize) 544 static char *next_string(char *string, unsigned long *secsize)
545 { 545 {
546 /* Skip non-zero chars */ 546 /* Skip non-zero chars */
547 while (string[0]) { 547 while (string[0]) {
548 string++; 548 string++;
549 if ((*secsize)-- <= 1) 549 if ((*secsize)-- <= 1)
550 return NULL; 550 return NULL;
551 } 551 }
552 552
553 /* Skip any zero padding. */ 553 /* Skip any zero padding. */
554 while (!string[0]) { 554 while (!string[0]) {
555 string++; 555 string++;
556 if ((*secsize)-- <= 1) 556 if ((*secsize)-- <= 1)
557 return NULL; 557 return NULL;
558 } 558 }
559 return string; 559 return string;
560 } 560 }
561 561
562 static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, 562 static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
563 const char *tag, char *info) 563 const char *tag, char *info)
564 { 564 {
565 char *p; 565 char *p;
566 unsigned int taglen = strlen(tag); 566 unsigned int taglen = strlen(tag);
567 unsigned long size = modinfo_len; 567 unsigned long size = modinfo_len;
568 568
569 if (info) { 569 if (info) {
570 size -= info - (char *)modinfo; 570 size -= info - (char *)modinfo;
571 modinfo = next_string(info, &size); 571 modinfo = next_string(info, &size);
572 } 572 }
573 573
574 for (p = modinfo; p; p = next_string(p, &size)) { 574 for (p = modinfo; p; p = next_string(p, &size)) {
575 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') 575 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
576 return p + taglen + 1; 576 return p + taglen + 1;
577 } 577 }
578 return NULL; 578 return NULL;
579 } 579 }
580 580
581 static char *get_modinfo(void *modinfo, unsigned long modinfo_len, 581 static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
582 const char *tag) 582 const char *tag)
583 583
584 { 584 {
585 return get_next_modinfo(modinfo, modinfo_len, tag, NULL); 585 return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
586 } 586 }
587 587
588 /** 588 /**
589 * Test if string s ends in string sub 589 * Test if string s ends in string sub
590 * return 0 if match 590 * return 0 if match
591 **/ 591 **/
592 static int strrcmp(const char *s, const char *sub) 592 static int strrcmp(const char *s, const char *sub)
593 { 593 {
594 int slen, sublen; 594 int slen, sublen;
595 595
596 if (!s || !sub) 596 if (!s || !sub)
597 return 1; 597 return 1;
598 598
599 slen = strlen(s); 599 slen = strlen(s);
600 sublen = strlen(sub); 600 sublen = strlen(sub);
601 601
602 if ((slen == 0) || (sublen == 0)) 602 if ((slen == 0) || (sublen == 0))
603 return 1; 603 return 1;
604 604
605 if (sublen > slen) 605 if (sublen > slen)
606 return 1; 606 return 1;
607 607
608 return memcmp(s + slen - sublen, sub, sublen); 608 return memcmp(s + slen - sublen, sub, sublen);
609 } 609 }
610 610
611 static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) 611 static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
612 { 612 {
613 if (sym) 613 if (sym)
614 return elf->strtab + sym->st_name; 614 return elf->strtab + sym->st_name;
615 else 615 else
616 return ""; 616 return "";
617 } 617 }
618 618
619 static const char *sec_name(struct elf_info *elf, int shndx) 619 static const char *sec_name(struct elf_info *elf, int shndx)
620 { 620 {
621 Elf_Shdr *sechdrs = elf->sechdrs; 621 Elf_Shdr *sechdrs = elf->sechdrs;
622 return (void *)elf->hdr + 622 return (void *)elf->hdr +
623 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 623 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
624 sechdrs[shndx].sh_name; 624 sechdrs[shndx].sh_name;
625 } 625 }
626 626
627 static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) 627 static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
628 { 628 {
629 return (void *)elf->hdr + 629 return (void *)elf->hdr +
630 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + 630 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
631 sechdr->sh_name; 631 sechdr->sh_name;
632 } 632 }
633 633
634 /* if sym is empty or point to a string 634 /* if sym is empty or point to a string
635 * like ".[0-9]+" then return 1. 635 * like ".[0-9]+" then return 1.
636 * This is the optional prefix added by ld to some sections 636 * This is the optional prefix added by ld to some sections
637 */ 637 */
638 static int number_prefix(const char *sym) 638 static int number_prefix(const char *sym)
639 { 639 {
640 if (*sym++ == '\0') 640 if (*sym++ == '\0')
641 return 1; 641 return 1;
642 if (*sym != '.') 642 if (*sym != '.')
643 return 0; 643 return 0;
644 do { 644 do {
645 char c = *sym++; 645 char c = *sym++;
646 if (c < '0' || c > '9') 646 if (c < '0' || c > '9')
647 return 0; 647 return 0;
648 } while (*sym); 648 } while (*sym);
649 return 1; 649 return 1;
650 } 650 }
651 651
652 /* The pattern is an array of simple patterns. 652 /* The pattern is an array of simple patterns.
653 * "foo" will match an exact string equal to "foo" 653 * "foo" will match an exact string equal to "foo"
654 * "*foo" will match a string that ends with "foo" 654 * "*foo" will match a string that ends with "foo"
655 * "foo*" will match a string that begins with "foo" 655 * "foo*" will match a string that begins with "foo"
656 * "foo$" will match a string equal to "foo" or "foo.1" 656 * "foo$" will match a string equal to "foo" or "foo.1"
657 * where the '1' can be any number including several digits. 657 * where the '1' can be any number including several digits.
658 * The $ syntax is for sections where ld append a dot number 658 * The $ syntax is for sections where ld append a dot number
659 * to make section name unique. 659 * to make section name unique.
660 */ 660 */
661 int match(const char *sym, const char * const pat[]) 661 int match(const char *sym, const char * const pat[])
662 { 662 {
663 const char *p; 663 const char *p;
664 while (*pat) { 664 while (*pat) {
665 p = *pat++; 665 p = *pat++;
666 const char *endp = p + strlen(p) - 1; 666 const char *endp = p + strlen(p) - 1;
667 667
668 /* "*foo" */ 668 /* "*foo" */
669 if (*p == '*') { 669 if (*p == '*') {
670 if (strrcmp(sym, p + 1) == 0) 670 if (strrcmp(sym, p + 1) == 0)
671 return 1; 671 return 1;
672 } 672 }
673 /* "foo*" */ 673 /* "foo*" */
674 else if (*endp == '*') { 674 else if (*endp == '*') {
675 if (strncmp(sym, p, strlen(p) - 1) == 0) 675 if (strncmp(sym, p, strlen(p) - 1) == 0)
676 return 1; 676 return 1;
677 } 677 }
678 /* "foo$" */ 678 /* "foo$" */
679 else if (*endp == '$') { 679 else if (*endp == '$') {
680 if (strncmp(sym, p, strlen(p) - 1) == 0) { 680 if (strncmp(sym, p, strlen(p) - 1) == 0) {
681 if (number_prefix(sym + strlen(p) - 1)) 681 if (number_prefix(sym + strlen(p) - 1))
682 return 1; 682 return 1;
683 } 683 }
684 } 684 }
685 /* no wildcards */ 685 /* no wildcards */
686 else { 686 else {
687 if (strcmp(p, sym) == 0) 687 if (strcmp(p, sym) == 0)
688 return 1; 688 return 1;
689 } 689 }
690 } 690 }
691 /* no match */ 691 /* no match */
692 return 0; 692 return 0;
693 } 693 }
694 694
695 /* sections that we do not want to do full section mismatch check on */ 695 /* sections that we do not want to do full section mismatch check on */
696 static const char *section_white_list[] = 696 static const char *section_white_list[] =
697 { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; 697 { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
698 698
699 /* 699 /*
700 * Is this section one we do not want to check? 700 * Is this section one we do not want to check?
701 * This is often debug sections. 701 * This is often debug sections.
702 * If we are going to check this section then 702 * If we are going to check this section then
703 * test if section name ends with a dot and a number. 703 * test if section name ends with a dot and a number.
704 * This is used to find sections where the linker have 704 * This is used to find sections where the linker have
705 * appended a dot-number to make the name unique. 705 * appended a dot-number to make the name unique.
706 * The cause of this is often a section specified in assembler 706 * The cause of this is often a section specified in assembler
707 * without "ax" / "aw" and the same section used in .c 707 * without "ax" / "aw" and the same section used in .c
708 * code where gcc add these. 708 * code where gcc add these.
709 */ 709 */
710 static int check_section(const char *modname, const char *sec) 710 static int check_section(const char *modname, const char *sec)
711 { 711 {
712 const char *e = sec + strlen(sec) - 1; 712 const char *e = sec + strlen(sec) - 1;
713 if (match(sec, section_white_list)) 713 if (match(sec, section_white_list))
714 return 1; 714 return 1;
715 715
716 if (*e && isdigit(*e)) { 716 if (*e && isdigit(*e)) {
717 /* consume all digits */ 717 /* consume all digits */
718 while (*e && e != sec && isdigit(*e)) 718 while (*e && e != sec && isdigit(*e))
719 e--; 719 e--;
720 if (*e == '.') { 720 if (*e == '.') {
721 warn("%s (%s): unexpected section name.\n" 721 warn("%s (%s): unexpected section name.\n"
722 "The (.[number]+) following section name are " 722 "The (.[number]+) following section name are "
723 "ld generated and not expected.\n" 723 "ld generated and not expected.\n"
724 "Did you forget to use \"ax\"/\"aw\" " 724 "Did you forget to use \"ax\"/\"aw\" "
725 "in a .S file?\n" 725 "in a .S file?\n"
726 "Note that for example <linux/init.h> contains\n" 726 "Note that for example <linux/init.h> contains\n"
727 "section definitions for use in .S files.\n\n", 727 "section definitions for use in .S files.\n\n",
728 modname, sec); 728 modname, sec);
729 } 729 }
730 } 730 }
731 return 0; 731 return 0;
732 } 732 }
733 733
734 734
735 735
736 #define ALL_INIT_DATA_SECTIONS \ 736 #define ALL_INIT_DATA_SECTIONS \
737 ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" 737 ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
738 #define ALL_EXIT_DATA_SECTIONS \ 738 #define ALL_EXIT_DATA_SECTIONS \
739 ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$" 739 ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
740 740
741 #define ALL_INIT_TEXT_SECTIONS \ 741 #define ALL_INIT_TEXT_SECTIONS \
742 ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$" 742 ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$"
743 #define ALL_EXIT_TEXT_SECTIONS \ 743 #define ALL_EXIT_TEXT_SECTIONS \
744 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" 744 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
745 745
746 #define ALL_INIT_SECTIONS ALL_INIT_DATA_SECTIONS, ALL_INIT_TEXT_SECTIONS 746 #define ALL_INIT_SECTIONS ALL_INIT_DATA_SECTIONS, ALL_INIT_TEXT_SECTIONS
747 #define ALL_EXIT_SECTIONS ALL_EXIT_DATA_SECTIONS, ALL_EXIT_TEXT_SECTIONS 747 #define ALL_EXIT_SECTIONS ALL_EXIT_DATA_SECTIONS, ALL_EXIT_TEXT_SECTIONS
748 748
749 #define DATA_SECTIONS ".data$", ".data.rel$" 749 #define DATA_SECTIONS ".data$", ".data.rel$"
750 #define TEXT_SECTIONS ".text$" 750 #define TEXT_SECTIONS ".text$"
751 751
752 #define INIT_SECTIONS ".init.data$", ".init.text$" 752 #define INIT_SECTIONS ".init.data$", ".init.text$"
753 #define DEV_INIT_SECTIONS ".devinit.data$", ".devinit.text$" 753 #define DEV_INIT_SECTIONS ".devinit.data$", ".devinit.text$"
754 #define CPU_INIT_SECTIONS ".cpuinit.data$", ".cpuinit.text$" 754 #define CPU_INIT_SECTIONS ".cpuinit.data$", ".cpuinit.text$"
755 #define MEM_INIT_SECTIONS ".meminit.data$", ".meminit.text$" 755 #define MEM_INIT_SECTIONS ".meminit.data$", ".meminit.text$"
756 756
757 #define EXIT_SECTIONS ".exit.data$", ".exit.text$" 757 #define EXIT_SECTIONS ".exit.data$", ".exit.text$"
758 #define DEV_EXIT_SECTIONS ".devexit.data$", ".devexit.text$" 758 #define DEV_EXIT_SECTIONS ".devexit.data$", ".devexit.text$"
759 #define CPU_EXIT_SECTIONS ".cpuexit.data$", ".cpuexit.text$" 759 #define CPU_EXIT_SECTIONS ".cpuexit.data$", ".cpuexit.text$"
760 #define MEM_EXIT_SECTIONS ".memexit.data$", ".memexit.text$" 760 #define MEM_EXIT_SECTIONS ".memexit.data$", ".memexit.text$"
761 761
762 /* init data sections */ 762 /* init data sections */
763 static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL }; 763 static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
764 764
765 /* all init sections */ 765 /* all init sections */
766 static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL }; 766 static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
767 767
768 /* All init and exit sections (code + data) */ 768 /* All init and exit sections (code + data) */
769 static const char *init_exit_sections[] = 769 static const char *init_exit_sections[] =
770 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; 770 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
771 771
772 /* data section */ 772 /* data section */
773 static const char *data_sections[] = { DATA_SECTIONS, NULL }; 773 static const char *data_sections[] = { DATA_SECTIONS, NULL };
774 774
775 /* sections that may refer to an init/exit section with no warning */ 775 /* sections that may refer to an init/exit section with no warning */
776 static const char *initref_sections[] = 776 static const char *initref_sections[] =
777 { 777 {
778 ".text.init.refok*", 778 ".text.init.refok*",
779 ".exit.text.refok*", 779 ".exit.text.refok*",
780 ".data.init.refok*", 780 ".data.init.refok*",
781 NULL 781 NULL
782 }; 782 };
783 783
784 784
785 /* symbols in .data that may refer to init/exit sections */ 785 /* symbols in .data that may refer to init/exit sections */
786 static const char *symbol_white_list[] = 786 static const char *symbol_white_list[] =
787 { 787 {
788 "*driver", 788 "*driver",
789 "*_template", /* scsi uses *_template a lot */ 789 "*_template", /* scsi uses *_template a lot */
790 "*_timer", /* arm uses ops structures named _timer a lot */ 790 "*_timer", /* arm uses ops structures named _timer a lot */
791 "*_sht", /* scsi also used *_sht to some extent */ 791 "*_sht", /* scsi also used *_sht to some extent */
792 "*_ops", 792 "*_ops",
793 "*_probe", 793 "*_probe",
794 "*_probe_one", 794 "*_probe_one",
795 "*_console", 795 "*_console",
796 NULL 796 NULL
797 }; 797 };
798 798
799 static const char *head_sections[] = { ".head.text*", NULL }; 799 static const char *head_sections[] = { ".head.text*", NULL };
800 static const char *linker_symbols[] = 800 static const char *linker_symbols[] =
801 { "__init_begin", "_sinittext", "_einittext", NULL }; 801 { "__init_begin", "_sinittext", "_einittext", NULL };
802 802
803 enum mismatch { 803 enum mismatch {
804 NO_MISMATCH, 804 NO_MISMATCH,
805 TEXT_TO_INIT, 805 TEXT_TO_INIT,
806 DATA_TO_INIT, 806 DATA_TO_INIT,
807 TEXT_TO_EXIT, 807 TEXT_TO_EXIT,
808 DATA_TO_EXIT, 808 DATA_TO_EXIT,
809 XXXINIT_TO_INIT, 809 XXXINIT_TO_INIT,
810 XXXEXIT_TO_EXIT, 810 XXXEXIT_TO_EXIT,
811 INIT_TO_EXIT, 811 INIT_TO_EXIT,
812 EXIT_TO_INIT, 812 EXIT_TO_INIT,
813 EXPORT_TO_INIT_EXIT, 813 EXPORT_TO_INIT_EXIT,
814 }; 814 };
815 815
816 struct sectioncheck { 816 struct sectioncheck {
817 const char *fromsec[20]; 817 const char *fromsec[20];
818 const char *tosec[20]; 818 const char *tosec[20];
819 enum mismatch mismatch; 819 enum mismatch mismatch;
820 }; 820 };
821 821
822 const struct sectioncheck sectioncheck[] = { 822 const struct sectioncheck sectioncheck[] = {
823 /* Do not reference init/exit code/data from 823 /* Do not reference init/exit code/data from
824 * normal code and data 824 * normal code and data
825 */ 825 */
826 { 826 {
827 .fromsec = { TEXT_SECTIONS, NULL }, 827 .fromsec = { TEXT_SECTIONS, NULL },
828 .tosec = { ALL_INIT_SECTIONS, NULL }, 828 .tosec = { ALL_INIT_SECTIONS, NULL },
829 .mismatch = TEXT_TO_INIT, 829 .mismatch = TEXT_TO_INIT,
830 }, 830 },
831 { 831 {
832 .fromsec = { DATA_SECTIONS, NULL }, 832 .fromsec = { DATA_SECTIONS, NULL },
833 .tosec = { ALL_INIT_SECTIONS, NULL }, 833 .tosec = { ALL_INIT_SECTIONS, NULL },
834 .mismatch = DATA_TO_INIT, 834 .mismatch = DATA_TO_INIT,
835 }, 835 },
836 { 836 {
837 .fromsec = { TEXT_SECTIONS, NULL }, 837 .fromsec = { TEXT_SECTIONS, NULL },
838 .tosec = { ALL_EXIT_SECTIONS, NULL }, 838 .tosec = { ALL_EXIT_SECTIONS, NULL },
839 .mismatch = TEXT_TO_EXIT, 839 .mismatch = TEXT_TO_EXIT,
840 }, 840 },
841 { 841 {
842 .fromsec = { DATA_SECTIONS, NULL }, 842 .fromsec = { DATA_SECTIONS, NULL },
843 .tosec = { ALL_EXIT_SECTIONS, NULL }, 843 .tosec = { ALL_EXIT_SECTIONS, NULL },
844 .mismatch = DATA_TO_EXIT, 844 .mismatch = DATA_TO_EXIT,
845 }, 845 },
846 /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ 846 /* Do not reference init code/data from devinit/cpuinit/meminit code/data */
847 { 847 {
848 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, 848 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL },
849 .tosec = { INIT_SECTIONS, NULL }, 849 .tosec = { INIT_SECTIONS, NULL },
850 .mismatch = XXXINIT_TO_INIT, 850 .mismatch = XXXINIT_TO_INIT,
851 }, 851 },
852 /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ 852 /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
853 { 853 {
854 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, 854 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL },
855 .tosec = { EXIT_SECTIONS, NULL }, 855 .tosec = { EXIT_SECTIONS, NULL },
856 .mismatch = XXXEXIT_TO_EXIT, 856 .mismatch = XXXEXIT_TO_EXIT,
857 }, 857 },
858 /* Do not use exit code/data from init code */ 858 /* Do not use exit code/data from init code */
859 { 859 {
860 .fromsec = { ALL_INIT_SECTIONS, NULL }, 860 .fromsec = { ALL_INIT_SECTIONS, NULL },
861 .tosec = { ALL_EXIT_SECTIONS, NULL }, 861 .tosec = { ALL_EXIT_SECTIONS, NULL },
862 .mismatch = INIT_TO_EXIT, 862 .mismatch = INIT_TO_EXIT,
863 }, 863 },
864 /* Do not use init code/data from exit code */ 864 /* Do not use init code/data from exit code */
865 { 865 {
866 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 866 .fromsec = { ALL_EXIT_SECTIONS, NULL },
867 .tosec = { ALL_INIT_SECTIONS, NULL }, 867 .tosec = { ALL_INIT_SECTIONS, NULL },
868 .mismatch = EXIT_TO_INIT, 868 .mismatch = EXIT_TO_INIT,
869 }, 869 },
870 /* Do not export init/exit functions or data */ 870 /* Do not export init/exit functions or data */
871 { 871 {
872 .fromsec = { "__ksymtab*", NULL }, 872 .fromsec = { "__ksymtab*", NULL },
873 .tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }, 873 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
874 .mismatch = EXPORT_TO_INIT_EXIT 874 .mismatch = EXPORT_TO_INIT_EXIT
875 } 875 }
876 }; 876 };
877 877
878 static int section_mismatch(const char *fromsec, const char *tosec) 878 static int section_mismatch(const char *fromsec, const char *tosec)
879 { 879 {
880 int i; 880 int i;
881 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 881 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
882 const struct sectioncheck *check = &sectioncheck[0]; 882 const struct sectioncheck *check = &sectioncheck[0];
883 883
884 for (i = 0; i < elems; i++) { 884 for (i = 0; i < elems; i++) {
885 if (match(fromsec, check->fromsec) && 885 if (match(fromsec, check->fromsec) &&
886 match(tosec, check->tosec)) 886 match(tosec, check->tosec))
887 return check->mismatch; 887 return check->mismatch;
888 check++; 888 check++;
889 } 889 }
890 return NO_MISMATCH; 890 return NO_MISMATCH;
891 } 891 }
892 892
893 /** 893 /**
894 * Whitelist to allow certain references to pass with no warning. 894 * Whitelist to allow certain references to pass with no warning.
895 * 895 *
896 * Pattern 0: 896 * Pattern 0:
897 * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. 897 * Do not warn if funtion/data are marked with __init_refok/__initdata_refok.
898 * The pattern is identified by: 898 * The pattern is identified by:
899 * fromsec = .text.init.refok* | .data.init.refok* 899 * fromsec = .text.init.refok* | .data.init.refok*
900 * 900 *
901 * Pattern 1: 901 * Pattern 1:
902 * If a module parameter is declared __initdata and permissions=0 902 * If a module parameter is declared __initdata and permissions=0
903 * then this is legal despite the warning generated. 903 * then this is legal despite the warning generated.
904 * We cannot see value of permissions here, so just ignore 904 * We cannot see value of permissions here, so just ignore
905 * this pattern. 905 * this pattern.
906 * The pattern is identified by: 906 * The pattern is identified by:
907 * tosec = .init.data 907 * tosec = .init.data
908 * fromsec = .data* 908 * fromsec = .data*
909 * atsym =__param* 909 * atsym =__param*
910 * 910 *
911 * Pattern 2: 911 * Pattern 2:
912 * Many drivers utilise a *driver container with references to 912 * Many drivers utilise a *driver container with references to
913 * add, remove, probe functions etc. 913 * add, remove, probe functions etc.
914 * These functions may often be marked __init and we do not want to 914 * These functions may often be marked __init and we do not want to
915 * warn here. 915 * warn here.
916 * the pattern is identified by: 916 * the pattern is identified by:
917 * tosec = init or exit section 917 * tosec = init or exit section
918 * fromsec = data section 918 * fromsec = data section
919 * atsym = *driver, *_template, *_sht, *_ops, *_probe, 919 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
920 * *probe_one, *_console, *_timer 920 * *probe_one, *_console, *_timer
921 * 921 *
922 * Pattern 3: 922 * Pattern 3:
923 * Whitelist all refereces from .text.head to .init.data 923 * Whitelist all refereces from .text.head to .init.data
924 * Whitelist all refereces from .text.head to .init.text 924 * Whitelist all refereces from .text.head to .init.text
925 * 925 *
926 * Pattern 4: 926 * Pattern 4:
927 * Some symbols belong to init section but still it is ok to reference 927 * Some symbols belong to init section but still it is ok to reference
928 * these from non-init sections as these symbols don't have any memory 928 * these from non-init sections as these symbols don't have any memory
929 * allocated for them and symbol address and value are same. So even 929 * allocated for them and symbol address and value are same. So even
930 * if init section is freed, its ok to reference those symbols. 930 * if init section is freed, its ok to reference those symbols.
931 * For ex. symbols marking the init section boundaries. 931 * For ex. symbols marking the init section boundaries.
932 * This pattern is identified by 932 * This pattern is identified by
933 * refsymname = __init_begin, _sinittext, _einittext 933 * refsymname = __init_begin, _sinittext, _einittext
934 * 934 *
935 **/ 935 **/
936 static int secref_whitelist(const char *fromsec, const char *fromsym, 936 static int secref_whitelist(const char *fromsec, const char *fromsym,
937 const char *tosec, const char *tosym) 937 const char *tosec, const char *tosym)
938 { 938 {
939 /* Check for pattern 0 */ 939 /* Check for pattern 0 */
940 if (match(fromsec, initref_sections)) 940 if (match(fromsec, initref_sections))
941 return 0; 941 return 0;
942 942
943 /* Check for pattern 1 */ 943 /* Check for pattern 1 */
944 if (match(tosec, init_data_sections) && 944 if (match(tosec, init_data_sections) &&
945 match(fromsec, data_sections) && 945 match(fromsec, data_sections) &&
946 (strncmp(fromsym, "__param", strlen("__param")) == 0)) 946 (strncmp(fromsym, "__param", strlen("__param")) == 0))
947 return 0; 947 return 0;
948 948
949 /* Check for pattern 2 */ 949 /* Check for pattern 2 */
950 if (match(tosec, init_exit_sections) && 950 if (match(tosec, init_exit_sections) &&
951 match(fromsec, data_sections) && 951 match(fromsec, data_sections) &&
952 match(fromsym, symbol_white_list)) 952 match(fromsym, symbol_white_list))
953 return 0; 953 return 0;
954 954
955 /* Check for pattern 3 */ 955 /* Check for pattern 3 */
956 if (match(fromsec, head_sections) && 956 if (match(fromsec, head_sections) &&
957 match(tosec, init_sections)) 957 match(tosec, init_sections))
958 return 0; 958 return 0;
959 959
960 /* Check for pattern 4 */ 960 /* Check for pattern 4 */
961 if (match(tosym, linker_symbols)) 961 if (match(tosym, linker_symbols))
962 return 0; 962 return 0;
963 963
964 return 1; 964 return 1;
965 } 965 }
966 966
967 /** 967 /**
968 * Find symbol based on relocation record info. 968 * Find symbol based on relocation record info.
969 * In some cases the symbol supplied is a valid symbol so 969 * In some cases the symbol supplied is a valid symbol so
970 * return refsym. If st_name != 0 we assume this is a valid symbol. 970 * return refsym. If st_name != 0 we assume this is a valid symbol.
971 * In other cases the symbol needs to be looked up in the symbol table 971 * In other cases the symbol needs to be looked up in the symbol table
972 * based on section and address. 972 * based on section and address.
973 * **/ 973 * **/
974 static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, 974 static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
975 Elf_Sym *relsym) 975 Elf_Sym *relsym)
976 { 976 {
977 Elf_Sym *sym; 977 Elf_Sym *sym;
978 Elf_Sym *near = NULL; 978 Elf_Sym *near = NULL;
979 Elf64_Sword distance = 20; 979 Elf64_Sword distance = 20;
980 Elf64_Sword d; 980 Elf64_Sword d;
981 981
982 if (relsym->st_name != 0) 982 if (relsym->st_name != 0)
983 return relsym; 983 return relsym;
984 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 984 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
985 if (sym->st_shndx != relsym->st_shndx) 985 if (sym->st_shndx != relsym->st_shndx)
986 continue; 986 continue;
987 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) 987 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
988 continue; 988 continue;
989 if (sym->st_value == addr) 989 if (sym->st_value == addr)
990 return sym; 990 return sym;
991 /* Find a symbol nearby - addr are maybe negative */ 991 /* Find a symbol nearby - addr are maybe negative */
992 d = sym->st_value - addr; 992 d = sym->st_value - addr;
993 if (d < 0) 993 if (d < 0)
994 d = addr - sym->st_value; 994 d = addr - sym->st_value;
995 if (d < distance) { 995 if (d < distance) {
996 distance = d; 996 distance = d;
997 near = sym; 997 near = sym;
998 } 998 }
999 } 999 }
1000 /* We need a close match */ 1000 /* We need a close match */
1001 if (distance < 20) 1001 if (distance < 20)
1002 return near; 1002 return near;
1003 else 1003 else
1004 return NULL; 1004 return NULL;
1005 } 1005 }
1006 1006
1007 static inline int is_arm_mapping_symbol(const char *str) 1007 static inline int is_arm_mapping_symbol(const char *str)
1008 { 1008 {
1009 return str[0] == '$' && strchr("atd", str[1]) 1009 return str[0] == '$' && strchr("atd", str[1])
1010 && (str[2] == '\0' || str[2] == '.'); 1010 && (str[2] == '\0' || str[2] == '.');
1011 } 1011 }
1012 1012
1013 /* 1013 /*
1014 * If there's no name there, ignore it; likewise, ignore it if it's 1014 * If there's no name there, ignore it; likewise, ignore it if it's
1015 * one of the magic symbols emitted used by current ARM tools. 1015 * one of the magic symbols emitted used by current ARM tools.
1016 * 1016 *
1017 * Otherwise if find_symbols_between() returns those symbols, they'll 1017 * Otherwise if find_symbols_between() returns those symbols, they'll
1018 * fail the whitelist tests and cause lots of false alarms ... fixable 1018 * fail the whitelist tests and cause lots of false alarms ... fixable
1019 * only by merging __exit and __init sections into __text, bloating 1019 * only by merging __exit and __init sections into __text, bloating
1020 * the kernel (which is especially evil on embedded platforms). 1020 * the kernel (which is especially evil on embedded platforms).
1021 */ 1021 */
1022 static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) 1022 static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
1023 { 1023 {
1024 const char *name = elf->strtab + sym->st_name; 1024 const char *name = elf->strtab + sym->st_name;
1025 1025
1026 if (!name || !strlen(name)) 1026 if (!name || !strlen(name))
1027 return 0; 1027 return 0;
1028 return !is_arm_mapping_symbol(name); 1028 return !is_arm_mapping_symbol(name);
1029 } 1029 }
1030 1030
1031 /* 1031 /*
1032 * Find symbols before or equal addr and after addr - in the section sec. 1032 * Find symbols before or equal addr and after addr - in the section sec.
1033 * If we find two symbols with equal offset prefer one with a valid name. 1033 * If we find two symbols with equal offset prefer one with a valid name.
1034 * The ELF format may have a better way to detect what type of symbol 1034 * The ELF format may have a better way to detect what type of symbol
1035 * it is, but this works for now. 1035 * it is, but this works for now.
1036 **/ 1036 **/
1037 static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, 1037 static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1038 const char *sec) 1038 const char *sec)
1039 { 1039 {
1040 Elf_Sym *sym; 1040 Elf_Sym *sym;
1041 Elf_Sym *near = NULL; 1041 Elf_Sym *near = NULL;
1042 Elf_Addr distance = ~0; 1042 Elf_Addr distance = ~0;
1043 1043
1044 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1044 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1045 const char *symsec; 1045 const char *symsec;
1046 1046
1047 if (sym->st_shndx >= SHN_LORESERVE) 1047 if (sym->st_shndx >= SHN_LORESERVE)
1048 continue; 1048 continue;
1049 symsec = sec_name(elf, sym->st_shndx); 1049 symsec = sec_name(elf, sym->st_shndx);
1050 if (strcmp(symsec, sec) != 0) 1050 if (strcmp(symsec, sec) != 0)
1051 continue; 1051 continue;
1052 if (!is_valid_name(elf, sym)) 1052 if (!is_valid_name(elf, sym))
1053 continue; 1053 continue;
1054 if (sym->st_value <= addr) { 1054 if (sym->st_value <= addr) {
1055 if ((addr - sym->st_value) < distance) { 1055 if ((addr - sym->st_value) < distance) {
1056 distance = addr - sym->st_value; 1056 distance = addr - sym->st_value;
1057 near = sym; 1057 near = sym;
1058 } else if ((addr - sym->st_value) == distance) { 1058 } else if ((addr - sym->st_value) == distance) {
1059 near = sym; 1059 near = sym;
1060 } 1060 }
1061 } 1061 }
1062 } 1062 }
1063 return near; 1063 return near;
1064 } 1064 }
1065 1065
1066 /* 1066 /*
1067 * Convert a section name to the function/data attribute 1067 * Convert a section name to the function/data attribute
1068 * .init.text => __init 1068 * .init.text => __init
1069 * .cpuinit.data => __cpudata 1069 * .cpuinit.data => __cpudata
1070 * .memexitconst => __memconst 1070 * .memexitconst => __memconst
1071 * etc. 1071 * etc.
1072 */ 1072 */
1073 static char *sec2annotation(const char *s) 1073 static char *sec2annotation(const char *s)
1074 { 1074 {
1075 if (match(s, init_exit_sections)) { 1075 if (match(s, init_exit_sections)) {
1076 char *p = malloc(20); 1076 char *p = malloc(20);
1077 char *r = p; 1077 char *r = p;
1078 1078
1079 *p++ = '_'; 1079 *p++ = '_';
1080 *p++ = '_'; 1080 *p++ = '_';
1081 if (*s == '.') 1081 if (*s == '.')
1082 s++; 1082 s++;
1083 while (*s && *s != '.') 1083 while (*s && *s != '.')
1084 *p++ = *s++; 1084 *p++ = *s++;
1085 *p = '\0'; 1085 *p = '\0';
1086 if (*s == '.') 1086 if (*s == '.')
1087 s++; 1087 s++;
1088 if (strstr(s, "rodata") != NULL) 1088 if (strstr(s, "rodata") != NULL)
1089 strcat(p, "const "); 1089 strcat(p, "const ");
1090 else if (strstr(s, "data") != NULL) 1090 else if (strstr(s, "data") != NULL)
1091 strcat(p, "data "); 1091 strcat(p, "data ");
1092 else 1092 else
1093 strcat(p, " "); 1093 strcat(p, " ");
1094 return r; /* we leak her but we do not care */ 1094 return r; /* we leak her but we do not care */
1095 } else { 1095 } else {
1096 return ""; 1096 return "";
1097 } 1097 }
1098 } 1098 }
1099 1099
1100 static int is_function(Elf_Sym *sym) 1100 static int is_function(Elf_Sym *sym)
1101 { 1101 {
1102 if (sym) 1102 if (sym)
1103 return ELF_ST_TYPE(sym->st_info) == STT_FUNC; 1103 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1104 else 1104 else
1105 return 0; 1105 return 0;
1106 } 1106 }
1107 1107
1108 /* 1108 /*
1109 * Print a warning about a section mismatch. 1109 * Print a warning about a section mismatch.
1110 * Try to find symbols near it so user can find it. 1110 * Try to find symbols near it so user can find it.
1111 * Check whitelist before warning - it may be a false positive. 1111 * Check whitelist before warning - it may be a false positive.
1112 */ 1112 */
1113 static void report_sec_mismatch(const char *modname, enum mismatch mismatch, 1113 static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
1114 const char *fromsec, 1114 const char *fromsec,
1115 unsigned long long fromaddr, 1115 unsigned long long fromaddr,
1116 const char *fromsym, 1116 const char *fromsym,
1117 int from_is_func, 1117 int from_is_func,
1118 const char *tosec, const char *tosym, 1118 const char *tosec, const char *tosym,
1119 int to_is_func) 1119 int to_is_func)
1120 { 1120 {
1121 const char *from, *from_p; 1121 const char *from, *from_p;
1122 const char *to, *to_p; 1122 const char *to, *to_p;
1123 from = from_is_func ? "function" : "variable"; 1123 from = from_is_func ? "function" : "variable";
1124 from_p = from_is_func ? "()" : ""; 1124 from_p = from_is_func ? "()" : "";
1125 to = to_is_func ? "function" : "variable"; 1125 to = to_is_func ? "function" : "variable";
1126 to_p = to_is_func ? "()" : ""; 1126 to_p = to_is_func ? "()" : "";
1127 1127
1128 sec_mismatch_count++; 1128 sec_mismatch_count++;
1129 if (!sec_mismatch_verbose) 1129 if (!sec_mismatch_verbose)
1130 return; 1130 return;
1131 1131
1132 fprintf(stderr, "WARNING: %s(%s+0x%llx): Section mismatch in" 1132 fprintf(stderr, "WARNING: %s(%s+0x%llx): Section mismatch in"
1133 " reference from the %s %s%s to the %s %s:%s%s\n", 1133 " reference from the %s %s%s to the %s %s:%s%s\n",
1134 modname, fromsec, fromaddr, from, fromsym, from_p, 1134 modname, fromsec, fromaddr, from, fromsym, from_p,
1135 to, tosec, tosym, to_p); 1135 to, tosec, tosym, to_p);
1136 1136
1137 switch (mismatch) { 1137 switch (mismatch) {
1138 case TEXT_TO_INIT: 1138 case TEXT_TO_INIT:
1139 fprintf(stderr, 1139 fprintf(stderr,
1140 "The function %s %s() references\n" 1140 "The function %s %s() references\n"
1141 "the %s %s%s%s.\n" 1141 "the %s %s%s%s.\n"
1142 "This is often because %s lacks a %s\n" 1142 "This is often because %s lacks a %s\n"
1143 "annotation or the annotation of %s is wrong.\n", 1143 "annotation or the annotation of %s is wrong.\n",
1144 sec2annotation(fromsec), fromsym, 1144 sec2annotation(fromsec), fromsym,
1145 to, sec2annotation(tosec), tosym, to_p, 1145 to, sec2annotation(tosec), tosym, to_p,
1146 fromsym, sec2annotation(tosec), tosym); 1146 fromsym, sec2annotation(tosec), tosym);
1147 break; 1147 break;
1148 case DATA_TO_INIT: { 1148 case DATA_TO_INIT: {
1149 const char **s = symbol_white_list; 1149 const char **s = symbol_white_list;
1150 fprintf(stderr, 1150 fprintf(stderr,
1151 "The variable %s references\n" 1151 "The variable %s references\n"
1152 "the %s %s%s%s\n" 1152 "the %s %s%s%s\n"
1153 "If the reference is valid then annotate the\n" 1153 "If the reference is valid then annotate the\n"
1154 "variable with __init* (see linux/init.h) " 1154 "variable with __init* (see linux/init.h) "
1155 "or name the variable:\n", 1155 "or name the variable:\n",
1156 fromsym, to, sec2annotation(tosec), tosym, to_p); 1156 fromsym, to, sec2annotation(tosec), tosym, to_p);
1157 while (*s) 1157 while (*s)
1158 fprintf(stderr, "%s, ", *s++); 1158 fprintf(stderr, "%s, ", *s++);
1159 fprintf(stderr, "\n"); 1159 fprintf(stderr, "\n");
1160 break; 1160 break;
1161 } 1161 }
1162 case TEXT_TO_EXIT: 1162 case TEXT_TO_EXIT:
1163 fprintf(stderr, 1163 fprintf(stderr,
1164 "The function %s() references a %s in an exit section.\n" 1164 "The function %s() references a %s in an exit section.\n"
1165 "Often the %s %s%s has valid usage outside the exit section\n" 1165 "Often the %s %s%s has valid usage outside the exit section\n"
1166 "and the fix is to remove the %sannotation of %s.\n", 1166 "and the fix is to remove the %sannotation of %s.\n",
1167 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1167 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
1168 break; 1168 break;
1169 case DATA_TO_EXIT: { 1169 case DATA_TO_EXIT: {
1170 const char **s = symbol_white_list; 1170 const char **s = symbol_white_list;
1171 fprintf(stderr, 1171 fprintf(stderr,
1172 "The variable %s references\n" 1172 "The variable %s references\n"
1173 "the %s %s%s%s\n" 1173 "the %s %s%s%s\n"
1174 "If the reference is valid then annotate the\n" 1174 "If the reference is valid then annotate the\n"
1175 "variable with __exit* (see linux/init.h) or " 1175 "variable with __exit* (see linux/init.h) or "
1176 "name the variable:\n", 1176 "name the variable:\n",
1177 fromsym, to, sec2annotation(tosec), tosym, to_p); 1177 fromsym, to, sec2annotation(tosec), tosym, to_p);
1178 while (*s) 1178 while (*s)
1179 fprintf(stderr, "%s, ", *s++); 1179 fprintf(stderr, "%s, ", *s++);
1180 fprintf(stderr, "\n"); 1180 fprintf(stderr, "\n");
1181 break; 1181 break;
1182 } 1182 }
1183 case XXXINIT_TO_INIT: 1183 case XXXINIT_TO_INIT:
1184 case XXXEXIT_TO_EXIT: 1184 case XXXEXIT_TO_EXIT:
1185 fprintf(stderr, 1185 fprintf(stderr,
1186 "The %s %s%s%s references\n" 1186 "The %s %s%s%s references\n"
1187 "a %s %s%s%s.\n" 1187 "a %s %s%s%s.\n"
1188 "If %s is only used by %s then\n" 1188 "If %s is only used by %s then\n"
1189 "annotate %s with a matching annotation.\n", 1189 "annotate %s with a matching annotation.\n",
1190 from, sec2annotation(fromsec), fromsym, from_p, 1190 from, sec2annotation(fromsec), fromsym, from_p,
1191 to, sec2annotation(tosec), tosym, to_p, 1191 to, sec2annotation(tosec), tosym, to_p,
1192 fromsym, tosym, fromsym); 1192 fromsym, tosym, fromsym);
1193 break; 1193 break;
1194 case INIT_TO_EXIT: 1194 case INIT_TO_EXIT:
1195 fprintf(stderr, 1195 fprintf(stderr,
1196 "The %s %s%s%s references\n" 1196 "The %s %s%s%s references\n"
1197 "a %s %s%s%s.\n" 1197 "a %s %s%s%s.\n"
1198 "This is often seen when error handling " 1198 "This is often seen when error handling "
1199 "in the init function\n" 1199 "in the init function\n"
1200 "uses functionality in the exit path.\n" 1200 "uses functionality in the exit path.\n"
1201 "The fix is often to remove the %sannotation of\n" 1201 "The fix is often to remove the %sannotation of\n"
1202 "%s%s so it may be used outside an exit section.\n", 1202 "%s%s so it may be used outside an exit section.\n",
1203 from, sec2annotation(fromsec), fromsym, from_p, 1203 from, sec2annotation(fromsec), fromsym, from_p,
1204 to, sec2annotation(tosec), tosym, to_p, 1204 to, sec2annotation(tosec), tosym, to_p,
1205 sec2annotation(tosec), tosym, to_p); 1205 sec2annotation(tosec), tosym, to_p);
1206 break; 1206 break;
1207 case EXIT_TO_INIT: 1207 case EXIT_TO_INIT:
1208 fprintf(stderr, 1208 fprintf(stderr,
1209 "The %s %s%s%s references\n" 1209 "The %s %s%s%s references\n"
1210 "a %s %s%s%s.\n" 1210 "a %s %s%s%s.\n"
1211 "This is often seen when error handling " 1211 "This is often seen when error handling "
1212 "in the exit function\n" 1212 "in the exit function\n"
1213 "uses functionality in the init path.\n" 1213 "uses functionality in the init path.\n"
1214 "The fix is often to remove the %sannotation of\n" 1214 "The fix is often to remove the %sannotation of\n"
1215 "%s%s so it may be used outside an init section.\n", 1215 "%s%s so it may be used outside an init section.\n",
1216 from, sec2annotation(fromsec), fromsym, from_p, 1216 from, sec2annotation(fromsec), fromsym, from_p,
1217 to, sec2annotation(tosec), tosym, to_p, 1217 to, sec2annotation(tosec), tosym, to_p,
1218 sec2annotation(tosec), tosym, to_p); 1218 sec2annotation(tosec), tosym, to_p);
1219 break; 1219 break;
1220 case EXPORT_TO_INIT_EXIT: 1220 case EXPORT_TO_INIT_EXIT:
1221 fprintf(stderr, 1221 fprintf(stderr,
1222 "The symbol %s is exported and annotated %s\n" 1222 "The symbol %s is exported and annotated %s\n"
1223 "Fix this by removing the %sannotation of %s " 1223 "Fix this by removing the %sannotation of %s "
1224 "or drop the export.\n", 1224 "or drop the export.\n",
1225 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1225 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1226 case NO_MISMATCH: 1226 case NO_MISMATCH:
1227 /* To get warnings on missing members */ 1227 /* To get warnings on missing members */
1228 break; 1228 break;
1229 } 1229 }
1230 fprintf(stderr, "\n"); 1230 fprintf(stderr, "\n");
1231 } 1231 }
1232 1232
1233 static void check_section_mismatch(const char *modname, struct elf_info *elf, 1233 static void check_section_mismatch(const char *modname, struct elf_info *elf,
1234 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1234 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1235 { 1235 {
1236 const char *tosec; 1236 const char *tosec;
1237 enum mismatch mismatch; 1237 enum mismatch mismatch;
1238 1238
1239 tosec = sec_name(elf, sym->st_shndx); 1239 tosec = sec_name(elf, sym->st_shndx);
1240 mismatch = section_mismatch(fromsec, tosec); 1240 mismatch = section_mismatch(fromsec, tosec);
1241 if (mismatch != NO_MISMATCH) { 1241 if (mismatch != NO_MISMATCH) {
1242 Elf_Sym *to; 1242 Elf_Sym *to;
1243 Elf_Sym *from; 1243 Elf_Sym *from;
1244 const char *tosym; 1244 const char *tosym;
1245 const char *fromsym; 1245 const char *fromsym;
1246 1246
1247 from = find_elf_symbol2(elf, r->r_offset, fromsec); 1247 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1248 fromsym = sym_name(elf, from); 1248 fromsym = sym_name(elf, from);
1249 to = find_elf_symbol(elf, r->r_addend, sym); 1249 to = find_elf_symbol(elf, r->r_addend, sym);
1250 tosym = sym_name(elf, to); 1250 tosym = sym_name(elf, to);
1251 1251
1252 /* check whitelist - we may ignore it */ 1252 /* check whitelist - we may ignore it */
1253 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { 1253 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
1254 report_sec_mismatch(modname, mismatch, 1254 report_sec_mismatch(modname, mismatch,
1255 fromsec, r->r_offset, fromsym, 1255 fromsec, r->r_offset, fromsym,
1256 is_function(from), tosec, tosym, 1256 is_function(from), tosec, tosym,
1257 is_function(to)); 1257 is_function(to));
1258 } 1258 }
1259 } 1259 }
1260 } 1260 }
1261 1261
1262 static unsigned int *reloc_location(struct elf_info *elf, 1262 static unsigned int *reloc_location(struct elf_info *elf,
1263 Elf_Shdr *sechdr, Elf_Rela *r) 1263 Elf_Shdr *sechdr, Elf_Rela *r)
1264 { 1264 {
1265 Elf_Shdr *sechdrs = elf->sechdrs; 1265 Elf_Shdr *sechdrs = elf->sechdrs;
1266 int section = sechdr->sh_info; 1266 int section = sechdr->sh_info;
1267 1267
1268 return (void *)elf->hdr + sechdrs[section].sh_offset + 1268 return (void *)elf->hdr + sechdrs[section].sh_offset +
1269 (r->r_offset - sechdrs[section].sh_addr); 1269 (r->r_offset - sechdrs[section].sh_addr);
1270 } 1270 }
1271 1271
1272 static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) 1272 static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1273 { 1273 {
1274 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1274 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1275 unsigned int *location = reloc_location(elf, sechdr, r); 1275 unsigned int *location = reloc_location(elf, sechdr, r);
1276 1276
1277 switch (r_typ) { 1277 switch (r_typ) {
1278 case R_386_32: 1278 case R_386_32:
1279 r->r_addend = TO_NATIVE(*location); 1279 r->r_addend = TO_NATIVE(*location);
1280 break; 1280 break;
1281 case R_386_PC32: 1281 case R_386_PC32:
1282 r->r_addend = TO_NATIVE(*location) + 4; 1282 r->r_addend = TO_NATIVE(*location) + 4;
1283 /* For CONFIG_RELOCATABLE=y */ 1283 /* For CONFIG_RELOCATABLE=y */
1284 if (elf->hdr->e_type == ET_EXEC) 1284 if (elf->hdr->e_type == ET_EXEC)
1285 r->r_addend += r->r_offset; 1285 r->r_addend += r->r_offset;
1286 break; 1286 break;
1287 } 1287 }
1288 return 0; 1288 return 0;
1289 } 1289 }
1290 1290
1291 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) 1291 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1292 { 1292 {
1293 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1293 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1294 1294
1295 switch (r_typ) { 1295 switch (r_typ) {
1296 case R_ARM_ABS32: 1296 case R_ARM_ABS32:
1297 /* From ARM ABI: (S + A) | T */ 1297 /* From ARM ABI: (S + A) | T */
1298 r->r_addend = (int)(long) 1298 r->r_addend = (int)(long)
1299 (elf->symtab_start + ELF_R_SYM(r->r_info)); 1299 (elf->symtab_start + ELF_R_SYM(r->r_info));
1300 break; 1300 break;
1301 case R_ARM_PC24: 1301 case R_ARM_PC24:
1302 /* From ARM ABI: ((S + A) | T) - P */ 1302 /* From ARM ABI: ((S + A) | T) - P */
1303 r->r_addend = (int)(long)(elf->hdr + 1303 r->r_addend = (int)(long)(elf->hdr +
1304 sechdr->sh_offset + 1304 sechdr->sh_offset +
1305 (r->r_offset - sechdr->sh_addr)); 1305 (r->r_offset - sechdr->sh_addr));
1306 break; 1306 break;
1307 default: 1307 default:
1308 return 1; 1308 return 1;
1309 } 1309 }
1310 return 0; 1310 return 0;
1311 } 1311 }
1312 1312
1313 static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) 1313 static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1314 { 1314 {
1315 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1315 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1316 unsigned int *location = reloc_location(elf, sechdr, r); 1316 unsigned int *location = reloc_location(elf, sechdr, r);
1317 unsigned int inst; 1317 unsigned int inst;
1318 1318
1319 if (r_typ == R_MIPS_HI16) 1319 if (r_typ == R_MIPS_HI16)
1320 return 1; /* skip this */ 1320 return 1; /* skip this */
1321 inst = TO_NATIVE(*location); 1321 inst = TO_NATIVE(*location);
1322 switch (r_typ) { 1322 switch (r_typ) {
1323 case R_MIPS_LO16: 1323 case R_MIPS_LO16:
1324 r->r_addend = inst & 0xffff; 1324 r->r_addend = inst & 0xffff;
1325 break; 1325 break;
1326 case R_MIPS_26: 1326 case R_MIPS_26:
1327 r->r_addend = (inst & 0x03ffffff) << 2; 1327 r->r_addend = (inst & 0x03ffffff) << 2;
1328 break; 1328 break;
1329 case R_MIPS_32: 1329 case R_MIPS_32:
1330 r->r_addend = inst; 1330 r->r_addend = inst;
1331 break; 1331 break;
1332 } 1332 }
1333 return 0; 1333 return 0;
1334 } 1334 }
1335 1335
1336 static void section_rela(const char *modname, struct elf_info *elf, 1336 static void section_rela(const char *modname, struct elf_info *elf,
1337 Elf_Shdr *sechdr) 1337 Elf_Shdr *sechdr)
1338 { 1338 {
1339 Elf_Sym *sym; 1339 Elf_Sym *sym;
1340 Elf_Rela *rela; 1340 Elf_Rela *rela;
1341 Elf_Rela r; 1341 Elf_Rela r;
1342 unsigned int r_sym; 1342 unsigned int r_sym;
1343 const char *fromsec; 1343 const char *fromsec;
1344 1344
1345 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; 1345 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
1346 Elf_Rela *stop = (void *)start + sechdr->sh_size; 1346 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1347 1347
1348 fromsec = sech_name(elf, sechdr); 1348 fromsec = sech_name(elf, sechdr);
1349 fromsec += strlen(".rela"); 1349 fromsec += strlen(".rela");
1350 /* if from section (name) is know good then skip it */ 1350 /* if from section (name) is know good then skip it */
1351 if (check_section(modname, fromsec)) 1351 if (check_section(modname, fromsec))
1352 return; 1352 return;
1353 1353
1354 for (rela = start; rela < stop; rela++) { 1354 for (rela = start; rela < stop; rela++) {
1355 r.r_offset = TO_NATIVE(rela->r_offset); 1355 r.r_offset = TO_NATIVE(rela->r_offset);
1356 #if KERNEL_ELFCLASS == ELFCLASS64 1356 #if KERNEL_ELFCLASS == ELFCLASS64
1357 if (elf->hdr->e_machine == EM_MIPS) { 1357 if (elf->hdr->e_machine == EM_MIPS) {
1358 unsigned int r_typ; 1358 unsigned int r_typ;
1359 r_sym = ELF64_MIPS_R_SYM(rela->r_info); 1359 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1360 r_sym = TO_NATIVE(r_sym); 1360 r_sym = TO_NATIVE(r_sym);
1361 r_typ = ELF64_MIPS_R_TYPE(rela->r_info); 1361 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1362 r.r_info = ELF64_R_INFO(r_sym, r_typ); 1362 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1363 } else { 1363 } else {
1364 r.r_info = TO_NATIVE(rela->r_info); 1364 r.r_info = TO_NATIVE(rela->r_info);
1365 r_sym = ELF_R_SYM(r.r_info); 1365 r_sym = ELF_R_SYM(r.r_info);
1366 } 1366 }
1367 #else 1367 #else
1368 r.r_info = TO_NATIVE(rela->r_info); 1368 r.r_info = TO_NATIVE(rela->r_info);
1369 r_sym = ELF_R_SYM(r.r_info); 1369 r_sym = ELF_R_SYM(r.r_info);
1370 #endif 1370 #endif
1371 r.r_addend = TO_NATIVE(rela->r_addend); 1371 r.r_addend = TO_NATIVE(rela->r_addend);
1372 sym = elf->symtab_start + r_sym; 1372 sym = elf->symtab_start + r_sym;
1373 /* Skip special sections */ 1373 /* Skip special sections */
1374 if (sym->st_shndx >= SHN_LORESERVE) 1374 if (sym->st_shndx >= SHN_LORESERVE)
1375 continue; 1375 continue;
1376 check_section_mismatch(modname, elf, &r, sym, fromsec); 1376 check_section_mismatch(modname, elf, &r, sym, fromsec);
1377 } 1377 }
1378 } 1378 }
1379 1379
1380 static void section_rel(const char *modname, struct elf_info *elf, 1380 static void section_rel(const char *modname, struct elf_info *elf,
1381 Elf_Shdr *sechdr) 1381 Elf_Shdr *sechdr)
1382 { 1382 {
1383 Elf_Sym *sym; 1383 Elf_Sym *sym;
1384 Elf_Rel *rel; 1384 Elf_Rel *rel;
1385 Elf_Rela r; 1385 Elf_Rela r;
1386 unsigned int r_sym; 1386 unsigned int r_sym;
1387 const char *fromsec; 1387 const char *fromsec;
1388 1388
1389 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; 1389 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
1390 Elf_Rel *stop = (void *)start + sechdr->sh_size; 1390 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1391 1391
1392 fromsec = sech_name(elf, sechdr); 1392 fromsec = sech_name(elf, sechdr);
1393 fromsec += strlen(".rel"); 1393 fromsec += strlen(".rel");
1394 /* if from section (name) is know good then skip it */ 1394 /* if from section (name) is know good then skip it */
1395 if (check_section(modname, fromsec)) 1395 if (check_section(modname, fromsec))
1396 return; 1396 return;
1397 1397
1398 for (rel = start; rel < stop; rel++) { 1398 for (rel = start; rel < stop; rel++) {
1399 r.r_offset = TO_NATIVE(rel->r_offset); 1399 r.r_offset = TO_NATIVE(rel->r_offset);
1400 #if KERNEL_ELFCLASS == ELFCLASS64 1400 #if KERNEL_ELFCLASS == ELFCLASS64
1401 if (elf->hdr->e_machine == EM_MIPS) { 1401 if (elf->hdr->e_machine == EM_MIPS) {
1402 unsigned int r_typ; 1402 unsigned int r_typ;
1403 r_sym = ELF64_MIPS_R_SYM(rel->r_info); 1403 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1404 r_sym = TO_NATIVE(r_sym); 1404 r_sym = TO_NATIVE(r_sym);
1405 r_typ = ELF64_MIPS_R_TYPE(rel->r_info); 1405 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1406 r.r_info = ELF64_R_INFO(r_sym, r_typ); 1406 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1407 } else { 1407 } else {
1408 r.r_info = TO_NATIVE(rel->r_info); 1408 r.r_info = TO_NATIVE(rel->r_info);
1409 r_sym = ELF_R_SYM(r.r_info); 1409 r_sym = ELF_R_SYM(r.r_info);
1410 } 1410 }
1411 #else 1411 #else
1412 r.r_info = TO_NATIVE(rel->r_info); 1412 r.r_info = TO_NATIVE(rel->r_info);
1413 r_sym = ELF_R_SYM(r.r_info); 1413 r_sym = ELF_R_SYM(r.r_info);
1414 #endif 1414 #endif
1415 r.r_addend = 0; 1415 r.r_addend = 0;
1416 switch (elf->hdr->e_machine) { 1416 switch (elf->hdr->e_machine) {
1417 case EM_386: 1417 case EM_386:
1418 if (addend_386_rel(elf, sechdr, &r)) 1418 if (addend_386_rel(elf, sechdr, &r))
1419 continue; 1419 continue;
1420 break; 1420 break;
1421 case EM_ARM: 1421 case EM_ARM:
1422 if (addend_arm_rel(elf, sechdr, &r)) 1422 if (addend_arm_rel(elf, sechdr, &r))
1423 continue; 1423 continue;
1424 break; 1424 break;
1425 case EM_MIPS: 1425 case EM_MIPS:
1426 if (addend_mips_rel(elf, sechdr, &r)) 1426 if (addend_mips_rel(elf, sechdr, &r))
1427 continue; 1427 continue;
1428 break; 1428 break;
1429 } 1429 }
1430 sym = elf->symtab_start + r_sym; 1430 sym = elf->symtab_start + r_sym;
1431 /* Skip special sections */ 1431 /* Skip special sections */
1432 if (sym->st_shndx >= SHN_LORESERVE) 1432 if (sym->st_shndx >= SHN_LORESERVE)
1433 continue; 1433 continue;
1434 check_section_mismatch(modname, elf, &r, sym, fromsec); 1434 check_section_mismatch(modname, elf, &r, sym, fromsec);
1435 } 1435 }
1436 } 1436 }
1437 1437
1438 /** 1438 /**
1439 * A module includes a number of sections that are discarded 1439 * A module includes a number of sections that are discarded
1440 * either when loaded or when used as built-in. 1440 * either when loaded or when used as built-in.
1441 * For loaded modules all functions marked __init and all data 1441 * For loaded modules all functions marked __init and all data
1442 * marked __initdata will be discarded when the module has been intialized. 1442 * marked __initdata will be discarded when the module has been intialized.
1443 * Likewise for modules used built-in the sections marked __exit 1443 * Likewise for modules used built-in the sections marked __exit
1444 * are discarded because __exit marked function are supposed to be called 1444 * are discarded because __exit marked function are supposed to be called
1445 * only when a moduel is unloaded which never happes for built-in modules. 1445 * only when a moduel is unloaded which never happes for built-in modules.
1446 * The check_sec_ref() function traverses all relocation records 1446 * The check_sec_ref() function traverses all relocation records
1447 * to find all references to a section that reference a section that will 1447 * to find all references to a section that reference a section that will
1448 * be discarded and warns about it. 1448 * be discarded and warns about it.
1449 **/ 1449 **/
1450 static void check_sec_ref(struct module *mod, const char *modname, 1450 static void check_sec_ref(struct module *mod, const char *modname,
1451 struct elf_info *elf) 1451 struct elf_info *elf)
1452 { 1452 {
1453 int i; 1453 int i;
1454 Elf_Shdr *sechdrs = elf->sechdrs; 1454 Elf_Shdr *sechdrs = elf->sechdrs;
1455 1455
1456 /* Walk through all sections */ 1456 /* Walk through all sections */
1457 for (i = 0; i < elf->hdr->e_shnum; i++) { 1457 for (i = 0; i < elf->hdr->e_shnum; i++) {
1458 /* We want to process only relocation sections and not .init */ 1458 /* We want to process only relocation sections and not .init */
1459 if (sechdrs[i].sh_type == SHT_RELA) 1459 if (sechdrs[i].sh_type == SHT_RELA)
1460 section_rela(modname, elf, &elf->sechdrs[i]); 1460 section_rela(modname, elf, &elf->sechdrs[i]);
1461 else if (sechdrs[i].sh_type == SHT_REL) 1461 else if (sechdrs[i].sh_type == SHT_REL)
1462 section_rel(modname, elf, &elf->sechdrs[i]); 1462 section_rel(modname, elf, &elf->sechdrs[i]);
1463 } 1463 }
1464 } 1464 }
1465 1465
1466 static void read_symbols(char *modname) 1466 static void read_symbols(char *modname)
1467 { 1467 {
1468 const char *symname; 1468 const char *symname;
1469 char *version; 1469 char *version;
1470 char *license; 1470 char *license;
1471 struct module *mod; 1471 struct module *mod;
1472 struct elf_info info = { }; 1472 struct elf_info info = { };
1473 Elf_Sym *sym; 1473 Elf_Sym *sym;
1474 1474
1475 if (!parse_elf(&info, modname)) 1475 if (!parse_elf(&info, modname))
1476 return; 1476 return;
1477 1477
1478 mod = new_module(modname); 1478 mod = new_module(modname);
1479 1479
1480 /* When there's no vmlinux, don't print warnings about 1480 /* When there's no vmlinux, don't print warnings about
1481 * unresolved symbols (since there'll be too many ;) */ 1481 * unresolved symbols (since there'll be too many ;) */
1482 if (is_vmlinux(modname)) { 1482 if (is_vmlinux(modname)) {
1483 have_vmlinux = 1; 1483 have_vmlinux = 1;
1484 mod->skip = 1; 1484 mod->skip = 1;
1485 } 1485 }
1486 1486
1487 license = get_modinfo(info.modinfo, info.modinfo_len, "license"); 1487 license = get_modinfo(info.modinfo, info.modinfo_len, "license");
1488 while (license) { 1488 while (license) {
1489 if (license_is_gpl_compatible(license)) 1489 if (license_is_gpl_compatible(license))
1490 mod->gpl_compatible = 1; 1490 mod->gpl_compatible = 1;
1491 else { 1491 else {
1492 mod->gpl_compatible = 0; 1492 mod->gpl_compatible = 0;
1493 break; 1493 break;
1494 } 1494 }
1495 license = get_next_modinfo(info.modinfo, info.modinfo_len, 1495 license = get_next_modinfo(info.modinfo, info.modinfo_len,
1496 "license", license); 1496 "license", license);
1497 } 1497 }
1498 1498
1499 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { 1499 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1500 symname = info.strtab + sym->st_name; 1500 symname = info.strtab + sym->st_name;
1501 1501
1502 handle_modversions(mod, &info, sym, symname); 1502 handle_modversions(mod, &info, sym, symname);
1503 handle_moddevtable(mod, &info, sym, symname); 1503 handle_moddevtable(mod, &info, sym, symname);
1504 } 1504 }
1505 if (!is_vmlinux(modname) || 1505 if (!is_vmlinux(modname) ||
1506 (is_vmlinux(modname) && vmlinux_section_warnings)) 1506 (is_vmlinux(modname) && vmlinux_section_warnings))
1507 check_sec_ref(mod, modname, &info); 1507 check_sec_ref(mod, modname, &info);
1508 1508
1509 version = get_modinfo(info.modinfo, info.modinfo_len, "version"); 1509 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1510 if (version) 1510 if (version)
1511 maybe_frob_rcs_version(modname, version, info.modinfo, 1511 maybe_frob_rcs_version(modname, version, info.modinfo,
1512 version - (char *)info.hdr); 1512 version - (char *)info.hdr);
1513 if (version || (all_versions && !is_vmlinux(modname))) 1513 if (version || (all_versions && !is_vmlinux(modname)))
1514 get_src_version(modname, mod->srcversion, 1514 get_src_version(modname, mod->srcversion,
1515 sizeof(mod->srcversion)-1); 1515 sizeof(mod->srcversion)-1);
1516 1516
1517 parse_elf_finish(&info); 1517 parse_elf_finish(&info);
1518 1518
1519 /* Our trick to get versioning for struct_module - it's 1519 /* Our trick to get versioning for struct_module - it's
1520 * never passed as an argument to an exported function, so 1520 * never passed as an argument to an exported function, so
1521 * the automatic versioning doesn't pick it up, but it's really 1521 * the automatic versioning doesn't pick it up, but it's really
1522 * important anyhow */ 1522 * important anyhow */
1523 if (modversions) 1523 if (modversions)
1524 mod->unres = alloc_symbol("struct_module", 0, mod->unres); 1524 mod->unres = alloc_symbol("struct_module", 0, mod->unres);
1525 } 1525 }
1526 1526
1527 #define SZ 500 1527 #define SZ 500
1528 1528
1529 /* We first write the generated file into memory using the 1529 /* We first write the generated file into memory using the
1530 * following helper, then compare to the file on disk and 1530 * following helper, then compare to the file on disk and
1531 * only update the later if anything changed */ 1531 * only update the later if anything changed */
1532 1532
1533 void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, 1533 void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
1534 const char *fmt, ...) 1534 const char *fmt, ...)
1535 { 1535 {
1536 char tmp[SZ]; 1536 char tmp[SZ];
1537 int len; 1537 int len;
1538 va_list ap; 1538 va_list ap;
1539 1539
1540 va_start(ap, fmt); 1540 va_start(ap, fmt);
1541 len = vsnprintf(tmp, SZ, fmt, ap); 1541 len = vsnprintf(tmp, SZ, fmt, ap);
1542 buf_write(buf, tmp, len); 1542 buf_write(buf, tmp, len);
1543 va_end(ap); 1543 va_end(ap);
1544 } 1544 }
1545 1545
1546 void buf_write(struct buffer *buf, const char *s, int len) 1546 void buf_write(struct buffer *buf, const char *s, int len)
1547 { 1547 {
1548 if (buf->size - buf->pos < len) { 1548 if (buf->size - buf->pos < len) {
1549 buf->size += len + SZ; 1549 buf->size += len + SZ;
1550 buf->p = realloc(buf->p, buf->size); 1550 buf->p = realloc(buf->p, buf->size);
1551 } 1551 }
1552 strncpy(buf->p + buf->pos, s, len); 1552 strncpy(buf->p + buf->pos, s, len);
1553 buf->pos += len; 1553 buf->pos += len;
1554 } 1554 }
1555 1555
1556 static void check_for_gpl_usage(enum export exp, const char *m, const char *s) 1556 static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
1557 { 1557 {
1558 const char *e = is_vmlinux(m) ?"":".ko"; 1558 const char *e = is_vmlinux(m) ?"":".ko";
1559 1559
1560 switch (exp) { 1560 switch (exp) {
1561 case export_gpl: 1561 case export_gpl:
1562 fatal("modpost: GPL-incompatible module %s%s " 1562 fatal("modpost: GPL-incompatible module %s%s "
1563 "uses GPL-only symbol '%s'\n", m, e, s); 1563 "uses GPL-only symbol '%s'\n", m, e, s);
1564 break; 1564 break;
1565 case export_unused_gpl: 1565 case export_unused_gpl:
1566 fatal("modpost: GPL-incompatible module %s%s " 1566 fatal("modpost: GPL-incompatible module %s%s "
1567 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s); 1567 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
1568 break; 1568 break;
1569 case export_gpl_future: 1569 case export_gpl_future:
1570 warn("modpost: GPL-incompatible module %s%s " 1570 warn("modpost: GPL-incompatible module %s%s "
1571 "uses future GPL-only symbol '%s'\n", m, e, s); 1571 "uses future GPL-only symbol '%s'\n", m, e, s);
1572 break; 1572 break;
1573 case export_plain: 1573 case export_plain:
1574 case export_unused: 1574 case export_unused:
1575 case export_unknown: 1575 case export_unknown:
1576 /* ignore */ 1576 /* ignore */
1577 break; 1577 break;
1578 } 1578 }
1579 } 1579 }
1580 1580
1581 static void check_for_unused(enum export exp, const char *m, const char *s) 1581 static void check_for_unused(enum export exp, const char *m, const char *s)
1582 { 1582 {
1583 const char *e = is_vmlinux(m) ?"":".ko"; 1583 const char *e = is_vmlinux(m) ?"":".ko";
1584 1584
1585 switch (exp) { 1585 switch (exp) {
1586 case export_unused: 1586 case export_unused:
1587 case export_unused_gpl: 1587 case export_unused_gpl:
1588 warn("modpost: module %s%s " 1588 warn("modpost: module %s%s "
1589 "uses symbol '%s' marked UNUSED\n", m, e, s); 1589 "uses symbol '%s' marked UNUSED\n", m, e, s);
1590 break; 1590 break;
1591 default: 1591 default:
1592 /* ignore */ 1592 /* ignore */
1593 break; 1593 break;
1594 } 1594 }
1595 } 1595 }
1596 1596
1597 static void check_exports(struct module *mod) 1597 static void check_exports(struct module *mod)
1598 { 1598 {
1599 struct symbol *s, *exp; 1599 struct symbol *s, *exp;
1600 1600
1601 for (s = mod->unres; s; s = s->next) { 1601 for (s = mod->unres; s; s = s->next) {
1602 const char *basename; 1602 const char *basename;
1603 exp = find_symbol(s->name); 1603 exp = find_symbol(s->name);
1604 if (!exp || exp->module == mod) 1604 if (!exp || exp->module == mod)
1605 continue; 1605 continue;
1606 basename = strrchr(mod->name, '/'); 1606 basename = strrchr(mod->name, '/');
1607 if (basename) 1607 if (basename)
1608 basename++; 1608 basename++;
1609 else 1609 else
1610 basename = mod->name; 1610 basename = mod->name;
1611 if (!mod->gpl_compatible) 1611 if (!mod->gpl_compatible)
1612 check_for_gpl_usage(exp->export, basename, exp->name); 1612 check_for_gpl_usage(exp->export, basename, exp->name);
1613 check_for_unused(exp->export, basename, exp->name); 1613 check_for_unused(exp->export, basename, exp->name);
1614 } 1614 }
1615 } 1615 }
1616 1616
1617 /** 1617 /**
1618 * Header for the generated file 1618 * Header for the generated file
1619 **/ 1619 **/
1620 static void add_header(struct buffer *b, struct module *mod) 1620 static void add_header(struct buffer *b, struct module *mod)
1621 { 1621 {
1622 buf_printf(b, "#include <linux/module.h>\n"); 1622 buf_printf(b, "#include <linux/module.h>\n");
1623 buf_printf(b, "#include <linux/vermagic.h>\n"); 1623 buf_printf(b, "#include <linux/vermagic.h>\n");
1624 buf_printf(b, "#include <linux/compiler.h>\n"); 1624 buf_printf(b, "#include <linux/compiler.h>\n");
1625 buf_printf(b, "\n"); 1625 buf_printf(b, "\n");
1626 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); 1626 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
1627 buf_printf(b, "\n"); 1627 buf_printf(b, "\n");
1628 buf_printf(b, "struct module __this_module\n"); 1628 buf_printf(b, "struct module __this_module\n");
1629 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); 1629 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
1630 buf_printf(b, " .name = KBUILD_MODNAME,\n"); 1630 buf_printf(b, " .name = KBUILD_MODNAME,\n");
1631 if (mod->has_init) 1631 if (mod->has_init)
1632 buf_printf(b, " .init = init_module,\n"); 1632 buf_printf(b, " .init = init_module,\n");
1633 if (mod->has_cleanup) 1633 if (mod->has_cleanup)
1634 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n" 1634 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
1635 " .exit = cleanup_module,\n" 1635 " .exit = cleanup_module,\n"
1636 "#endif\n"); 1636 "#endif\n");
1637 buf_printf(b, " .arch = MODULE_ARCH_INIT,\n"); 1637 buf_printf(b, " .arch = MODULE_ARCH_INIT,\n");
1638 buf_printf(b, "};\n"); 1638 buf_printf(b, "};\n");
1639 } 1639 }
1640 1640
1641 /** 1641 /**
1642 * Record CRCs for unresolved symbols 1642 * Record CRCs for unresolved symbols
1643 **/ 1643 **/
1644 static int add_versions(struct buffer *b, struct module *mod) 1644 static int add_versions(struct buffer *b, struct module *mod)
1645 { 1645 {
1646 struct symbol *s, *exp; 1646 struct symbol *s, *exp;
1647 int err = 0; 1647 int err = 0;
1648 1648
1649 for (s = mod->unres; s; s = s->next) { 1649 for (s = mod->unres; s; s = s->next) {
1650 exp = find_symbol(s->name); 1650 exp = find_symbol(s->name);
1651 if (!exp || exp->module == mod) { 1651 if (!exp || exp->module == mod) {
1652 if (have_vmlinux && !s->weak) { 1652 if (have_vmlinux && !s->weak) {
1653 if (warn_unresolved) { 1653 if (warn_unresolved) {
1654 warn("\"%s\" [%s.ko] undefined!\n", 1654 warn("\"%s\" [%s.ko] undefined!\n",
1655 s->name, mod->name); 1655 s->name, mod->name);
1656 } else { 1656 } else {
1657 merror("\"%s\" [%s.ko] undefined!\n", 1657 merror("\"%s\" [%s.ko] undefined!\n",
1658 s->name, mod->name); 1658 s->name, mod->name);
1659 err = 1; 1659 err = 1;
1660 } 1660 }
1661 } 1661 }
1662 continue; 1662 continue;
1663 } 1663 }
1664 s->module = exp->module; 1664 s->module = exp->module;
1665 s->crc_valid = exp->crc_valid; 1665 s->crc_valid = exp->crc_valid;
1666 s->crc = exp->crc; 1666 s->crc = exp->crc;
1667 } 1667 }
1668 1668
1669 if (!modversions) 1669 if (!modversions)
1670 return err; 1670 return err;
1671 1671
1672 buf_printf(b, "\n"); 1672 buf_printf(b, "\n");
1673 buf_printf(b, "static const struct modversion_info ____versions[]\n"); 1673 buf_printf(b, "static const struct modversion_info ____versions[]\n");
1674 buf_printf(b, "__used\n"); 1674 buf_printf(b, "__used\n");
1675 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); 1675 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
1676 1676
1677 for (s = mod->unres; s; s = s->next) { 1677 for (s = mod->unres; s; s = s->next) {
1678 if (!s->module) 1678 if (!s->module)
1679 continue; 1679 continue;
1680 if (!s->crc_valid) { 1680 if (!s->crc_valid) {
1681 warn("\"%s\" [%s.ko] has no CRC!\n", 1681 warn("\"%s\" [%s.ko] has no CRC!\n",
1682 s->name, mod->name); 1682 s->name, mod->name);
1683 continue; 1683 continue;
1684 } 1684 }
1685 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); 1685 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
1686 } 1686 }
1687 1687
1688 buf_printf(b, "};\n"); 1688 buf_printf(b, "};\n");
1689 1689
1690 return err; 1690 return err;
1691 } 1691 }
1692 1692
1693 static void add_depends(struct buffer *b, struct module *mod, 1693 static void add_depends(struct buffer *b, struct module *mod,
1694 struct module *modules) 1694 struct module *modules)
1695 { 1695 {
1696 struct symbol *s; 1696 struct symbol *s;
1697 struct module *m; 1697 struct module *m;
1698 int first = 1; 1698 int first = 1;
1699 1699
1700 for (m = modules; m; m = m->next) 1700 for (m = modules; m; m = m->next)
1701 m->seen = is_vmlinux(m->name); 1701 m->seen = is_vmlinux(m->name);
1702 1702
1703 buf_printf(b, "\n"); 1703 buf_printf(b, "\n");
1704 buf_printf(b, "static const char __module_depends[]\n"); 1704 buf_printf(b, "static const char __module_depends[]\n");
1705 buf_printf(b, "__used\n"); 1705 buf_printf(b, "__used\n");
1706 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); 1706 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1707 buf_printf(b, "\"depends="); 1707 buf_printf(b, "\"depends=");
1708 for (s = mod->unres; s; s = s->next) { 1708 for (s = mod->unres; s; s = s->next) {
1709 const char *p; 1709 const char *p;
1710 if (!s->module) 1710 if (!s->module)
1711 continue; 1711 continue;
1712 1712
1713 if (s->module->seen) 1713 if (s->module->seen)
1714 continue; 1714 continue;
1715 1715
1716 s->module->seen = 1; 1716 s->module->seen = 1;
1717 p = strrchr(s->module->name, '/'); 1717 p = strrchr(s->module->name, '/');
1718 if (p) 1718 if (p)
1719 p++; 1719 p++;
1720 else 1720 else
1721 p = s->module->name; 1721 p = s->module->name;
1722 buf_printf(b, "%s%s", first ? "" : ",", p); 1722 buf_printf(b, "%s%s", first ? "" : ",", p);
1723 first = 0; 1723 first = 0;
1724 } 1724 }
1725 buf_printf(b, "\";\n"); 1725 buf_printf(b, "\";\n");
1726 } 1726 }
1727 1727
1728 static void add_srcversion(struct buffer *b, struct module *mod) 1728 static void add_srcversion(struct buffer *b, struct module *mod)
1729 { 1729 {
1730 if (mod->srcversion[0]) { 1730 if (mod->srcversion[0]) {
1731 buf_printf(b, "\n"); 1731 buf_printf(b, "\n");
1732 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", 1732 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
1733 mod->srcversion); 1733 mod->srcversion);
1734 } 1734 }
1735 } 1735 }
1736 1736
1737 static void write_if_changed(struct buffer *b, const char *fname) 1737 static void write_if_changed(struct buffer *b, const char *fname)
1738 { 1738 {
1739 char *tmp; 1739 char *tmp;
1740 FILE *file; 1740 FILE *file;
1741 struct stat st; 1741 struct stat st;
1742 1742
1743 file = fopen(fname, "r"); 1743 file = fopen(fname, "r");
1744 if (!file) 1744 if (!file)
1745 goto write; 1745 goto write;
1746 1746
1747 if (fstat(fileno(file), &st) < 0) 1747 if (fstat(fileno(file), &st) < 0)
1748 goto close_write; 1748 goto close_write;
1749 1749
1750 if (st.st_size != b->pos) 1750 if (st.st_size != b->pos)
1751 goto close_write; 1751 goto close_write;
1752 1752
1753 tmp = NOFAIL(malloc(b->pos)); 1753 tmp = NOFAIL(malloc(b->pos));
1754 if (fread(tmp, 1, b->pos, file) != b->pos) 1754 if (fread(tmp, 1, b->pos, file) != b->pos)
1755 goto free_write; 1755 goto free_write;
1756 1756
1757 if (memcmp(tmp, b->p, b->pos) != 0) 1757 if (memcmp(tmp, b->p, b->pos) != 0)
1758 goto free_write; 1758 goto free_write;
1759 1759
1760 free(tmp); 1760 free(tmp);
1761 fclose(file); 1761 fclose(file);
1762 return; 1762 return;
1763 1763
1764 free_write: 1764 free_write:
1765 free(tmp); 1765 free(tmp);
1766 close_write: 1766 close_write:
1767 fclose(file); 1767 fclose(file);
1768 write: 1768 write:
1769 file = fopen(fname, "w"); 1769 file = fopen(fname, "w");
1770 if (!file) { 1770 if (!file) {
1771 perror(fname); 1771 perror(fname);
1772 exit(1); 1772 exit(1);
1773 } 1773 }
1774 if (fwrite(b->p, 1, b->pos, file) != b->pos) { 1774 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
1775 perror(fname); 1775 perror(fname);
1776 exit(1); 1776 exit(1);
1777 } 1777 }
1778 fclose(file); 1778 fclose(file);
1779 } 1779 }
1780 1780
1781 /* parse Module.symvers file. line format: 1781 /* parse Module.symvers file. line format:
1782 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something] 1782 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
1783 **/ 1783 **/
1784 static void read_dump(const char *fname, unsigned int kernel) 1784 static void read_dump(const char *fname, unsigned int kernel)
1785 { 1785 {
1786 unsigned long size, pos = 0; 1786 unsigned long size, pos = 0;
1787 void *file = grab_file(fname, &size); 1787 void *file = grab_file(fname, &size);
1788 char *line; 1788 char *line;
1789 1789
1790 if (!file) 1790 if (!file)
1791 /* No symbol versions, silently ignore */ 1791 /* No symbol versions, silently ignore */
1792 return; 1792 return;
1793 1793
1794 while ((line = get_next_line(&pos, file, size))) { 1794 while ((line = get_next_line(&pos, file, size))) {
1795 char *symname, *modname, *d, *export, *end; 1795 char *symname, *modname, *d, *export, *end;
1796 unsigned int crc; 1796 unsigned int crc;
1797 struct module *mod; 1797 struct module *mod;
1798 struct symbol *s; 1798 struct symbol *s;
1799 1799
1800 if (!(symname = strchr(line, '\t'))) 1800 if (!(symname = strchr(line, '\t')))
1801 goto fail; 1801 goto fail;
1802 *symname++ = '\0'; 1802 *symname++ = '\0';
1803 if (!(modname = strchr(symname, '\t'))) 1803 if (!(modname = strchr(symname, '\t')))
1804 goto fail; 1804 goto fail;
1805 *modname++ = '\0'; 1805 *modname++ = '\0';
1806 if ((export = strchr(modname, '\t')) != NULL) 1806 if ((export = strchr(modname, '\t')) != NULL)
1807 *export++ = '\0'; 1807 *export++ = '\0';
1808 if (export && ((end = strchr(export, '\t')) != NULL)) 1808 if (export && ((end = strchr(export, '\t')) != NULL))
1809 *end = '\0'; 1809 *end = '\0';
1810 crc = strtoul(line, &d, 16); 1810 crc = strtoul(line, &d, 16);
1811 if (*symname == '\0' || *modname == '\0' || *d != '\0') 1811 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1812 goto fail; 1812 goto fail;
1813 mod = find_module(modname); 1813 mod = find_module(modname);
1814 if (!mod) { 1814 if (!mod) {
1815 if (is_vmlinux(modname)) 1815 if (is_vmlinux(modname))
1816 have_vmlinux = 1; 1816 have_vmlinux = 1;
1817 mod = new_module(NOFAIL(strdup(modname))); 1817 mod = new_module(NOFAIL(strdup(modname)));
1818 mod->skip = 1; 1818 mod->skip = 1;
1819 } 1819 }
1820 s = sym_add_exported(symname, mod, export_no(export)); 1820 s = sym_add_exported(symname, mod, export_no(export));
1821 s->kernel = kernel; 1821 s->kernel = kernel;
1822 s->preloaded = 1; 1822 s->preloaded = 1;
1823 sym_update_crc(symname, mod, crc, export_no(export)); 1823 sym_update_crc(symname, mod, crc, export_no(export));
1824 } 1824 }
1825 return; 1825 return;
1826 fail: 1826 fail:
1827 fatal("parse error in symbol dump file\n"); 1827 fatal("parse error in symbol dump file\n");
1828 } 1828 }
1829 1829
1830 /* For normal builds always dump all symbols. 1830 /* For normal builds always dump all symbols.
1831 * For external modules only dump symbols 1831 * For external modules only dump symbols
1832 * that are not read from kernel Module.symvers. 1832 * that are not read from kernel Module.symvers.
1833 **/ 1833 **/
1834 static int dump_sym(struct symbol *sym) 1834 static int dump_sym(struct symbol *sym)
1835 { 1835 {
1836 if (!external_module) 1836 if (!external_module)
1837 return 1; 1837 return 1;
1838 if (sym->vmlinux || sym->kernel) 1838 if (sym->vmlinux || sym->kernel)
1839 return 0; 1839 return 0;
1840 return 1; 1840 return 1;
1841 } 1841 }
1842 1842
1843 static void write_dump(const char *fname) 1843 static void write_dump(const char *fname)
1844 { 1844 {
1845 struct buffer buf = { }; 1845 struct buffer buf = { };
1846 struct symbol *symbol; 1846 struct symbol *symbol;
1847 int n; 1847 int n;
1848 1848
1849 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { 1849 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
1850 symbol = symbolhash[n]; 1850 symbol = symbolhash[n];
1851 while (symbol) { 1851 while (symbol) {
1852 if (dump_sym(symbol)) 1852 if (dump_sym(symbol))
1853 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", 1853 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
1854 symbol->crc, symbol->name, 1854 symbol->crc, symbol->name,
1855 symbol->module->name, 1855 symbol->module->name,
1856 export_str(symbol->export)); 1856 export_str(symbol->export));
1857 symbol = symbol->next; 1857 symbol = symbol->next;
1858 } 1858 }
1859 } 1859 }
1860 write_if_changed(&buf, fname); 1860 write_if_changed(&buf, fname);
1861 } 1861 }
1862 1862
1863 int main(int argc, char **argv) 1863 int main(int argc, char **argv)
1864 { 1864 {
1865 struct module *mod; 1865 struct module *mod;
1866 struct buffer buf = { }; 1866 struct buffer buf = { };
1867 char *kernel_read = NULL, *module_read = NULL; 1867 char *kernel_read = NULL, *module_read = NULL;
1868 char *dump_write = NULL; 1868 char *dump_write = NULL;
1869 int opt; 1869 int opt;
1870 int err; 1870 int err;
1871 1871
1872 while ((opt = getopt(argc, argv, "i:I:msSo:aw")) != -1) { 1872 while ((opt = getopt(argc, argv, "i:I:msSo:aw")) != -1) {
1873 switch (opt) { 1873 switch (opt) {
1874 case 'i': 1874 case 'i':
1875 kernel_read = optarg; 1875 kernel_read = optarg;
1876 break; 1876 break;
1877 case 'I': 1877 case 'I':
1878 module_read = optarg; 1878 module_read = optarg;
1879 external_module = 1; 1879 external_module = 1;
1880 break; 1880 break;
1881 case 'm': 1881 case 'm':
1882 modversions = 1; 1882 modversions = 1;
1883 break; 1883 break;
1884 case 'o': 1884 case 'o':
1885 dump_write = optarg; 1885 dump_write = optarg;
1886 break; 1886 break;
1887 case 'a': 1887 case 'a':
1888 all_versions = 1; 1888 all_versions = 1;
1889 break; 1889 break;
1890 case 's': 1890 case 's':
1891 vmlinux_section_warnings = 0; 1891 vmlinux_section_warnings = 0;
1892 break; 1892 break;
1893 case 'S': 1893 case 'S':
1894 sec_mismatch_verbose = 0; 1894 sec_mismatch_verbose = 0;
1895 break; 1895 break;
1896 case 'w': 1896 case 'w':
1897 warn_unresolved = 1; 1897 warn_unresolved = 1;
1898 break; 1898 break;
1899 default: 1899 default:
1900 exit(1); 1900 exit(1);
1901 } 1901 }
1902 } 1902 }
1903 1903
1904 if (kernel_read) 1904 if (kernel_read)
1905 read_dump(kernel_read, 1); 1905 read_dump(kernel_read, 1);
1906 if (module_read) 1906 if (module_read)
1907 read_dump(module_read, 0); 1907 read_dump(module_read, 0);
1908 1908
1909 while (optind < argc) 1909 while (optind < argc)
1910 read_symbols(argv[optind++]); 1910 read_symbols(argv[optind++]);
1911 1911
1912 for (mod = modules; mod; mod = mod->next) { 1912 for (mod = modules; mod; mod = mod->next) {
1913 if (mod->skip) 1913 if (mod->skip)
1914 continue; 1914 continue;
1915 check_exports(mod); 1915 check_exports(mod);
1916 } 1916 }
1917 1917
1918 err = 0; 1918 err = 0;
1919 1919
1920 for (mod = modules; mod; mod = mod->next) { 1920 for (mod = modules; mod; mod = mod->next) {
1921 char fname[strlen(mod->name) + 10]; 1921 char fname[strlen(mod->name) + 10];
1922 1922
1923 if (mod->skip) 1923 if (mod->skip)
1924 continue; 1924 continue;
1925 1925
1926 buf.pos = 0; 1926 buf.pos = 0;
1927 1927
1928 add_header(&buf, mod); 1928 add_header(&buf, mod);
1929 err |= add_versions(&buf, mod); 1929 err |= add_versions(&buf, mod);
1930 add_depends(&buf, mod, modules); 1930 add_depends(&buf, mod, modules);
1931 add_moddevtable(&buf, mod); 1931 add_moddevtable(&buf, mod);
1932 add_srcversion(&buf, mod); 1932 add_srcversion(&buf, mod);
1933 1933
1934 sprintf(fname, "%s.mod.c", mod->name); 1934 sprintf(fname, "%s.mod.c", mod->name);
1935 write_if_changed(&buf, fname); 1935 write_if_changed(&buf, fname);
1936 } 1936 }
1937 1937
1938 if (dump_write) 1938 if (dump_write)
1939 write_dump(dump_write); 1939 write_dump(dump_write);
1940 if (sec_mismatch_count && !sec_mismatch_verbose) 1940 if (sec_mismatch_count && !sec_mismatch_verbose)
1941 fprintf(stderr, "modpost: Found %d section mismatch(es).\n" 1941 fprintf(stderr, "modpost: Found %d section mismatch(es).\n"
1942 "To see full details build your kernel with:\n" 1942 "To see full details build your kernel with:\n"
1943 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", 1943 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
1944 sec_mismatch_count); 1944 sec_mismatch_count);
1945 1945
1946 return err; 1946 return err;
1947 } 1947 }
1948 1948