blob: bbc54e3169aa7c88a4f6f3e113de9aca74209478 [file] [log] [blame]
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini insmod implementation for busybox
4 *
5 * This version of insmod supports ARM, CRIS, H8/300, x86, ia64, x86_64,
6 * m68k, MIPS, PowerPC, S390, SH3/4/5, Sparc, v850e, and x86_64.
7 *
8 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
9 * and Ron Alder <alder@lineo.com>
10 *
11 * Rodney Radford <rradford@mindspring.com> 17-Aug-2004.
12 * Added x86_64 support.
13 *
14 * Miles Bader <miles@gnu.org> added NEC V850E support.
15 *
16 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
17 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
18 *
19 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
20 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
21 * very minor changes required to also work with StrongArm and presumably
22 * all ARM based systems.
23 *
24 * Yoshinori Sato <ysato@users.sourceforge.jp> 19-May-2004.
25 * added Renesas H8/300 support.
26 *
27 * Paul Mundt <lethal@linux-sh.org> 08-Aug-2003.
28 * Integrated support for sh64 (SH-5), from preliminary modutils
29 * patches from Benedict Gaster <benedict.gaster@superh.com>.
30 * Currently limited to support for 32bit ABI.
31 *
32 * Magnus Damm <damm@opensource.se> 22-May-2002.
33 * The plt and got code are now using the same structs.
34 * Added generic linked list code to fully support PowerPC.
35 * Replaced the mess in arch_apply_relocation() with architecture blocks.
36 * The arch_create_got() function got cleaned up with architecture blocks.
37 * These blocks should be easy maintain and sync with obj_xxx.c in modutils.
38 *
39 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
40 * PowerPC specific code stolen from modutils-2.3.16,
41 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
42 * I've only tested the code on mpc8xx platforms in big-endian mode.
43 * Did some cleanup and added USE_xxx_ENTRIES...
44 *
45 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
46 * based on modutils-2.4.2
47 * MIPS specific support for Elf loading and relocation.
48 * Copyright 1996, 1997 Linux International.
49 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
50 *
51 * Based almost entirely on the Linux modutils-2.3.11 implementation.
52 * Copyright 1996, 1997 Linux International.
53 * New implementation contributed by Richard Henderson <rth@tamu.edu>
54 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
55 * Restructured (and partly rewritten) by:
56 * Björn Ekwall <bj0rn@blox.se> February 1999
57 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +020058 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Denis Vlasenkoba1315d2008-09-13 14:59:38 +000059 */
60
61#include "libbb.h"
62#include "modutils.h"
63#include <libgen.h>
64#include <sys/utsname.h>
65
66#if ENABLE_FEATURE_INSMOD_LOADINKMEM
67#define LOADBITS 0
68#else
69#define LOADBITS 1
70#endif
71
72/* Alpha */
73#if defined(__alpha__)
74#define MATCH_MACHINE(x) (x == EM_ALPHA)
75#define SHT_RELM SHT_RELA
76#define Elf64_RelM Elf64_Rela
77#define ELFCLASSM ELFCLASS64
78#endif
79
80/* ARM support */
81#if defined(__arm__)
82#define MATCH_MACHINE(x) (x == EM_ARM)
83#define SHT_RELM SHT_REL
84#define Elf32_RelM Elf32_Rel
85#define ELFCLASSM ELFCLASS32
86#define USE_PLT_ENTRIES
87#define PLT_ENTRY_SIZE 8
88#define USE_GOT_ENTRIES
89#define GOT_ENTRY_SIZE 8
90#define USE_SINGLE
91#endif
92
Macpaul Lin58662f22010-08-05 13:14:05 +080093/* NDS32 support */
94#if defined(__nds32__) || defined(__NDS32__)
95#define CONFIG_USE_GOT_ENTRIES
96#define CONFIG_GOT_ENTRY_SIZE 4
97#define CONFIG_USE_SINGLE
98
99#if defined(__NDS32_EB__)
100#define MATCH_MACHINE(x) (x == EM_NDS32)
101#define SHT_RELM SHT_RELA
102#define Elf32_RelM Elf32_Rela
103#define ELFCLASSM ELFCLASS32
104#endif
105
106#if defined(__NDS32_EL__)
107#define MATCH_MACHINE(x) (x == EM_NDS32)
108#define SHT_RELM SHT_RELA
109#define Elf32_RelM Elf32_Rela
110#define ELFCLASSM ELFCLASS32
111#endif
112#endif
113
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000114/* blackfin */
115#if defined(BFIN)
116#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
117#define SHT_RELM SHT_RELA
118#define Elf32_RelM Elf32_Rela
119#define ELFCLASSM ELFCLASS32
120#endif
121
122/* CRIS */
123#if defined(__cris__)
124#define MATCH_MACHINE(x) (x == EM_CRIS)
125#define SHT_RELM SHT_RELA
126#define Elf32_RelM Elf32_Rela
127#define ELFCLASSM ELFCLASS32
128#ifndef EM_CRIS
129#define EM_CRIS 76
130#define R_CRIS_NONE 0
131#define R_CRIS_32 3
132#endif
133#endif
134
135/* H8/300 */
136#if defined(__H8300H__) || defined(__H8300S__)
137#define MATCH_MACHINE(x) (x == EM_H8_300)
138#define SHT_RELM SHT_RELA
139#define Elf32_RelM Elf32_Rela
140#define ELFCLASSM ELFCLASS32
141#define USE_SINGLE
142#define SYMBOL_PREFIX "_"
143#endif
144
145/* PA-RISC / HP-PA */
146#if defined(__hppa__)
147#define MATCH_MACHINE(x) (x == EM_PARISC)
148#define SHT_RELM SHT_RELA
149#if defined(__LP64__)
150#define Elf64_RelM Elf64_Rela
151#define ELFCLASSM ELFCLASS64
152#else
153#define Elf32_RelM Elf32_Rela
154#define ELFCLASSM ELFCLASS32
155#endif
156#endif
157
158/* x86 */
159#if defined(__i386__)
160#ifndef EM_486
161#define MATCH_MACHINE(x) (x == EM_386)
162#else
163#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
164#endif
165#define SHT_RELM SHT_REL
166#define Elf32_RelM Elf32_Rel
167#define ELFCLASSM ELFCLASS32
168#define USE_GOT_ENTRIES
169#define GOT_ENTRY_SIZE 4
170#define USE_SINGLE
171#endif
172
173/* IA64, aka Itanium */
174#if defined(__ia64__)
175#define MATCH_MACHINE(x) (x == EM_IA_64)
176#define SHT_RELM SHT_RELA
177#define Elf64_RelM Elf64_Rela
178#define ELFCLASSM ELFCLASS64
179#endif
180
181/* m68k */
182#if defined(__mc68000__)
183#define MATCH_MACHINE(x) (x == EM_68K)
184#define SHT_RELM SHT_RELA
185#define Elf32_RelM Elf32_Rela
186#define ELFCLASSM ELFCLASS32
187#define USE_GOT_ENTRIES
188#define GOT_ENTRY_SIZE 4
189#define USE_SINGLE
190#endif
191
192/* Microblaze */
193#if defined(__microblaze__)
194#define USE_SINGLE
195#include <linux/elf-em.h>
196#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
197#define SHT_RELM SHT_RELA
198#define Elf32_RelM Elf32_Rela
199#define ELFCLASSM ELFCLASS32
200#endif
201
202/* MIPS */
203#if defined(__mips__)
204#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
205#define SHT_RELM SHT_REL
206#define Elf32_RelM Elf32_Rel
207#define ELFCLASSM ELFCLASS32
208/* Account for ELF spec changes. */
209#ifndef EM_MIPS_RS3_LE
210#ifdef EM_MIPS_RS4_BE
211#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
212#else
213#define EM_MIPS_RS3_LE 10
214#endif
215#endif /* !EM_MIPS_RS3_LE */
216#define ARCHDATAM "__dbe_table"
217#endif
218
219/* Nios II */
220#if defined(__nios2__)
221#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
222#define SHT_RELM SHT_RELA
223#define Elf32_RelM Elf32_Rela
224#define ELFCLASSM ELFCLASS32
225#endif
226
227/* PowerPC */
228#if defined(__powerpc64__)
229#define MATCH_MACHINE(x) (x == EM_PPC64)
230#define SHT_RELM SHT_RELA
231#define Elf64_RelM Elf64_Rela
232#define ELFCLASSM ELFCLASS64
233#elif defined(__powerpc__)
234#define MATCH_MACHINE(x) (x == EM_PPC)
235#define SHT_RELM SHT_RELA
236#define Elf32_RelM Elf32_Rela
237#define ELFCLASSM ELFCLASS32
238#define USE_PLT_ENTRIES
239#define PLT_ENTRY_SIZE 16
240#define USE_PLT_LIST
241#define LIST_ARCHTYPE ElfW(Addr)
242#define USE_LIST
243#define ARCHDATAM "__ftr_fixup"
244#endif
245
246/* S390 */
247#if defined(__s390__)
248#define MATCH_MACHINE(x) (x == EM_S390)
249#define SHT_RELM SHT_RELA
250#define Elf32_RelM Elf32_Rela
251#define ELFCLASSM ELFCLASS32
252#define USE_PLT_ENTRIES
253#define PLT_ENTRY_SIZE 8
254#define USE_GOT_ENTRIES
255#define GOT_ENTRY_SIZE 8
256#define USE_SINGLE
257#endif
258
259/* SuperH */
260#if defined(__sh__)
261#define MATCH_MACHINE(x) (x == EM_SH)
262#define SHT_RELM SHT_RELA
263#define Elf32_RelM Elf32_Rela
264#define ELFCLASSM ELFCLASS32
265#define USE_GOT_ENTRIES
266#define GOT_ENTRY_SIZE 4
267#define USE_SINGLE
268/* the SH changes have only been tested in =little endian= mode */
269/* I'm not sure about big endian, so let's warn: */
270#if defined(__sh__) && BB_BIG_ENDIAN
271# error insmod.c may require changes for use on big endian SH
272#endif
273/* it may or may not work on the SH1/SH2... Error on those also */
274#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
275#error insmod.c may require changes for SH1 or SH2 use
276#endif
277#endif
278
279/* Sparc */
280#if defined(__sparc__)
281#define MATCH_MACHINE(x) (x == EM_SPARC)
282#define SHT_RELM SHT_RELA
283#define Elf32_RelM Elf32_Rela
284#define ELFCLASSM ELFCLASS32
285#endif
286
287/* v850e */
288#if defined(__v850e__)
289#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
290#define SHT_RELM SHT_RELA
291#define Elf32_RelM Elf32_Rela
292#define ELFCLASSM ELFCLASS32
293#define USE_PLT_ENTRIES
294#define PLT_ENTRY_SIZE 8
295#define USE_SINGLE
296#ifndef EM_CYGNUS_V850 /* grumble */
297#define EM_CYGNUS_V850 0x9080
298#endif
299#define SYMBOL_PREFIX "_"
300#endif
301
302/* X86_64 */
303#if defined(__x86_64__)
304#define MATCH_MACHINE(x) (x == EM_X86_64)
305#define SHT_RELM SHT_RELA
306#define USE_GOT_ENTRIES
307#define GOT_ENTRY_SIZE 8
308#define USE_SINGLE
309#define Elf64_RelM Elf64_Rela
310#define ELFCLASSM ELFCLASS64
311#endif
312
313#ifndef SHT_RELM
314#error Sorry, but insmod.c does not yet support this architecture...
315#endif
316
317
318//----------------------------------------------------------------------------
319//--------modutils module.h, lines 45-242
320//----------------------------------------------------------------------------
321
322/* Definitions for the Linux module syscall interface.
323 Copyright 1996, 1997 Linux International.
324
325 Contributed by Richard Henderson <rth@tamu.edu>
326
327 This file is part of the Linux modutils.
328
329 This program is free software; you can redistribute it and/or modify it
330 under the terms of the GNU General Public License as published by the
331 Free Software Foundation; either version 2 of the License, or (at your
332 option) any later version.
333
334 This program is distributed in the hope that it will be useful, but
335 WITHOUT ANY WARRANTY; without even the implied warranty of
336 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
337 General Public License for more details.
338
339 You should have received a copy of the GNU General Public License
340 along with this program; if not, write to the Free Software Foundation,
341 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
342
343
344#ifndef MODUTILS_MODULE_H
345
346/*======================================================================*/
347/* For sizeof() which are related to the module platform and not to the
348 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
349
350#define tgt_sizeof_char sizeof(char)
351#define tgt_sizeof_short sizeof(short)
352#define tgt_sizeof_int sizeof(int)
353#define tgt_sizeof_long sizeof(long)
354#define tgt_sizeof_char_p sizeof(char *)
355#define tgt_sizeof_void_p sizeof(void *)
356#define tgt_long long
357
358#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
359#undef tgt_sizeof_long
360#undef tgt_sizeof_char_p
361#undef tgt_sizeof_void_p
362#undef tgt_long
363enum {
364 tgt_sizeof_long = 8,
365 tgt_sizeof_char_p = 8,
366 tgt_sizeof_void_p = 8
367};
368#define tgt_long long long
369#endif
370
371/*======================================================================*/
372/* The structures used in Linux 2.1. */
373
374/* Note: new_module_symbol does not use tgt_long intentionally */
375struct new_module_symbol {
376 unsigned long value;
377 unsigned long name;
378};
379
380struct new_module_persist;
381
382struct new_module_ref {
383 unsigned tgt_long dep; /* kernel addresses */
384 unsigned tgt_long ref;
385 unsigned tgt_long next_ref;
386};
387
388struct new_module {
389 unsigned tgt_long size_of_struct; /* == sizeof(module) */
390 unsigned tgt_long next;
391 unsigned tgt_long name;
392 unsigned tgt_long size;
393
394 tgt_long usecount;
395 unsigned tgt_long flags; /* AUTOCLEAN et al */
396
397 unsigned nsyms;
398 unsigned ndeps;
399
400 unsigned tgt_long syms;
401 unsigned tgt_long deps;
402 unsigned tgt_long refs;
403 unsigned tgt_long init;
404 unsigned tgt_long cleanup;
405 unsigned tgt_long ex_table_start;
406 unsigned tgt_long ex_table_end;
407#ifdef __alpha__
408 unsigned tgt_long gp;
409#endif
410 /* Everything after here is extension. */
411 unsigned tgt_long persist_start;
412 unsigned tgt_long persist_end;
413 unsigned tgt_long can_unload;
414 unsigned tgt_long runsize;
415 const char *kallsyms_start; /* All symbols for kernel debugging */
416 const char *kallsyms_end;
417 const char *archdata_start; /* arch specific data for module */
418 const char *archdata_end;
419 const char *kernel_data; /* Reserved for kernel internal use */
420};
421
422#ifdef ARCHDATAM
423#define ARCHDATA_SEC_NAME ARCHDATAM
424#else
425#define ARCHDATA_SEC_NAME "__archdata"
426#endif
427#define KALLSYMS_SEC_NAME "__kallsyms"
428
429
430struct new_module_info {
431 unsigned long addr;
432 unsigned long size;
433 unsigned long flags;
434 long usecount;
435};
436
437/* Bits of module.flags. */
438enum {
439 NEW_MOD_RUNNING = 1,
440 NEW_MOD_DELETED = 2,
441 NEW_MOD_AUTOCLEAN = 4,
442 NEW_MOD_VISITED = 8,
443 NEW_MOD_USED_ONCE = 16
444};
445
446int init_module(const char *name, const struct new_module *);
447int query_module(const char *name, int which, void *buf,
448 size_t bufsize, size_t *ret);
449
450/* Values for query_module's which. */
451enum {
452 QM_MODULES = 1,
453 QM_DEPS = 2,
454 QM_REFS = 3,
455 QM_SYMBOLS = 4,
456 QM_INFO = 5
457};
458
459/*======================================================================*/
460/* The system calls unchanged between 2.0 and 2.1. */
461
462unsigned long create_module(const char *, size_t);
463int delete_module(const char *module, unsigned int flags);
464
465
466#endif /* module.h */
467
468//----------------------------------------------------------------------------
469//--------end of modutils module.h
470//----------------------------------------------------------------------------
471
472
473
474//----------------------------------------------------------------------------
475//--------modutils obj.h, lines 253-462
476//----------------------------------------------------------------------------
477
478/* Elf object file loading and relocation routines.
479 Copyright 1996, 1997 Linux International.
480
481 Contributed by Richard Henderson <rth@tamu.edu>
482
483 This file is part of the Linux modutils.
484
485 This program is free software; you can redistribute it and/or modify it
486 under the terms of the GNU General Public License as published by the
487 Free Software Foundation; either version 2 of the License, or (at your
488 option) any later version.
489
490 This program is distributed in the hope that it will be useful, but
491 WITHOUT ANY WARRANTY; without even the implied warranty of
492 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
493 General Public License for more details.
494
495 You should have received a copy of the GNU General Public License
496 along with this program; if not, write to the Free Software Foundation,
497 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
498
499
500#ifndef MODUTILS_OBJ_H
501
502/* The relocatable object is manipulated using elfin types. */
503
504#include <elf.h>
505#include <endian.h>
506
507#ifndef ElfW
508# if ELFCLASSM == ELFCLASS32
509# define ElfW(x) Elf32_ ## x
510# define ELFW(x) ELF32_ ## x
511# else
512# define ElfW(x) Elf64_ ## x
513# define ELFW(x) ELF64_ ## x
514# endif
515#endif
516
517/* For some reason this is missing from some ancient C libraries.... */
518#ifndef ELF32_ST_INFO
519# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
520#endif
521
522#ifndef ELF64_ST_INFO
523# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
524#endif
525
526#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
527#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
528#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
529#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
530#define ELF_R_SYM(val) ELFW(R_SYM)(val)
531
532struct obj_string_patch;
533struct obj_symbol_patch;
534
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200535struct obj_section {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000536 ElfW(Shdr) header;
537 const char *name;
538 char *contents;
539 struct obj_section *load_next;
540 int idx;
541};
542
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200543struct obj_symbol {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000544 struct obj_symbol *next; /* hash table link */
545 const char *name;
546 unsigned long value;
547 unsigned long size;
548 int secidx; /* the defining section index/module */
549 int info;
550 int ksymidx; /* for export to the kernel symtab */
551 int referenced; /* actually used in the link */
552};
553
554/* Hardcode the hash table size. We shouldn't be needing so many
555 symbols that we begin to degrade performance, and we get a big win
556 by giving the compiler a constant divisor. */
557
558#define HASH_BUCKETS 521
559
560struct obj_file {
561 ElfW(Ehdr) header;
562 ElfW(Addr) baseaddr;
563 struct obj_section **sections;
564 struct obj_section *load_order;
565 struct obj_section **load_order_search_start;
566 struct obj_string_patch *string_patches;
567 struct obj_symbol_patch *symbol_patches;
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200568 int (*symbol_cmp)(const char *, const char *); /* cant be FAST_FUNC */
569 unsigned long (*symbol_hash)(const char *) FAST_FUNC;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000570 unsigned long local_symtab_size;
571 struct obj_symbol **local_symtab;
572 struct obj_symbol *symtab[HASH_BUCKETS];
573};
574
575enum obj_reloc {
576 obj_reloc_ok,
577 obj_reloc_overflow,
578 obj_reloc_dangerous,
579 obj_reloc_unhandled
580};
581
582struct obj_string_patch {
583 struct obj_string_patch *next;
584 int reloc_secidx;
585 ElfW(Addr) reloc_offset;
586 ElfW(Addr) string_offset;
587};
588
589struct obj_symbol_patch {
590 struct obj_symbol_patch *next;
591 int reloc_secidx;
592 ElfW(Addr) reloc_offset;
593 struct obj_symbol *sym;
594};
595
596
597/* Generic object manipulation routines. */
598
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200599static unsigned long FAST_FUNC obj_elf_hash(const char *);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000600
601static unsigned long obj_elf_hash_n(const char *, unsigned long len);
602
603static struct obj_symbol *obj_find_symbol(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200604 const char *name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000605
606static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200607 struct obj_symbol *sym);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000608
609#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
610static void obj_set_symbol_compare(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200611 int (*cmp)(const char *, const char *),
612 unsigned long (*hash)(const char *) FAST_FUNC);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000613#endif
614
615static struct obj_section *obj_find_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200616 const char *name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000617
618static void obj_insert_section_load_order(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200619 struct obj_section *sec);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000620
621static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200622 const char *name,
623 unsigned long align,
624 unsigned long size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000625
626static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200627 const char *name,
628 unsigned long align,
629 unsigned long size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000630
631static void *obj_extend_section(struct obj_section *sec, unsigned long more);
632
633static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200634 const char *string);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000635
636static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200637 struct obj_symbol *sym);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000638
639static void obj_check_undefineds(struct obj_file *f);
640
641static void obj_allocate_commons(struct obj_file *f);
642
643static unsigned long obj_load_size(struct obj_file *f);
644
645static int obj_relocate(struct obj_file *f, ElfW(Addr) base);
646
Denis Vlasenkof4393042009-04-05 23:25:09 +0000647#if !LOADBITS
648#define obj_load(image, image_size, loadprogbits) \
649 obj_load(image, image_size)
650#endif
651static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000652
653static int obj_create_image(struct obj_file *f, char *image);
654
655/* Architecture specific manipulation routines. */
656
657static struct obj_file *arch_new_file(void);
658
659static struct obj_section *arch_new_section(void);
660
661static struct obj_symbol *arch_new_symbol(void);
662
663static enum obj_reloc arch_apply_relocation(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200664 struct obj_section *targsec,
665 /*struct obj_section *symsec,*/
666 struct obj_symbol *sym,
667 ElfW(RelM) *rel, ElfW(Addr) value);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000668
669static void arch_create_got(struct obj_file *f);
670#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
671static int obj_gpl_license(struct obj_file *f, const char **license);
Denis Vlasenkoe35af562009-01-31 14:22:24 +0000672#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000673#endif /* obj.h */
674//----------------------------------------------------------------------------
675//--------end of modutils obj.h
676//----------------------------------------------------------------------------
677
678
679/* SPFX is always a string, so it can be concatenated to string constants. */
680#ifdef SYMBOL_PREFIX
681#define SPFX SYMBOL_PREFIX
682#else
683#define SPFX ""
684#endif
685
686enum { STRVERSIONLEN = 64 };
687
688/*======================================================================*/
689
690#define flag_force_load (option_mask32 & INSMOD_OPT_FORCE)
691#define flag_autoclean (option_mask32 & INSMOD_OPT_KERNELD)
692#define flag_verbose (option_mask32 & INSMOD_OPT_VERBOSE)
693#define flag_quiet (option_mask32 & INSMOD_OPT_SILENT)
694#define flag_noexport (option_mask32 & INSMOD_OPT_NO_EXPORT)
695#define flag_print_load_map (option_mask32 & INSMOD_OPT_PRINT_MAP)
696
697/*======================================================================*/
698
699#if defined(USE_LIST)
700
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200701struct arch_list_entry {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000702 struct arch_list_entry *next;
703 LIST_ARCHTYPE addend;
704 int offset;
705 int inited : 1;
706};
707
708#endif
709
710#if defined(USE_SINGLE)
711
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200712struct arch_single_entry {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000713 int offset;
714 int inited : 1;
715 int allocated : 1;
716};
717
718#endif
719
720#if defined(__mips__)
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200721struct mips_hi16 {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000722 struct mips_hi16 *next;
723 ElfW(Addr) *addr;
724 ElfW(Addr) value;
725};
726#endif
727
728struct arch_file {
729 struct obj_file root;
730#if defined(USE_PLT_ENTRIES)
731 struct obj_section *plt;
732#endif
733#if defined(USE_GOT_ENTRIES)
734 struct obj_section *got;
735#endif
736#if defined(__mips__)
737 struct mips_hi16 *mips_hi16_list;
738#endif
739};
740
741struct arch_symbol {
742 struct obj_symbol root;
743#if defined(USE_PLT_ENTRIES)
744#if defined(USE_PLT_LIST)
745 struct arch_list_entry *pltent;
746#else
747 struct arch_single_entry pltent;
748#endif
749#endif
750#if defined(USE_GOT_ENTRIES)
751 struct arch_single_entry gotent;
752#endif
753};
754
755
756struct external_module {
757 const char *name;
758 ElfW(Addr) addr;
759 int used;
760 size_t nsyms;
761 struct new_module_symbol *syms;
762};
763
764static struct new_module_symbol *ksyms;
765static size_t nksyms;
766
767static struct external_module *ext_modules;
768static int n_ext_modules;
769static int n_ext_modules_used;
770
771/*======================================================================*/
772
773
774static struct obj_file *arch_new_file(void)
775{
776 struct arch_file *f;
777 f = xzalloc(sizeof(*f));
778 return &f->root; /* it's a first member */
779}
780
781static struct obj_section *arch_new_section(void)
782{
783 return xzalloc(sizeof(struct obj_section));
784}
785
786static struct obj_symbol *arch_new_symbol(void)
787{
788 struct arch_symbol *sym;
789 sym = xzalloc(sizeof(*sym));
790 return &sym->root;
791}
792
793static enum obj_reloc
794arch_apply_relocation(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200795 struct obj_section *targsec,
796 /*struct obj_section *symsec,*/
797 struct obj_symbol *sym,
798 ElfW(RelM) *rel, ElfW(Addr) v)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000799{
800#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
801 || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
802 || defined(__powerpc__) || defined(__mips__)
803 struct arch_file *ifile = (struct arch_file *) f;
804#endif
805 enum obj_reloc ret = obj_reloc_ok;
806 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
807#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
808 || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
809 || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
810 || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
811 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
812#endif
813#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
814 struct arch_symbol *isym = (struct arch_symbol *) sym;
815#endif
816#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
817 || defined(__sh__) || defined(__s390__)
818#if defined(USE_GOT_ENTRIES)
819 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
820#endif
821#endif
822#if defined(USE_PLT_ENTRIES)
823 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
824 unsigned long *ip;
825# if defined(USE_PLT_LIST)
826 struct arch_list_entry *pe;
827# else
828 struct arch_single_entry *pe;
829# endif
830#endif
831
832 switch (ELF_R_TYPE(rel->r_info)) {
833
834#if defined(__arm__)
835
836 case R_ARM_NONE:
837 break;
838
839 case R_ARM_ABS32:
840 *loc += v;
841 break;
842
843 case R_ARM_GOT32:
844 goto bb_use_got;
845
846 case R_ARM_GOTPC:
847 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
848 * (which is .got) similar to branch,
849 * but is full 32 bits relative */
850
851 *loc += got - dot;
852 break;
853
854 case R_ARM_PC24:
855 case R_ARM_PLT32:
856 goto bb_use_plt;
857
858 case R_ARM_GOTOFF: /* address relative to the got */
859 *loc += v - got;
860 break;
861
862#elif defined(__cris__)
863
864 case R_CRIS_NONE:
865 break;
866
867 case R_CRIS_32:
868 /* CRIS keeps the relocation value in the r_addend field and
869 * should not use whats in *loc at all
870 */
871 *loc = v;
872 break;
873
874#elif defined(__H8300H__) || defined(__H8300S__)
875
876 case R_H8_DIR24R8:
877 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
878 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
879 break;
880 case R_H8_DIR24A8:
881 *loc += v;
882 break;
883 case R_H8_DIR32:
884 case R_H8_DIR32A16:
885 *loc += v;
886 break;
887 case R_H8_PCREL16:
888 v -= dot + 2;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100889 if ((ElfW(Sword))v > 0x7fff
890 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
891 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000892 ret = obj_reloc_overflow;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100893 } else {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000894 *(unsigned short *)loc = v;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100895 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000896 break;
897 case R_H8_PCREL8:
898 v -= dot + 1;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100899 if ((ElfW(Sword))v > 0x7f
900 || (ElfW(Sword))v < -(ElfW(Sword))0x80
901 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000902 ret = obj_reloc_overflow;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100903 } else {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000904 *(unsigned char *)loc = v;
Denys Vlasenko6b9f1632010-01-28 02:24:24 +0100905 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000906 break;
907
908#elif defined(__i386__)
909
910 case R_386_NONE:
911 break;
912
913 case R_386_32:
914 *loc += v;
915 break;
916
917 case R_386_PLT32:
918 case R_386_PC32:
919 case R_386_GOTOFF:
920 *loc += v - dot;
921 break;
922
923 case R_386_GLOB_DAT:
924 case R_386_JMP_SLOT:
925 *loc = v;
926 break;
927
928 case R_386_RELATIVE:
929 *loc += f->baseaddr;
930 break;
931
932 case R_386_GOTPC:
933 *loc += got - dot;
934 break;
935
936 case R_386_GOT32:
937 goto bb_use_got;
938 break;
939
940#elif defined(__microblaze__)
941 case R_MICROBLAZE_NONE:
942 case R_MICROBLAZE_64_NONE:
943 case R_MICROBLAZE_32_SYM_OP_SYM:
944 case R_MICROBLAZE_32_PCREL:
945 break;
946
947 case R_MICROBLAZE_64_PCREL: {
948 /* dot is the address of the current instruction.
949 * v is the target symbol address.
950 * So we need to extract the offset in the code,
951 * adding v, then subtrating the current address
952 * of this instruction.
953 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
954 */
955
956 /* Get split offset stored in code */
957 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
958 (loc[1] & 0xFFFF);
959
960 /* Adjust relative offset. -4 adjustment required
961 * because dot points to the IMM insn, but branch
962 * is computed relative to the branch instruction itself.
963 */
964 temp += v - dot - 4;
965
966 /* Store back into code */
967 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
968 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
969
970 break;
971 }
972
973 case R_MICROBLAZE_32:
974 *loc += v;
975 break;
976
977 case R_MICROBLAZE_64: {
978 /* Get split pointer stored in code */
979 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
980 (loc[1] & 0xFFFF);
981
982 /* Add reloc offset */
983 temp1+=v;
984
985 /* Store back into code */
986 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
987 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
988
989 break;
990 }
991
992 case R_MICROBLAZE_32_PCREL_LO:
993 case R_MICROBLAZE_32_LO:
994 case R_MICROBLAZE_SRO32:
995 case R_MICROBLAZE_SRW32:
996 ret = obj_reloc_unhandled;
997 break;
998
999#elif defined(__mc68000__)
1000
1001 case R_68K_NONE:
1002 break;
1003
1004 case R_68K_32:
1005 *loc += v;
1006 break;
1007
1008 case R_68K_8:
1009 if (v > 0xff) {
1010 ret = obj_reloc_overflow;
1011 }
1012 *(char *)loc = v;
1013 break;
1014
1015 case R_68K_16:
1016 if (v > 0xffff) {
1017 ret = obj_reloc_overflow;
1018 }
1019 *(short *)loc = v;
1020 break;
1021
1022 case R_68K_PC8:
1023 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001024 if ((ElfW(Sword))v > 0x7f
1025 || (ElfW(Sword))v < -(ElfW(Sword))0x80
1026 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001027 ret = obj_reloc_overflow;
1028 }
1029 *(char *)loc = v;
1030 break;
1031
1032 case R_68K_PC16:
1033 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001034 if ((ElfW(Sword))v > 0x7fff
1035 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
1036 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001037 ret = obj_reloc_overflow;
1038 }
1039 *(short *)loc = v;
1040 break;
1041
1042 case R_68K_PC32:
1043 *(int *)loc = v - dot;
1044 break;
1045
1046 case R_68K_GLOB_DAT:
1047 case R_68K_JMP_SLOT:
1048 *loc = v;
1049 break;
1050
1051 case R_68K_RELATIVE:
1052 *(int *)loc += f->baseaddr;
1053 break;
1054
1055 case R_68K_GOT32:
1056 goto bb_use_got;
1057
1058# ifdef R_68K_GOTOFF
1059 case R_68K_GOTOFF:
1060 *loc += v - got;
1061 break;
1062# endif
1063
1064#elif defined(__mips__)
1065
1066 case R_MIPS_NONE:
1067 break;
1068
1069 case R_MIPS_32:
1070 *loc += v;
1071 break;
1072
1073 case R_MIPS_26:
1074 if (v % 4)
1075 ret = obj_reloc_dangerous;
1076 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1077 ret = obj_reloc_overflow;
1078 *loc =
1079 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1080 0x03ffffff);
1081 break;
1082
1083 case R_MIPS_HI16:
1084 {
1085 struct mips_hi16 *n;
1086
1087 /* We cannot relocate this one now because we don't know the value
1088 of the carry we need to add. Save the information, and let LO16
1089 do the actual relocation. */
1090 n = xmalloc(sizeof *n);
1091 n->addr = loc;
1092 n->value = v;
1093 n->next = ifile->mips_hi16_list;
1094 ifile->mips_hi16_list = n;
1095 break;
1096 }
1097
1098 case R_MIPS_LO16:
1099 {
1100 unsigned long insnlo = *loc;
1101 ElfW(Addr) val, vallo;
1102
1103 /* Sign extend the addend we extract from the lo insn. */
1104 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1105
1106 if (ifile->mips_hi16_list != NULL) {
1107 struct mips_hi16 *l;
1108
1109 l = ifile->mips_hi16_list;
1110 while (l != NULL) {
1111 struct mips_hi16 *next;
1112 unsigned long insn;
1113
1114 /* Do the HI16 relocation. Note that we actually don't
1115 need to know anything about the LO16 itself, except where
1116 to find the low 16 bits of the addend needed by the LO16. */
1117 insn = *l->addr;
1118 val =
1119 ((insn & 0xffff) << 16) +
1120 vallo;
1121 val += v;
1122
1123 /* Account for the sign extension that will happen in the
1124 low bits. */
1125 val =
1126 ((val >> 16) +
1127 ((val & 0x8000) !=
1128 0)) & 0xffff;
1129
1130 insn = (insn & ~0xffff) | val;
1131 *l->addr = insn;
1132
1133 next = l->next;
1134 free(l);
1135 l = next;
1136 }
1137
1138 ifile->mips_hi16_list = NULL;
1139 }
1140
1141 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1142 val = v + vallo;
1143 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1144 *loc = insnlo;
1145 break;
1146 }
1147
1148#elif defined(__nios2__)
1149
1150 case R_NIOS2_NONE:
1151 break;
1152
1153 case R_NIOS2_BFD_RELOC_32:
1154 *loc += v;
1155 break;
1156
1157 case R_NIOS2_BFD_RELOC_16:
1158 if (v > 0xffff) {
1159 ret = obj_reloc_overflow;
1160 }
1161 *(short *)loc = v;
1162 break;
1163
1164 case R_NIOS2_BFD_RELOC_8:
1165 if (v > 0xff) {
1166 ret = obj_reloc_overflow;
1167 }
1168 *(char *)loc = v;
1169 break;
1170
1171 case R_NIOS2_S16:
1172 {
1173 Elf32_Addr word;
1174
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001175 if ((Elf32_Sword)v > 0x7fff
1176 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1177 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001178 ret = obj_reloc_overflow;
1179 }
1180
1181 word = *loc;
1182 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1183 (word & 0x3f);
1184 }
1185 break;
1186
1187 case R_NIOS2_U16:
1188 {
1189 Elf32_Addr word;
1190
1191 if (v > 0xffff) {
1192 ret = obj_reloc_overflow;
1193 }
1194
1195 word = *loc;
1196 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1197 (word & 0x3f);
1198 }
1199 break;
1200
1201 case R_NIOS2_PCREL16:
1202 {
1203 Elf32_Addr word;
1204
1205 v -= dot + 4;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001206 if ((Elf32_Sword)v > 0x7fff
1207 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1208 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001209 ret = obj_reloc_overflow;
1210 }
1211
1212 word = *loc;
1213 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1214 }
1215 break;
1216
1217 case R_NIOS2_GPREL:
1218 {
1219 Elf32_Addr word, gp;
1220 /* get _gp */
1221 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001222 v -= gp;
1223 if ((Elf32_Sword)v > 0x7fff
1224 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1225 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001226 ret = obj_reloc_overflow;
1227 }
1228
1229 word = *loc;
1230 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1231 }
1232 break;
1233
1234 case R_NIOS2_CALL26:
1235 if (v & 3)
1236 ret = obj_reloc_dangerous;
1237 if ((v >> 28) != (dot >> 28))
1238 ret = obj_reloc_overflow;
1239 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1240 break;
1241
1242 case R_NIOS2_IMM5:
1243 {
1244 Elf32_Addr word;
1245
1246 if (v > 0x1f) {
1247 ret = obj_reloc_overflow;
1248 }
1249
1250 word = *loc & ~0x7c0;
1251 *loc = word | ((v & 0x1f) << 6);
1252 }
1253 break;
1254
1255 case R_NIOS2_IMM6:
1256 {
1257 Elf32_Addr word;
1258
1259 if (v > 0x3f) {
1260 ret = obj_reloc_overflow;
1261 }
1262
1263 word = *loc & ~0xfc0;
1264 *loc = word | ((v & 0x3f) << 6);
1265 }
1266 break;
1267
1268 case R_NIOS2_IMM8:
1269 {
1270 Elf32_Addr word;
1271
1272 if (v > 0xff) {
1273 ret = obj_reloc_overflow;
1274 }
1275
1276 word = *loc & ~0x3fc0;
1277 *loc = word | ((v & 0xff) << 6);
1278 }
1279 break;
1280
1281 case R_NIOS2_HI16:
1282 {
1283 Elf32_Addr word;
1284
1285 word = *loc;
1286 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1287 (word & 0x3f);
1288 }
1289 break;
1290
1291 case R_NIOS2_LO16:
1292 {
1293 Elf32_Addr word;
1294
1295 word = *loc;
1296 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1297 (word & 0x3f);
1298 }
1299 break;
1300
1301 case R_NIOS2_HIADJ16:
1302 {
1303 Elf32_Addr word1, word2;
1304
1305 word1 = *loc;
1306 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1307 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1308 (word1 & 0x3f);
1309 }
1310 break;
1311
1312#elif defined(__powerpc64__)
1313 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
1314
1315#elif defined(__powerpc__)
1316
1317 case R_PPC_ADDR16_HA:
1318 *(unsigned short *)loc = (v + 0x8000) >> 16;
1319 break;
1320
1321 case R_PPC_ADDR16_HI:
1322 *(unsigned short *)loc = v >> 16;
1323 break;
1324
1325 case R_PPC_ADDR16_LO:
1326 *(unsigned short *)loc = v;
1327 break;
1328
1329 case R_PPC_REL24:
1330 goto bb_use_plt;
1331
1332 case R_PPC_REL32:
1333 *loc = v - dot;
1334 break;
1335
1336 case R_PPC_ADDR32:
1337 *loc = v;
1338 break;
1339
1340#elif defined(__s390__)
1341
1342 case R_390_32:
1343 *(unsigned int *) loc += v;
1344 break;
1345 case R_390_16:
1346 *(unsigned short *) loc += v;
1347 break;
1348 case R_390_8:
1349 *(unsigned char *) loc += v;
1350 break;
1351
1352 case R_390_PC32:
1353 *(unsigned int *) loc += v - dot;
1354 break;
1355 case R_390_PC16DBL:
1356 *(unsigned short *) loc += (v - dot) >> 1;
1357 break;
1358 case R_390_PC16:
1359 *(unsigned short *) loc += v - dot;
1360 break;
1361
1362 case R_390_PLT32:
1363 case R_390_PLT16DBL:
1364 /* find the plt entry and initialize it. */
1365 pe = (struct arch_single_entry *) &isym->pltent;
1366 if (pe->inited == 0) {
1367 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1368 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1369 ip[1] = 0x100607f1;
1370 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1371 ip[2] = v - 2;
1372 else
1373 ip[2] = v;
1374 pe->inited = 1;
1375 }
1376
1377 /* Insert relative distance to target. */
1378 v = plt + pe->offset - dot;
1379 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1380 *(unsigned int *) loc = (unsigned int) v;
1381 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1382 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1383 break;
1384
1385 case R_390_GLOB_DAT:
1386 case R_390_JMP_SLOT:
1387 *loc = v;
1388 break;
1389
1390 case R_390_RELATIVE:
1391 *loc += f->baseaddr;
1392 break;
1393
1394 case R_390_GOTPC:
1395 *(unsigned long *) loc += got - dot;
1396 break;
1397
1398 case R_390_GOT12:
1399 case R_390_GOT16:
1400 case R_390_GOT32:
1401 if (!isym->gotent.inited)
1402 {
1403 isym->gotent.inited = 1;
1404 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1405 }
1406 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1407 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1408 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1409 *(unsigned short *) loc += isym->gotent.offset;
1410 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1411 *(unsigned int *) loc += isym->gotent.offset;
1412 break;
1413
1414# ifndef R_390_GOTOFF32
1415# define R_390_GOTOFF32 R_390_GOTOFF
1416# endif
1417 case R_390_GOTOFF32:
1418 *loc += v - got;
1419 break;
1420
1421#elif defined(__sh__)
1422
1423 case R_SH_NONE:
1424 break;
1425
1426 case R_SH_DIR32:
1427 *loc += v;
1428 break;
1429
1430 case R_SH_REL32:
1431 *loc += v - dot;
1432 break;
1433
1434 case R_SH_PLT32:
1435 *loc = v - dot;
1436 break;
1437
1438 case R_SH_GLOB_DAT:
1439 case R_SH_JMP_SLOT:
1440 *loc = v;
1441 break;
1442
1443 case R_SH_RELATIVE:
1444 *loc = f->baseaddr + rel->r_addend;
1445 break;
1446
1447 case R_SH_GOTPC:
1448 *loc = got - dot + rel->r_addend;
1449 break;
1450
1451 case R_SH_GOT32:
1452 goto bb_use_got;
1453
1454 case R_SH_GOTOFF:
1455 *loc = v - got;
1456 break;
1457
1458# if defined(__SH5__)
1459 case R_SH_IMM_MEDLOW16:
1460 case R_SH_IMM_LOW16:
1461 {
1462 ElfW(Addr) word;
1463
1464 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1465 v >>= 16;
1466
1467 /*
1468 * movi and shori have the format:
1469 *
1470 * | op | imm | reg | reserved |
1471 * 31..26 25..10 9.. 4 3 .. 0
1472 *
1473 * so we simply mask and or in imm.
1474 */
1475 word = *loc & ~0x3fffc00;
1476 word |= (v & 0xffff) << 10;
1477
1478 *loc = word;
1479
1480 break;
1481 }
1482
1483 case R_SH_IMM_MEDLOW16_PCREL:
1484 case R_SH_IMM_LOW16_PCREL:
1485 {
1486 ElfW(Addr) word;
1487
1488 word = *loc & ~0x3fffc00;
1489
1490 v -= dot;
1491
1492 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1493 v >>= 16;
1494
1495 word |= (v & 0xffff) << 10;
1496
1497 *loc = word;
1498
1499 break;
1500 }
1501# endif /* __SH5__ */
1502
1503#elif defined(__v850e__)
1504
1505 case R_V850_NONE:
1506 break;
1507
1508 case R_V850_32:
1509 /* We write two shorts instead of a long because even
1510 32-bit insns only need half-word alignment, but
1511 32-bit data needs to be long-word aligned. */
1512 v += ((unsigned short *)loc)[0];
1513 v += ((unsigned short *)loc)[1] << 16;
1514 ((unsigned short *)loc)[0] = v & 0xffff;
1515 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1516 break;
1517
1518 case R_V850_22_PCREL:
1519 goto bb_use_plt;
1520
1521#elif defined(__x86_64__)
1522
1523 case R_X86_64_NONE:
1524 break;
1525
1526 case R_X86_64_64:
1527 *loc += v;
1528 break;
1529
1530 case R_X86_64_32:
1531 *(unsigned int *) loc += v;
1532 if (v > 0xffffffff)
1533 {
1534 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1535 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1536 }
1537 break;
1538
1539 case R_X86_64_32S:
1540 *(signed int *) loc += v;
1541 break;
1542
1543 case R_X86_64_16:
1544 *(unsigned short *) loc += v;
1545 break;
1546
1547 case R_X86_64_8:
1548 *(unsigned char *) loc += v;
1549 break;
1550
1551 case R_X86_64_PC32:
1552 *(unsigned int *) loc += v - dot;
1553 break;
1554
1555 case R_X86_64_PC16:
1556 *(unsigned short *) loc += v - dot;
1557 break;
1558
1559 case R_X86_64_PC8:
1560 *(unsigned char *) loc += v - dot;
1561 break;
1562
1563 case R_X86_64_GLOB_DAT:
1564 case R_X86_64_JUMP_SLOT:
1565 *loc = v;
1566 break;
1567
1568 case R_X86_64_RELATIVE:
1569 *loc += f->baseaddr;
1570 break;
1571
1572 case R_X86_64_GOT32:
1573 case R_X86_64_GOTPCREL:
1574 goto bb_use_got;
1575# if 0
1576 if (!isym->gotent.reloc_done)
1577 {
1578 isym->gotent.reloc_done = 1;
1579 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1580 }
1581 /* XXX are these really correct? */
1582 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1583 *(unsigned int *) loc += v + isym->gotent.offset;
1584 else
1585 *loc += isym->gotent.offset;
1586 break;
1587# endif
1588
1589#else
1590# warning "no idea how to handle relocations on your arch"
1591#endif
1592
1593 default:
Denys Vlasenko083e1722010-01-28 12:30:24 +01001594 printf("Warning: unhandled reloc %d\n", (int)ELF_R_TYPE(rel->r_info));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001595 ret = obj_reloc_unhandled;
1596 break;
1597
1598#if defined(USE_PLT_ENTRIES)
1599
1600bb_use_plt:
1601
1602 /* find the plt entry and initialize it if necessary */
1603
1604#if defined(USE_PLT_LIST)
1605 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1606 pe = pe->next;
1607#else
1608 pe = &isym->pltent;
1609#endif
1610
1611 if (! pe->inited) {
1612 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1613
1614 /* generate some machine code */
1615
1616#if defined(__arm__)
1617 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1618 ip[1] = v; /* sym@ */
1619#endif
1620#if defined(__powerpc__)
1621 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1622 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1623 ip[2] = 0x7d6903a6; /* mtctr r11 */
1624 ip[3] = 0x4e800420; /* bctr */
1625#endif
1626#if defined(__v850e__)
1627 /* We have to trash a register, so we assume that any control
1628 transfer more than 21-bits away must be a function call
1629 (so we can use a call-clobbered register). */
1630 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1631 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
1632#endif
1633 pe->inited = 1;
1634 }
1635
1636 /* relative distance to target */
1637 v -= dot;
1638 /* if the target is too far away.... */
1639#if defined(__arm__) || defined(__powerpc__)
1640 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1641#elif defined(__v850e__)
1642 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1643#endif
1644 /* go via the plt */
1645 v = plt + pe->offset - dot;
1646
1647#if defined(__v850e__)
1648 if (v & 1)
1649#else
1650 if (v & 3)
1651#endif
1652 ret = obj_reloc_dangerous;
1653
1654 /* merge the offset into the instruction. */
1655#if defined(__arm__)
1656 /* Convert to words. */
1657 v >>= 2;
1658
1659 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1660#endif
1661#if defined(__powerpc__)
1662 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1663#endif
1664#if defined(__v850e__)
1665 /* We write two shorts instead of a long because even 32-bit insns
1666 only need half-word alignment, but the 32-bit data write needs
1667 to be long-word aligned. */
1668 ((unsigned short *)loc)[0] =
1669 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1670 | ((v >> 16) & 0x3f); /* offs high part */
1671 ((unsigned short *)loc)[1] =
1672 (v & 0xffff); /* offs low part */
1673#endif
1674 break;
1675#endif /* USE_PLT_ENTRIES */
1676
1677#if defined(USE_GOT_ENTRIES)
1678bb_use_got:
1679
1680 /* needs an entry in the .got: set it, once */
1681 if (!isym->gotent.inited) {
1682 isym->gotent.inited = 1;
1683 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1684 }
1685 /* make the reloc with_respect_to_.got */
1686#if defined(__sh__)
1687 *loc += isym->gotent.offset + rel->r_addend;
1688#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1689 *loc += isym->gotent.offset;
1690#endif
1691 break;
1692
1693#endif /* USE_GOT_ENTRIES */
1694 }
1695
1696 return ret;
1697}
1698
1699
1700#if defined(USE_LIST)
1701
1702static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1703 int offset, int size)
1704{
1705 struct arch_list_entry *pe;
1706
1707 for (pe = *list; pe != NULL; pe = pe->next) {
1708 if (pe->addend == rel->r_addend) {
1709 break;
1710 }
1711 }
1712
1713 if (pe == NULL) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001714 pe = xzalloc(sizeof(struct arch_list_entry));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001715 pe->next = *list;
1716 pe->addend = rel->r_addend;
1717 pe->offset = offset;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001718 /*pe->inited = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001719 *list = pe;
1720 return size;
1721 }
1722 return 0;
1723}
1724
1725#endif
1726
1727#if defined(USE_SINGLE)
1728
1729static int arch_single_init(/*ElfW(RelM) *rel,*/ struct arch_single_entry *single,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001730 int offset, int size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001731{
1732 if (single->allocated == 0) {
1733 single->allocated = 1;
1734 single->offset = offset;
1735 single->inited = 0;
1736 return size;
1737 }
1738 return 0;
1739}
1740
1741#endif
1742
1743#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1744
1745static struct obj_section *arch_xsect_init(struct obj_file *f, const char *name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001746 int offset, int size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001747{
1748 struct obj_section *myrelsec = obj_find_section(f, name);
1749
1750 if (offset == 0) {
1751 offset += size;
1752 }
1753
1754 if (myrelsec) {
1755 obj_extend_section(myrelsec, offset);
1756 } else {
1757 myrelsec = obj_create_alloced_section(f, name,
1758 size, offset);
1759 }
1760
1761 return myrelsec;
1762}
1763
1764#endif
1765
1766static void arch_create_got(struct obj_file *f)
1767{
1768#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1769 struct arch_file *ifile = (struct arch_file *) f;
1770 int i;
1771#if defined(USE_GOT_ENTRIES)
1772 int got_offset = 0, got_needed = 0, got_allocate;
1773#endif
1774#if defined(USE_PLT_ENTRIES)
1775 int plt_offset = 0, plt_needed = 0, plt_allocate;
1776#endif
1777 struct obj_section *relsec, *symsec, *strsec;
1778 ElfW(RelM) *rel, *relend;
1779 ElfW(Sym) *symtab, *extsym;
1780 const char *strtab, *name;
1781 struct arch_symbol *intsym;
1782
1783 for (i = 0; i < f->header.e_shnum; ++i) {
1784 relsec = f->sections[i];
1785 if (relsec->header.sh_type != SHT_RELM)
1786 continue;
1787
1788 symsec = f->sections[relsec->header.sh_link];
1789 strsec = f->sections[symsec->header.sh_link];
1790
1791 rel = (ElfW(RelM) *) relsec->contents;
1792 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1793 symtab = (ElfW(Sym) *) symsec->contents;
1794 strtab = (const char *) strsec->contents;
1795
1796 for (; rel < relend; ++rel) {
1797 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1798
1799#if defined(USE_GOT_ENTRIES)
1800 got_allocate = 0;
1801#endif
1802#if defined(USE_PLT_ENTRIES)
1803 plt_allocate = 0;
1804#endif
1805
1806 switch (ELF_R_TYPE(rel->r_info)) {
1807#if defined(__arm__)
1808 case R_ARM_PC24:
1809 case R_ARM_PLT32:
1810 plt_allocate = 1;
1811 break;
1812
1813 case R_ARM_GOTOFF:
1814 case R_ARM_GOTPC:
1815 got_needed = 1;
1816 continue;
1817
1818 case R_ARM_GOT32:
1819 got_allocate = 1;
1820 break;
1821
1822#elif defined(__i386__)
1823 case R_386_GOTPC:
1824 case R_386_GOTOFF:
1825 got_needed = 1;
1826 continue;
1827
1828 case R_386_GOT32:
1829 got_allocate = 1;
1830 break;
1831
1832#elif defined(__powerpc__)
1833 case R_PPC_REL24:
1834 plt_allocate = 1;
1835 break;
1836
1837#elif defined(__mc68000__)
1838 case R_68K_GOT32:
1839 got_allocate = 1;
1840 break;
1841
1842#ifdef R_68K_GOTOFF
1843 case R_68K_GOTOFF:
1844 got_needed = 1;
1845 continue;
1846#endif
1847
1848#elif defined(__sh__)
1849 case R_SH_GOT32:
1850 got_allocate = 1;
1851 break;
1852
1853 case R_SH_GOTPC:
1854 case R_SH_GOTOFF:
1855 got_needed = 1;
1856 continue;
1857
1858#elif defined(__v850e__)
1859 case R_V850_22_PCREL:
1860 plt_needed = 1;
1861 break;
1862
1863#endif
1864 default:
1865 continue;
1866 }
1867
1868 if (extsym->st_name != 0) {
1869 name = strtab + extsym->st_name;
1870 } else {
1871 name = f->sections[extsym->st_shndx]->name;
1872 }
1873 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1874#if defined(USE_GOT_ENTRIES)
1875 if (got_allocate) {
1876 got_offset += arch_single_init(
1877 /*rel,*/ &intsym->gotent,
1878 got_offset, GOT_ENTRY_SIZE);
1879
1880 got_needed = 1;
1881 }
1882#endif
1883#if defined(USE_PLT_ENTRIES)
1884 if (plt_allocate) {
1885#if defined(USE_PLT_LIST)
1886 plt_offset += arch_list_add(
1887 rel, &intsym->pltent,
1888 plt_offset, PLT_ENTRY_SIZE);
1889#else
1890 plt_offset += arch_single_init(
1891 /*rel,*/ &intsym->pltent,
1892 plt_offset, PLT_ENTRY_SIZE);
1893#endif
1894 plt_needed = 1;
1895 }
1896#endif
1897 }
1898 }
1899
1900#if defined(USE_GOT_ENTRIES)
1901 if (got_needed) {
1902 ifile->got = arch_xsect_init(f, ".got", got_offset,
1903 GOT_ENTRY_SIZE);
1904 }
1905#endif
1906
1907#if defined(USE_PLT_ENTRIES)
1908 if (plt_needed) {
1909 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1910 PLT_ENTRY_SIZE);
1911 }
1912#endif
1913
1914#endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */
1915}
1916
1917/*======================================================================*/
1918
1919/* Standard ELF hash function. */
1920static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1921{
1922 unsigned long h = 0;
1923 unsigned long g;
1924 unsigned char ch;
1925
1926 while (n > 0) {
1927 ch = *name++;
1928 h = (h << 4) + ch;
1929 g = (h & 0xf0000000);
1930 if (g != 0) {
1931 h ^= g >> 24;
1932 h &= ~g;
1933 }
1934 n--;
1935 }
1936 return h;
1937}
1938
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001939static unsigned long FAST_FUNC obj_elf_hash(const char *name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001940{
1941 return obj_elf_hash_n(name, strlen(name));
1942}
1943
1944#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
1945/* String comparison for non-co-versioned kernel and module. */
1946
1947static int ncv_strcmp(const char *a, const char *b)
1948{
1949 size_t alen = strlen(a), blen = strlen(b);
1950
1951 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1952 return strncmp(a, b, alen);
1953 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1954 return strncmp(a, b, blen);
1955 else
1956 return strcmp(a, b);
1957}
1958
1959/* String hashing for non-co-versioned kernel and module. Here
1960 we are simply forced to drop the crc from the hash. */
1961
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001962static unsigned long FAST_FUNC ncv_symbol_hash(const char *str)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001963{
1964 size_t len = strlen(str);
1965 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1966 len -= 10;
1967 return obj_elf_hash_n(str, len);
1968}
1969
1970static void
1971obj_set_symbol_compare(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001972 int (*cmp) (const char *, const char *),
1973 unsigned long (*hash) (const char *) FAST_FUNC)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001974{
1975 if (cmp)
1976 f->symbol_cmp = cmp;
1977 if (hash) {
1978 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1979 int i;
1980
1981 f->symbol_hash = hash;
1982
1983 memcpy(tmptab, f->symtab, sizeof(tmptab));
1984 memset(f->symtab, 0, sizeof(f->symtab));
1985
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001986 for (i = 0; i < HASH_BUCKETS; ++i) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001987 for (sym = tmptab[i]; sym; sym = next) {
1988 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1989 next = sym->next;
1990 sym->next = f->symtab[h];
1991 f->symtab[h] = sym;
1992 }
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001993 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001994 }
1995}
1996
1997#endif /* FEATURE_INSMOD_VERSION_CHECKING */
1998
1999static struct obj_symbol *
2000obj_add_symbol(struct obj_file *f, const char *name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002001 unsigned long symidx, int info,
2002 int secidx, ElfW(Addr) value,
2003 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002004{
2005 struct obj_symbol *sym;
2006 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2007 int n_type = ELF_ST_TYPE(info);
2008 int n_binding = ELF_ST_BIND(info);
2009
2010 for (sym = f->symtab[hash]; sym; sym = sym->next) {
2011 if (f->symbol_cmp(sym->name, name) == 0) {
2012 int o_secidx = sym->secidx;
2013 int o_info = sym->info;
2014 int o_type = ELF_ST_TYPE(o_info);
2015 int o_binding = ELF_ST_BIND(o_info);
2016
2017 /* A redefinition! Is it legal? */
2018
2019 if (secidx == SHN_UNDEF)
2020 return sym;
2021 else if (o_secidx == SHN_UNDEF)
2022 goto found;
2023 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2024 /* Cope with local and global symbols of the same name
2025 in the same object file, as might have been created
2026 by ld -r. The only reason locals are now seen at this
2027 level at all is so that we can do semi-sensible things
2028 with parameters. */
2029
2030 struct obj_symbol *nsym, **p;
2031
2032 nsym = arch_new_symbol();
2033 nsym->next = sym->next;
2034 nsym->ksymidx = -1;
2035
2036 /* Excise the old (local) symbol from the hash chain. */
2037 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2038 continue;
2039 *p = sym = nsym;
2040 goto found;
2041 } else if (n_binding == STB_LOCAL) {
2042 /* Another symbol of the same name has already been defined.
2043 Just add this to the local table. */
2044 sym = arch_new_symbol();
2045 sym->next = NULL;
2046 sym->ksymidx = -1;
2047 f->local_symtab[symidx] = sym;
2048 goto found;
2049 } else if (n_binding == STB_WEAK)
2050 return sym;
2051 else if (o_binding == STB_WEAK)
2052 goto found;
2053 /* Don't unify COMMON symbols with object types the programmer
2054 doesn't expect. */
2055 else if (secidx == SHN_COMMON
2056 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2057 return sym;
2058 else if (o_secidx == SHN_COMMON
2059 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2060 goto found;
2061 else {
2062 /* Don't report an error if the symbol is coming from
2063 the kernel or some external module. */
2064 if (secidx <= SHN_HIRESERVE)
2065 bb_error_msg("%s multiply defined", name);
2066 return sym;
2067 }
2068 }
2069 }
2070
2071 /* Completely new symbol. */
2072 sym = arch_new_symbol();
2073 sym->next = f->symtab[hash];
2074 f->symtab[hash] = sym;
2075 sym->ksymidx = -1;
2076 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
2077 if (symidx >= f->local_symtab_size)
2078 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2079 name, (long) symidx, (long) f->local_symtab_size);
2080 else
2081 f->local_symtab[symidx] = sym;
2082 }
2083
2084found:
2085 sym->name = name;
2086 sym->value = value;
2087 sym->size = size;
2088 sym->secidx = secidx;
2089 sym->info = info;
2090
2091 return sym;
2092}
2093
2094static struct obj_symbol *
2095obj_find_symbol(struct obj_file *f, const char *name)
2096{
2097 struct obj_symbol *sym;
2098 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2099
2100 for (sym = f->symtab[hash]; sym; sym = sym->next)
2101 if (f->symbol_cmp(sym->name, name) == 0)
2102 return sym;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002103 return NULL;
2104}
2105
2106static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2107{
2108 if (sym) {
2109 if (sym->secidx >= SHN_LORESERVE)
2110 return sym->value;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002111 return sym->value + f->sections[sym->secidx]->header.sh_addr;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002112 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002113 /* As a special case, a NULL sym has value zero. */
2114 return 0;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002115}
2116
2117static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2118{
2119 int i, n = f->header.e_shnum;
2120
2121 for (i = 0; i < n; ++i)
2122 if (strcmp(f->sections[i]->name, name) == 0)
2123 return f->sections[i];
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002124 return NULL;
2125}
2126
2127static int obj_load_order_prio(struct obj_section *a)
2128{
2129 unsigned long af, ac;
2130
2131 af = a->header.sh_flags;
2132
2133 ac = 0;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002134 if (a->name[0] != '.' || strlen(a->name) != 10
2135 || strcmp(a->name + 5, ".init") != 0
2136 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002137 ac |= 32;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002138 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002139 if (af & SHF_ALLOC)
2140 ac |= 16;
2141 if (!(af & SHF_WRITE))
2142 ac |= 8;
2143 if (af & SHF_EXECINSTR)
2144 ac |= 4;
2145 if (a->header.sh_type != SHT_NOBITS)
2146 ac |= 2;
2147
2148 return ac;
2149}
2150
2151static void
2152obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2153{
2154 struct obj_section **p;
2155 int prio = obj_load_order_prio(sec);
2156 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2157 if (obj_load_order_prio(*p) < prio)
2158 break;
2159 sec->load_next = *p;
2160 *p = sec;
2161}
2162
Denis Vlasenko49325962009-01-31 23:33:54 +00002163static struct obj_section *helper_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002164 const char *name,
2165 unsigned long align,
2166 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002167{
2168 int newidx = f->header.e_shnum++;
2169 struct obj_section *sec;
2170
2171 f->sections = xrealloc_vector(f->sections, 2, newidx);
2172 f->sections[newidx] = sec = arch_new_section();
2173
2174 sec->header.sh_type = SHT_PROGBITS;
2175 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2176 sec->header.sh_size = size;
2177 sec->header.sh_addralign = align;
2178 sec->name = name;
2179 sec->idx = newidx;
2180 if (size)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002181 sec->contents = xzalloc(size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002182
Denis Vlasenko49325962009-01-31 23:33:54 +00002183 return sec;
2184}
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002185
Denis Vlasenko49325962009-01-31 23:33:54 +00002186static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002187 const char *name,
2188 unsigned long align,
2189 unsigned long size)
Denis Vlasenko49325962009-01-31 23:33:54 +00002190{
2191 struct obj_section *sec;
2192
2193 sec = helper_create_alloced_section(f, name, align, size);
2194 obj_insert_section_load_order(f, sec);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002195 return sec;
2196}
2197
2198static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002199 const char *name,
2200 unsigned long align,
2201 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002202{
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002203 struct obj_section *sec;
2204
Denis Vlasenko49325962009-01-31 23:33:54 +00002205 sec = helper_create_alloced_section(f, name, align, size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002206 sec->load_next = f->load_order;
2207 f->load_order = sec;
2208 if (f->load_order_search_start == &f->load_order)
2209 f->load_order_search_start = &sec->load_next;
2210
2211 return sec;
2212}
2213
2214static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2215{
2216 unsigned long oldsize = sec->header.sh_size;
2217 if (more) {
2218 sec->header.sh_size += more;
2219 sec->contents = xrealloc(sec->contents, sec->header.sh_size);
2220 }
2221 return sec->contents + oldsize;
2222}
2223
2224
2225/* Conditionally add the symbols from the given symbol set to the
2226 new module. */
2227
Denis Vlasenko49325962009-01-31 23:33:54 +00002228static int add_symbols_from(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002229 int idx,
2230 struct new_module_symbol *syms,
2231 size_t nsyms)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002232{
2233 struct new_module_symbol *s;
2234 size_t i;
2235 int used = 0;
2236#ifdef SYMBOL_PREFIX
Denis Vlasenko49325962009-01-31 23:33:54 +00002237 char *name_buf = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002238 size_t name_alloced_size = 0;
2239#endif
2240#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2241 int gpl;
2242
2243 gpl = obj_gpl_license(f, NULL) == 0;
2244#endif
2245 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2246 /* Only add symbols that are already marked external.
2247 If we override locals we may cause problems for
2248 argument initialization. We will also create a false
2249 dependency on the module. */
2250 struct obj_symbol *sym;
2251 char *name;
2252
2253 /* GPL licensed modules can use symbols exported with
2254 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2255 * exported names. Non-GPL modules never see any GPLONLY_
2256 * symbols so they cannot fudge it by adding the prefix on
2257 * their references.
2258 */
2259 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2260#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2261 if (gpl)
2262 s->name += 8;
2263 else
2264#endif
2265 continue;
2266 }
2267 name = (char *)s->name;
2268
2269#ifdef SYMBOL_PREFIX
2270 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2271 kernel exports `C names', but module object files
2272 reference `linker names'). */
2273 size_t extra = sizeof SYMBOL_PREFIX;
2274 size_t name_size = strlen(name) + extra;
2275 if (name_size > name_alloced_size) {
2276 name_alloced_size = name_size * 2;
2277 name_buf = alloca(name_alloced_size);
2278 }
2279 strcpy(name_buf, SYMBOL_PREFIX);
2280 strcpy(name_buf + extra - 1, name);
2281 name = name_buf;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002282#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002283
2284 sym = obj_find_symbol(f, name);
2285 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2286#ifdef SYMBOL_PREFIX
2287 /* Put NAME_BUF into more permanent storage. */
2288 name = xmalloc(name_size);
2289 strcpy(name, name_buf);
2290#endif
2291 sym = obj_add_symbol(f, name, -1,
2292 ELF_ST_INFO(STB_GLOBAL,
2293 STT_NOTYPE),
2294 idx, s->value, 0);
2295 /* Did our symbol just get installed? If so, mark the
2296 module as "used". */
2297 if (sym->secidx == idx)
2298 used = 1;
2299 }
2300 }
2301
2302 return used;
2303}
2304
2305static void add_kernel_symbols(struct obj_file *f)
2306{
2307 struct external_module *m;
2308 int i, nused = 0;
2309
2310 /* Add module symbols first. */
2311
2312 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) {
2313 if (m->nsyms
2314 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms)
2315 ) {
2316 m->used = 1;
2317 ++nused;
2318 }
2319 }
2320
2321 n_ext_modules_used = nused;
2322
2323 /* And finally the symbols from the kernel proper. */
2324
2325 if (nksyms)
2326 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2327}
2328
2329static char *get_modinfo_value(struct obj_file *f, const char *key)
2330{
2331 struct obj_section *sec;
2332 char *p, *v, *n, *ep;
2333 size_t klen = strlen(key);
2334
2335 sec = obj_find_section(f, ".modinfo");
2336 if (sec == NULL)
2337 return NULL;
2338 p = sec->contents;
2339 ep = p + sec->header.sh_size;
2340 while (p < ep) {
2341 v = strchr(p, '=');
2342 n = strchr(p, '\0');
2343 if (v) {
2344 if (p + klen == v && strncmp(p, key, klen) == 0)
2345 return v + 1;
2346 } else {
2347 if (p + klen == n && strcmp(p, key) == 0)
2348 return n;
2349 }
2350 p = n + 1;
2351 }
2352
2353 return NULL;
2354}
2355
2356
2357/*======================================================================*/
2358/* Functions relating to module loading after 2.1.18. */
2359
2360/* From Linux-2.6 sources */
2361/* You can use " around spaces, but can't escape ". */
2362/* Hyphens and underscores equivalent in parameter names. */
2363static char *next_arg(char *args, char **param, char **val)
2364{
2365 unsigned int i, equals = 0;
2366 int in_quote = 0, quoted = 0;
2367 char *next;
2368
2369 if (*args == '"') {
2370 args++;
2371 in_quote = 1;
2372 quoted = 1;
2373 }
2374
2375 for (i = 0; args[i]; i++) {
2376 if (args[i] == ' ' && !in_quote)
2377 break;
2378 if (equals == 0) {
2379 if (args[i] == '=')
2380 equals = i;
2381 }
2382 if (args[i] == '"')
2383 in_quote = !in_quote;
2384 }
2385
2386 *param = args;
2387 if (!equals)
2388 *val = NULL;
2389 else {
2390 args[equals] = '\0';
2391 *val = args + equals + 1;
2392
2393 /* Don't include quotes in value. */
2394 if (**val == '"') {
2395 (*val)++;
2396 if (args[i-1] == '"')
2397 args[i-1] = '\0';
2398 }
2399 if (quoted && args[i-1] == '"')
2400 args[i-1] = '\0';
2401 }
2402
2403 if (args[i]) {
2404 args[i] = '\0';
2405 next = args + i + 1;
2406 } else
2407 next = args + i;
2408
2409 /* Chew up trailing spaces. */
2410 return skip_whitespace(next);
2411}
2412
2413static void
2414new_process_module_arguments(struct obj_file *f, const char *options)
2415{
2416 char *xoptions, *pos;
2417 char *param, *val;
2418
2419 xoptions = pos = xstrdup(skip_whitespace(options));
2420 while (*pos) {
2421 unsigned long charssize = 0;
2422 char *tmp, *contents, *loc, *pinfo, *p;
2423 struct obj_symbol *sym;
2424 int min, max, n, len;
2425
2426 pos = next_arg(pos, &param, &val);
2427
2428 tmp = xasprintf("parm_%s", param);
2429 pinfo = get_modinfo_value(f, tmp);
2430 free(tmp);
2431 if (pinfo == NULL)
2432 bb_error_msg_and_die("invalid parameter %s", param);
2433
2434#ifdef SYMBOL_PREFIX
2435 tmp = xasprintf(SYMBOL_PREFIX "%s", param);
2436 sym = obj_find_symbol(f, tmp);
2437 free(tmp);
2438#else
2439 sym = obj_find_symbol(f, param);
2440#endif
2441
2442 /* Also check that the parameter was not resolved from the kernel. */
2443 if (sym == NULL || sym->secidx > SHN_HIRESERVE)
2444 bb_error_msg_and_die("symbol for parameter %s not found", param);
2445
2446 /* Number of parameters */
Denys Vlasenko07cda222011-02-13 04:17:35 +01002447 min = max = 1;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002448 if (isdigit(*pinfo)) {
Denys Vlasenko07cda222011-02-13 04:17:35 +01002449 min = max = strtoul(pinfo, &pinfo, 10);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002450 if (*pinfo == '-')
2451 max = strtoul(pinfo + 1, &pinfo, 10);
Denys Vlasenko07cda222011-02-13 04:17:35 +01002452 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002453
2454 contents = f->sections[sym->secidx]->contents;
2455 loc = contents + sym->value;
2456
2457 if (*pinfo == 'c') {
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002458 if (!isdigit(pinfo[1])) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002459 bb_error_msg_and_die("parameter type 'c' for %s must be followed by"
2460 " the maximum size", param);
2461 }
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002462 charssize = strtoul(pinfo + 1, NULL, 10);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002463 }
2464
2465 if (val == NULL) {
2466 if (*pinfo != 'b')
2467 bb_error_msg_and_die("argument expected for parameter %s", param);
2468 val = (char *) "1";
2469 }
2470
2471 /* Parse parameter values */
2472 n = 0;
2473 p = val;
Denys Vlasenko07cda222011-02-13 04:17:35 +01002474 while (*p) {
2475 char sv_ch;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002476 char *endp;
2477
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002478 if (++n > max)
2479 bb_error_msg_and_die("too many values for %s (max %d)", param, max);
2480
2481 switch (*pinfo) {
2482 case 's':
2483 len = strcspn(p, ",");
Denys Vlasenko07cda222011-02-13 04:17:35 +01002484 sv_ch = p[len];
2485 p[len] = '\0';
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002486 obj_string_patch(f, sym->secidx,
2487 loc - contents, p);
2488 loc += tgt_sizeof_char_p;
2489 p += len;
Denys Vlasenko07cda222011-02-13 04:17:35 +01002490 *p = sv_ch;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002491 break;
2492 case 'c':
2493 len = strcspn(p, ",");
Denys Vlasenko07cda222011-02-13 04:17:35 +01002494 sv_ch = p[len];
2495 p[len] = '\0';
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002496 if (len >= charssize)
2497 bb_error_msg_and_die("string too long for %s (max %ld)", param,
2498 charssize - 1);
2499 strcpy((char *) loc, p);
2500 loc += charssize;
2501 p += len;
Denys Vlasenko07cda222011-02-13 04:17:35 +01002502 *p = sv_ch;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002503 break;
2504 case 'b':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002505 *loc++ = strtoul(p, &endp, 0);
2506 p = endp; /* gcc likes temp var for &endp */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002507 break;
2508 case 'h':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002509 *(short *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002510 loc += tgt_sizeof_short;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002511 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002512 break;
2513 case 'i':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002514 *(int *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002515 loc += tgt_sizeof_int;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002516 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002517 break;
2518 case 'l':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002519 *(long *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002520 loc += tgt_sizeof_long;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002521 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002522 break;
2523 default:
2524 bb_error_msg_and_die("unknown parameter type '%c' for %s",
2525 *pinfo, param);
2526 }
2527
2528 p = skip_whitespace(p);
2529 if (*p != ',')
2530 break;
2531 p = skip_whitespace(p + 1);
2532 }
2533
2534 if (n < min)
2535 bb_error_msg_and_die("parameter %s requires at least %d arguments", param, min);
2536 if (*p != '\0')
2537 bb_error_msg_and_die("invalid argument syntax for %s", param);
2538 }
2539
2540 free(xoptions);
2541}
2542
2543#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
2544static int new_is_module_checksummed(struct obj_file *f)
2545{
2546 const char *p = get_modinfo_value(f, "using_checksums");
2547 if (p)
2548 return xatoi(p);
2549 return 0;
2550}
2551
2552/* Get the module's kernel version in the canonical integer form. */
2553
2554static int
2555new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2556{
2557 char *p, *q;
2558 int a, b, c;
2559
2560 p = get_modinfo_value(f, "kernel_version");
2561 if (p == NULL)
2562 return -1;
2563 safe_strncpy(str, p, STRVERSIONLEN);
2564
2565 a = strtoul(p, &p, 10);
2566 if (*p != '.')
2567 return -1;
2568 b = strtoul(p + 1, &p, 10);
2569 if (*p != '.')
2570 return -1;
2571 c = strtoul(p + 1, &q, 10);
2572 if (p + 1 == q)
2573 return -1;
2574
2575 return a << 16 | b << 8 | c;
2576}
2577
2578#endif /* FEATURE_INSMOD_VERSION_CHECKING */
2579
2580
2581/* Fetch the loaded modules, and all currently exported symbols. */
2582
2583static void new_get_kernel_symbols(void)
2584{
2585 char *module_names, *mn;
2586 struct external_module *modules, *m;
2587 struct new_module_symbol *syms, *s;
2588 size_t ret, bufsize, nmod, nsyms, i, j;
2589
2590 /* Collect the loaded modules. */
2591
2592 bufsize = 256;
2593 module_names = xmalloc(bufsize);
2594
2595 retry_modules_load:
2596 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2597 if (errno == ENOSPC && bufsize < ret) {
2598 bufsize = ret;
2599 module_names = xrealloc(module_names, bufsize);
2600 goto retry_modules_load;
2601 }
2602 bb_perror_msg_and_die("QM_MODULES");
2603 }
2604
2605 n_ext_modules = nmod = ret;
2606
2607 /* Collect the modules' symbols. */
2608
2609 if (nmod) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002610 ext_modules = modules = xzalloc(nmod * sizeof(*modules));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002611 for (i = 0, mn = module_names, m = modules;
2612 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2613 struct new_module_info info;
2614
2615 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2616 if (errno == ENOENT) {
2617 /* The module was removed out from underneath us. */
2618 continue;
2619 }
2620 bb_perror_msg_and_die("query_module: QM_INFO: %s", mn);
2621 }
2622
2623 bufsize = 1024;
2624 syms = xmalloc(bufsize);
2625 retry_mod_sym_load:
2626 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2627 switch (errno) {
2628 case ENOSPC:
2629 bufsize = ret;
2630 syms = xrealloc(syms, bufsize);
2631 goto retry_mod_sym_load;
2632 case ENOENT:
2633 /* The module was removed out from underneath us. */
2634 continue;
2635 default:
2636 bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn);
2637 }
2638 }
2639 nsyms = ret;
2640
2641 m->name = mn;
2642 m->addr = info.addr;
2643 m->nsyms = nsyms;
2644 m->syms = syms;
2645
2646 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2647 s->name += (unsigned long) syms;
2648 }
2649 }
2650 }
2651
2652 /* Collect the kernel's symbols. */
2653
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002654 bufsize = 16 * 1024;
2655 syms = xmalloc(bufsize);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002656 retry_kern_sym_load:
2657 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2658 if (errno == ENOSPC && bufsize < ret) {
2659 bufsize = ret;
2660 syms = xrealloc(syms, bufsize);
2661 goto retry_kern_sym_load;
2662 }
2663 bb_perror_msg_and_die("kernel: QM_SYMBOLS");
2664 }
2665 nksyms = nsyms = ret;
2666 ksyms = syms;
2667
2668 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2669 s->name += (unsigned long) syms;
2670 }
2671}
2672
2673
2674/* Return the kernel symbol checksum version, or zero if not used. */
2675
2676static int new_is_kernel_checksummed(void)
2677{
2678 struct new_module_symbol *s;
2679 size_t i;
2680
2681 /* Using_Versions is not the first symbol, but it should be in there. */
2682
2683 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2684 if (strcmp((char *) s->name, "Using_Versions") == 0)
2685 return s->value;
2686
2687 return 0;
2688}
2689
2690
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002691static void new_create_this_module(struct obj_file *f, const char *m_name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002692{
2693 struct obj_section *sec;
2694
2695 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2696 sizeof(struct new_module));
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002697 /* done by obj_create_alloced_section_first: */
2698 /*memset(sec->contents, 0, sizeof(struct new_module));*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002699
2700 obj_add_symbol(f, SPFX "__this_module", -1,
2701 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2702 sizeof(struct new_module));
2703
2704 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2705 m_name);
2706}
2707
2708#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2709/* add an entry to the __ksymtab section, creating it if necessary */
2710static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2711{
2712 struct obj_section *sec;
2713 ElfW(Addr) ofs;
2714
2715 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2716 * If __ksymtab is defined but not marked alloc, x out the first character
2717 * (no obj_delete routine) and create a new __ksymtab with the correct
2718 * characteristics.
2719 */
2720 sec = obj_find_section(f, "__ksymtab");
2721 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2722 *((char *)(sec->name)) = 'x'; /* override const */
2723 sec = NULL;
2724 }
2725 if (!sec)
2726 sec = obj_create_alloced_section(f, "__ksymtab",
2727 tgt_sizeof_void_p, 0);
2728 if (!sec)
2729 return;
2730 sec->header.sh_flags |= SHF_ALLOC;
2731 /* Empty section might be byte-aligned */
2732 sec->header.sh_addralign = tgt_sizeof_void_p;
2733 ofs = sec->header.sh_size;
2734 obj_symbol_patch(f, sec->idx, ofs, sym);
2735 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2736 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2737}
2738#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
2739
2740static int new_create_module_ksymtab(struct obj_file *f)
2741{
2742 struct obj_section *sec;
2743 int i;
2744
2745 /* We must always add the module references. */
2746
2747 if (n_ext_modules_used) {
2748 struct new_module_ref *dep;
2749 struct obj_symbol *tm;
2750
2751 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2752 (sizeof(struct new_module_ref)
2753 * n_ext_modules_used));
2754 if (!sec)
2755 return 0;
2756
2757 tm = obj_find_symbol(f, SPFX "__this_module");
2758 dep = (struct new_module_ref *) sec->contents;
2759 for (i = 0; i < n_ext_modules; ++i)
2760 if (ext_modules[i].used) {
2761 dep->dep = ext_modules[i].addr;
2762 obj_symbol_patch(f, sec->idx,
2763 (char *) &dep->ref - sec->contents, tm);
2764 dep->next_ref = 0;
2765 ++dep;
2766 }
2767 }
2768
2769 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
2770 size_t nsyms;
2771 int *loaded;
2772
2773 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
2774
2775 /* We don't want to export symbols residing in sections that
2776 aren't loaded. There are a number of these created so that
2777 we make sure certain module options don't appear twice. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002778 i = f->header.e_shnum;
2779 loaded = alloca(sizeof(int) * i);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002780 while (--i >= 0)
2781 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2782
2783 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2784 struct obj_symbol *sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002785 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002786 if (ELF_ST_BIND(sym->info) != STB_LOCAL
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002787 && sym->secidx <= SHN_HIRESERVE
2788 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002789 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002790 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2791
2792 obj_symbol_patch(f, sec->idx, ofs, sym);
2793 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2794 sym->name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002795 nsyms++;
2796 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002797 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002798 }
2799
2800 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2801 }
2802
2803 return 1;
2804}
2805
2806
2807static int
2808new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2809{
2810 struct new_module *module;
2811 struct obj_section *sec;
2812 void *image;
2813 int ret;
2814 tgt_long m_addr;
2815
2816 sec = obj_find_section(f, ".this");
2817 if (!sec || !sec->contents) {
2818 bb_perror_msg_and_die("corrupt module %s?", m_name);
2819 }
2820 module = (struct new_module *) sec->contents;
2821 m_addr = sec->header.sh_addr;
2822
2823 module->size_of_struct = sizeof(*module);
2824 module->size = m_size;
2825 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2826
2827 sec = obj_find_section(f, "__ksymtab");
2828 if (sec && sec->header.sh_size) {
2829 module->syms = sec->header.sh_addr;
2830 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2831 }
2832
2833 if (n_ext_modules_used) {
2834 sec = obj_find_section(f, ".kmodtab");
2835 module->deps = sec->header.sh_addr;
2836 module->ndeps = n_ext_modules_used;
2837 }
2838
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002839 module->init = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2840 module->cleanup = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002841
2842 sec = obj_find_section(f, "__ex_table");
2843 if (sec) {
2844 module->ex_table_start = sec->header.sh_addr;
2845 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2846 }
2847
2848 sec = obj_find_section(f, ".text.init");
2849 if (sec) {
2850 module->runsize = sec->header.sh_addr - m_addr;
2851 }
2852 sec = obj_find_section(f, ".data.init");
2853 if (sec) {
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002854 if (!module->runsize
2855 || module->runsize > sec->header.sh_addr - m_addr
2856 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002857 module->runsize = sec->header.sh_addr - m_addr;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002858 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002859 }
2860 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2861 if (sec && sec->header.sh_size) {
2862 module->archdata_start = (void*)sec->header.sh_addr;
2863 module->archdata_end = module->archdata_start + sec->header.sh_size;
2864 }
2865 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2866 if (sec && sec->header.sh_size) {
2867 module->kallsyms_start = (void*)sec->header.sh_addr;
2868 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2869 }
2870
2871 /* Whew! All of the initialization is complete. Collect the final
2872 module image and give it to the kernel. */
2873
2874 image = xmalloc(m_size);
2875 obj_create_image(f, image);
2876
2877 ret = init_module(m_name, (struct new_module *) image);
2878 if (ret)
2879 bb_perror_msg("init_module: %s", m_name);
2880
2881 free(image);
2882
2883 return ret == 0;
2884}
2885
2886
2887/*======================================================================*/
2888
2889static void
2890obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2891 const char *string)
2892{
2893 struct obj_string_patch *p;
2894 struct obj_section *strsec;
2895 size_t len = strlen(string) + 1;
2896 char *loc;
2897
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002898 p = xzalloc(sizeof(*p));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002899 p->next = f->string_patches;
2900 p->reloc_secidx = secidx;
2901 p->reloc_offset = offset;
2902 f->string_patches = p;
2903
2904 strsec = obj_find_section(f, ".kstrtab");
2905 if (strsec == NULL) {
2906 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002907 /*p->string_offset = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002908 loc = strsec->contents;
2909 } else {
2910 p->string_offset = strsec->header.sh_size;
2911 loc = obj_extend_section(strsec, len);
2912 }
2913 memcpy(loc, string, len);
2914}
2915
2916static void
2917obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002918 struct obj_symbol *sym)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002919{
2920 struct obj_symbol_patch *p;
2921
2922 p = xmalloc(sizeof(*p));
2923 p->next = f->symbol_patches;
2924 p->reloc_secidx = secidx;
2925 p->reloc_offset = offset;
2926 p->sym = sym;
2927 f->symbol_patches = p;
2928}
2929
2930static void obj_check_undefineds(struct obj_file *f)
2931{
2932 unsigned i;
2933
2934 for (i = 0; i < HASH_BUCKETS; ++i) {
2935 struct obj_symbol *sym;
Denis Vlasenko49325962009-01-31 23:33:54 +00002936 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002937 if (sym->secidx == SHN_UNDEF) {
2938 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
2939 sym->secidx = SHN_ABS;
2940 sym->value = 0;
2941 } else {
2942 if (!flag_quiet)
2943 bb_error_msg_and_die("unresolved symbol %s", sym->name);
2944 }
2945 }
Denis Vlasenko49325962009-01-31 23:33:54 +00002946 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002947 }
2948}
2949
2950static void obj_allocate_commons(struct obj_file *f)
2951{
2952 struct common_entry {
2953 struct common_entry *next;
2954 struct obj_symbol *sym;
2955 } *common_head = NULL;
2956
2957 unsigned long i;
2958
2959 for (i = 0; i < HASH_BUCKETS; ++i) {
2960 struct obj_symbol *sym;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002961 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002962 if (sym->secidx == SHN_COMMON) {
2963 /* Collect all COMMON symbols and sort them by size so as to
2964 minimize space wasted by alignment requirements. */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002965 struct common_entry **p, *n;
2966 for (p = &common_head; *p; p = &(*p)->next)
2967 if (sym->size <= (*p)->sym->size)
2968 break;
2969 n = alloca(sizeof(*n));
2970 n->next = *p;
2971 n->sym = sym;
2972 *p = n;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002973 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002974 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002975 }
2976
2977 for (i = 1; i < f->local_symtab_size; ++i) {
2978 struct obj_symbol *sym = f->local_symtab[i];
2979 if (sym && sym->secidx == SHN_COMMON) {
2980 struct common_entry **p, *n;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002981 for (p = &common_head; *p; p = &(*p)->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002982 if (sym == (*p)->sym)
2983 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002984 if (sym->size < (*p)->sym->size) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002985 n = alloca(sizeof(*n));
2986 n->next = *p;
2987 n->sym = sym;
2988 *p = n;
2989 break;
2990 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002991 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002992 }
2993 }
2994
2995 if (common_head) {
2996 /* Find the bss section. */
2997 for (i = 0; i < f->header.e_shnum; ++i)
2998 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2999 break;
3000
3001 /* If for some reason there hadn't been one, create one. */
3002 if (i == f->header.e_shnum) {
3003 struct obj_section *sec;
3004
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003005 f->header.e_shnum++;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003006 f->sections = xrealloc_vector(f->sections, 2, i);
3007 f->sections[i] = sec = arch_new_section();
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003008
3009 sec->header.sh_type = SHT_PROGBITS;
3010 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
3011 sec->name = ".bss";
3012 sec->idx = i;
3013 }
3014
3015 /* Allocate the COMMONS. */
3016 {
3017 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
3018 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
3019 struct common_entry *c;
3020
3021 for (c = common_head; c; c = c->next) {
3022 ElfW(Addr) align = c->sym->value;
3023
3024 if (align > max_align)
3025 max_align = align;
3026 if (bss_size & (align - 1))
3027 bss_size = (bss_size | (align - 1)) + 1;
3028
3029 c->sym->secidx = i;
3030 c->sym->value = bss_size;
3031
3032 bss_size += c->sym->size;
3033 }
3034
3035 f->sections[i]->header.sh_size = bss_size;
3036 f->sections[i]->header.sh_addralign = max_align;
3037 }
3038 }
3039
3040 /* For the sake of patch relocation and parameter initialization,
3041 allocate zeroed data for NOBITS sections now. Note that after
3042 this we cannot assume NOBITS are really empty. */
3043 for (i = 0; i < f->header.e_shnum; ++i) {
3044 struct obj_section *s = f->sections[i];
3045 if (s->header.sh_type == SHT_NOBITS) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003046 s->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003047 if (s->header.sh_size != 0)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003048 s->contents = xzalloc(s->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003049 s->header.sh_type = SHT_PROGBITS;
3050 }
3051 }
3052}
3053
3054static unsigned long obj_load_size(struct obj_file *f)
3055{
3056 unsigned long dot = 0;
3057 struct obj_section *sec;
3058
3059 /* Finalize the positions of the sections relative to one another. */
3060
3061 for (sec = f->load_order; sec; sec = sec->load_next) {
3062 ElfW(Addr) align;
3063
3064 align = sec->header.sh_addralign;
3065 if (align && (dot & (align - 1)))
3066 dot = (dot | (align - 1)) + 1;
3067
3068 sec->header.sh_addr = dot;
3069 dot += sec->header.sh_size;
3070 }
3071
3072 return dot;
3073}
3074
3075static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3076{
3077 int i, n = f->header.e_shnum;
3078 int ret = 1;
3079
3080 /* Finalize the addresses of the sections. */
3081
3082 f->baseaddr = base;
3083 for (i = 0; i < n; ++i)
3084 f->sections[i]->header.sh_addr += base;
3085
3086 /* And iterate over all of the relocations. */
3087
3088 for (i = 0; i < n; ++i) {
3089 struct obj_section *relsec, *symsec, *targsec, *strsec;
3090 ElfW(RelM) * rel, *relend;
3091 ElfW(Sym) * symtab;
3092 const char *strtab;
3093
3094 relsec = f->sections[i];
3095 if (relsec->header.sh_type != SHT_RELM)
3096 continue;
3097
3098 symsec = f->sections[relsec->header.sh_link];
3099 targsec = f->sections[relsec->header.sh_info];
3100 strsec = f->sections[symsec->header.sh_link];
3101
3102 rel = (ElfW(RelM) *) relsec->contents;
3103 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3104 symtab = (ElfW(Sym) *) symsec->contents;
3105 strtab = (const char *) strsec->contents;
3106
3107 for (; rel < relend; ++rel) {
3108 ElfW(Addr) value = 0;
3109 struct obj_symbol *intsym = NULL;
3110 unsigned long symndx;
Denis Vlasenko49325962009-01-31 23:33:54 +00003111 ElfW(Sym) *extsym = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003112 const char *errmsg;
3113
3114 /* Attempt to find a value to use for this relocation. */
3115
3116 symndx = ELF_R_SYM(rel->r_info);
3117 if (symndx) {
3118 /* Note we've already checked for undefined symbols. */
3119
3120 extsym = &symtab[symndx];
3121 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3122 /* Local symbols we look up in the local table to be sure
3123 we get the one that is really intended. */
3124 intsym = f->local_symtab[symndx];
3125 } else {
3126 /* Others we look up in the hash table. */
3127 const char *name;
3128 if (extsym->st_name)
3129 name = strtab + extsym->st_name;
3130 else
3131 name = f->sections[extsym->st_shndx]->name;
3132 intsym = obj_find_symbol(f, name);
3133 }
3134
3135 value = obj_symbol_final_value(f, intsym);
3136 intsym->referenced = 1;
3137 }
3138#if SHT_RELM == SHT_RELA
3139#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3140 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003141 if (!extsym || !extsym->st_name
3142 || ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003143#endif
3144 value += rel->r_addend;
3145#endif
3146
3147 /* Do it! */
3148 switch (arch_apply_relocation
3149 (f, targsec, /*symsec,*/ intsym, rel, value)
3150 ) {
3151 case obj_reloc_ok:
3152 break;
3153
3154 case obj_reloc_overflow:
3155 errmsg = "Relocation overflow";
3156 goto bad_reloc;
3157 case obj_reloc_dangerous:
3158 errmsg = "Dangerous relocation";
3159 goto bad_reloc;
3160 case obj_reloc_unhandled:
3161 errmsg = "Unhandled relocation";
3162bad_reloc:
3163 if (extsym) {
3164 bb_error_msg("%s of type %ld for %s", errmsg,
3165 (long) ELF_R_TYPE(rel->r_info),
3166 strtab + extsym->st_name);
3167 } else {
3168 bb_error_msg("%s of type %ld", errmsg,
3169 (long) ELF_R_TYPE(rel->r_info));
3170 }
3171 ret = 0;
3172 break;
3173 }
3174 }
3175 }
3176
3177 /* Finally, take care of the patches. */
3178
3179 if (f->string_patches) {
3180 struct obj_string_patch *p;
3181 struct obj_section *strsec;
3182 ElfW(Addr) strsec_base;
3183 strsec = obj_find_section(f, ".kstrtab");
3184 strsec_base = strsec->header.sh_addr;
3185
3186 for (p = f->string_patches; p; p = p->next) {
3187 struct obj_section *targsec = f->sections[p->reloc_secidx];
3188 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3189 = strsec_base + p->string_offset;
3190 }
3191 }
3192
3193 if (f->symbol_patches) {
3194 struct obj_symbol_patch *p;
3195
3196 for (p = f->symbol_patches; p; p = p->next) {
3197 struct obj_section *targsec = f->sections[p->reloc_secidx];
3198 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3199 = obj_symbol_final_value(f, p->sym);
3200 }
3201 }
3202
3203 return ret;
3204}
3205
3206static int obj_create_image(struct obj_file *f, char *image)
3207{
3208 struct obj_section *sec;
3209 ElfW(Addr) base = f->baseaddr;
3210
3211 for (sec = f->load_order; sec; sec = sec->load_next) {
3212 char *secimg;
3213
3214 if (sec->contents == 0 || sec->header.sh_size == 0)
3215 continue;
3216
3217 secimg = image + (sec->header.sh_addr - base);
3218
3219 /* Note that we allocated data for NOBITS sections earlier. */
3220 memcpy(secimg, sec->contents, sec->header.sh_size);
3221 }
3222
3223 return 1;
3224}
3225
3226/*======================================================================*/
3227
Denis Vlasenkof4393042009-04-05 23:25:09 +00003228static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003229{
Denys Vlasenko98a4c7c2010-02-04 15:00:15 +01003230 typedef uint32_t aliased_uint32_t FIX_ALIASING;
Denis Vlasenkoe1de3af2009-03-29 16:38:59 +00003231#if BB_LITTLE_ENDIAN
3232# define ELFMAG_U32 ((uint32_t)(ELFMAG0 + 0x100 * (ELFMAG1 + (0x100 * (ELFMAG2 + 0x100 * ELFMAG3)))))
3233#else
3234# define ELFMAG_U32 ((uint32_t)((((ELFMAG0 * 0x100) + ELFMAG1) * 0x100 + ELFMAG2) * 0x100 + ELFMAG3))
3235#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003236 struct obj_file *f;
3237 ElfW(Shdr) * section_headers;
3238 size_t shnum, i;
3239 char *shstrtab;
3240
3241 /* Read the file header. */
3242
3243 f = arch_new_file();
3244 f->symbol_cmp = strcmp;
3245 f->symbol_hash = obj_elf_hash;
3246 f->load_order_search_start = &f->load_order;
3247
Denis Vlasenkof4393042009-04-05 23:25:09 +00003248 if (image_size < sizeof(f->header))
3249 bb_error_msg_and_die("error while loading ELF header");
3250 memcpy(&f->header, image, sizeof(f->header));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003251
Denys Vlasenko98a4c7c2010-02-04 15:00:15 +01003252 if (*(aliased_uint32_t*)(&f->header.e_ident) != ELFMAG_U32) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003253 bb_error_msg_and_die("not an ELF file");
3254 }
3255 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003256 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3257 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3258 || !MATCH_MACHINE(f->header.e_machine)
3259 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003260 bb_error_msg_and_die("ELF file not for this architecture");
3261 }
3262 if (f->header.e_type != ET_REL) {
3263 bb_error_msg_and_die("ELF file not a relocatable object");
3264 }
3265
3266 /* Read the section headers. */
3267
3268 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3269 bb_error_msg_and_die("section header size mismatch: %lu != %lu",
3270 (unsigned long) f->header.e_shentsize,
3271 (unsigned long) sizeof(ElfW(Shdr)));
3272 }
3273
3274 shnum = f->header.e_shnum;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003275 /* Growth of ->sections vector will be done by
3276 * xrealloc_vector(..., 2, ...), therefore we must allocate
3277 * at least 2^2 = 4 extra elements here. */
3278 f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003279
3280 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003281 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum)
3282 bb_error_msg_and_die("error while loading section headers");
3283 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003284
3285 /* Read the section data. */
3286
3287 for (i = 0; i < shnum; ++i) {
3288 struct obj_section *sec;
3289
3290 f->sections[i] = sec = arch_new_section();
3291
3292 sec->header = section_headers[i];
3293 sec->idx = i;
3294
3295 if (sec->header.sh_size) {
3296 switch (sec->header.sh_type) {
3297 case SHT_NULL:
3298 case SHT_NOTE:
3299 case SHT_NOBITS:
3300 /* ignore */
3301 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003302 case SHT_PROGBITS:
3303#if LOADBITS
3304 if (!loadprogbits) {
3305 sec->contents = NULL;
3306 break;
3307 }
3308#endif
3309 case SHT_SYMTAB:
3310 case SHT_STRTAB:
3311 case SHT_RELM:
Ralf Rösch8597da12010-04-14 09:45:37 -07003312#if defined(__mips__)
3313 case SHT_MIPS_DWARF:
3314#endif
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003315 sec->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003316 if (sec->header.sh_size > 0) {
3317 sec->contents = xmalloc(sec->header.sh_size);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003318 if (image_size < (sec->header.sh_offset + sec->header.sh_size))
3319 bb_error_msg_and_die("error while loading section data");
3320 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003321 }
3322 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003323#if SHT_RELM == SHT_REL
3324 case SHT_RELA:
3325 bb_error_msg_and_die("RELA relocations not supported on this architecture");
3326#else
3327 case SHT_REL:
3328 bb_error_msg_and_die("REL relocations not supported on this architecture");
3329#endif
3330 default:
3331 if (sec->header.sh_type >= SHT_LOPROC) {
3332 /* Assume processor specific section types are debug
3333 info and can safely be ignored. If this is ever not
3334 the case (Hello MIPS?), don't put ifdefs here but
3335 create an arch_load_proc_section(). */
3336 break;
3337 }
3338
3339 bb_error_msg_and_die("can't handle sections of type %ld",
3340 (long) sec->header.sh_type);
3341 }
3342 }
3343 }
3344
3345 /* Do what sort of interpretation as needed by each section. */
3346
3347 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3348
3349 for (i = 0; i < shnum; ++i) {
3350 struct obj_section *sec = f->sections[i];
3351 sec->name = shstrtab + sec->header.sh_name;
3352 }
3353
3354 for (i = 0; i < shnum; ++i) {
3355 struct obj_section *sec = f->sections[i];
3356
3357 /* .modinfo should be contents only but gcc has no attribute for that.
3358 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3359 */
3360 if (strcmp(sec->name, ".modinfo") == 0)
3361 sec->header.sh_flags &= ~SHF_ALLOC;
3362
3363 if (sec->header.sh_flags & SHF_ALLOC)
3364 obj_insert_section_load_order(f, sec);
3365
3366 switch (sec->header.sh_type) {
3367 case SHT_SYMTAB:
3368 {
3369 unsigned long nsym, j;
3370 char *strtab;
3371 ElfW(Sym) * sym;
3372
3373 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3374 bb_error_msg_and_die("symbol size mismatch: %lu != %lu",
3375 (unsigned long) sec->header.sh_entsize,
3376 (unsigned long) sizeof(ElfW(Sym)));
3377 }
3378
3379 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3380 strtab = f->sections[sec->header.sh_link]->contents;
3381 sym = (ElfW(Sym) *) sec->contents;
3382
3383 /* Allocate space for a table of local symbols. */
3384 j = f->local_symtab_size = sec->header.sh_info;
3385 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
3386
3387 /* Insert all symbols into the hash table. */
3388 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3389 ElfW(Addr) val = sym->st_value;
3390 const char *name;
3391 if (sym->st_name)
3392 name = strtab + sym->st_name;
3393 else if (sym->st_shndx < shnum)
3394 name = f->sections[sym->st_shndx]->name;
3395 else
3396 continue;
3397#if defined(__SH5__)
3398 /*
3399 * For sh64 it is possible that the target of a branch
3400 * requires a mode switch (32 to 16 and back again).
3401 *
3402 * This is implied by the lsb being set in the target
3403 * address for SHmedia mode and clear for SHcompact.
3404 */
3405 val |= sym->st_other & 4;
3406#endif
3407 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3408 val, sym->st_size);
3409 }
3410 }
3411 break;
3412
3413 case SHT_RELM:
3414 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3415 bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu",
3416 (unsigned long) sec->header.sh_entsize,
3417 (unsigned long) sizeof(ElfW(RelM)));
3418 }
3419 break;
3420 /* XXX Relocation code from modutils-2.3.19 is not here.
3421 * Why? That's about 20 lines of code from obj/obj_load.c,
3422 * which gets done in a second pass through the sections.
3423 * This BusyBox insmod does similar work in obj_relocate(). */
3424 }
3425 }
3426
3427 return f;
3428}
3429
3430#if ENABLE_FEATURE_INSMOD_LOADINKMEM
3431/*
3432 * load the unloaded sections directly into the memory allocated by
3433 * kernel for the module
3434 */
3435
Denis Vlasenkof4393042009-04-05 23:25:09 +00003436static int obj_load_progbits(char *image, size_t image_size, struct obj_file *f, char *imagebase)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003437{
3438 ElfW(Addr) base = f->baseaddr;
3439 struct obj_section* sec;
3440
3441 for (sec = f->load_order; sec; sec = sec->load_next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003442 /* section already loaded? */
3443 if (sec->contents != NULL)
3444 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003445 if (sec->header.sh_size == 0)
3446 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003447 sec->contents = imagebase + (sec->header.sh_addr - base);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003448 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) {
3449 bb_error_msg("error reading ELF section data");
3450 return 0; /* need to delete half-loaded module! */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003451 }
Denis Vlasenkof4393042009-04-05 23:25:09 +00003452 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003453 }
3454 return 1;
3455}
3456#endif
3457
3458static void hide_special_symbols(struct obj_file *f)
3459{
3460 static const char *const specials[] = {
3461 SPFX "cleanup_module",
3462 SPFX "init_module",
3463 SPFX "kernel_version",
3464 NULL
3465 };
3466
3467 struct obj_symbol *sym;
3468 const char *const *p;
3469
3470 for (p = specials; *p; ++p) {
3471 sym = obj_find_symbol(f, *p);
3472 if (sym != NULL)
3473 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3474 }
3475}
3476
3477
3478#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
3479static int obj_gpl_license(struct obj_file *f, const char **license)
3480{
3481 struct obj_section *sec;
3482 /* This list must match *exactly* the list of allowable licenses in
3483 * linux/include/linux/module.h. Checking for leading "GPL" will not
3484 * work, somebody will use "GPL sucks, this is proprietary".
3485 */
3486 static const char *const gpl_licenses[] = {
3487 "GPL",
3488 "GPL v2",
3489 "GPL and additional rights",
3490 "Dual BSD/GPL",
3491 "Dual MPL/GPL"
3492 };
3493
3494 sec = obj_find_section(f, ".modinfo");
3495 if (sec) {
3496 const char *value, *ptr, *endptr;
3497 ptr = sec->contents;
3498 endptr = ptr + sec->header.sh_size;
3499 while (ptr < endptr) {
3500 value = strchr(ptr, '=');
3501 if (value && strncmp(ptr, "license", value-ptr) == 0) {
3502 unsigned i;
3503 if (license)
3504 *license = value+1;
3505 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
3506 if (strcmp(value+1, gpl_licenses[i]) == 0)
3507 return 0;
3508 }
3509 return 2;
3510 }
3511 ptr = strchr(ptr, '\0');
3512 if (ptr)
3513 ptr++;
3514 else
3515 ptr = endptr;
3516 }
3517 }
3518 return 1;
3519}
3520
3521#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3522#define TAINT_PROPRIETORY_MODULE (1 << 0)
3523#define TAINT_FORCED_MODULE (1 << 1)
3524#define TAINT_UNSAFE_SMP (1 << 2)
3525#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3526
3527static void set_tainted(int fd, const char *m_name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02003528 int kernel_has_tainted, int taint,
3529 const char *text1, const char *text2)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003530{
3531 static smallint printed_info;
3532
3533 char buf[80];
3534 int oldval;
3535
3536 if (fd < 0 && !kernel_has_tainted)
3537 return; /* New modutils on old kernel */
3538 printf("Warning: loading %s will taint the kernel: %s%s\n",
3539 m_name, text1, text2);
3540 if (!printed_info) {
3541 printf(" See %s for information about tainted modules\n", TAINT_URL);
3542 printed_info = 1;
3543 }
3544 if (fd >= 0) {
3545 read(fd, buf, sizeof(buf)-1);
3546 buf[sizeof(buf)-1] = '\0';
3547 oldval = strtoul(buf, NULL, 10);
3548 sprintf(buf, "%d\n", oldval | taint);
Denis Vlasenko73c571a2009-03-09 00:12:37 +00003549 xwrite_str(fd, buf);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003550 }
3551}
3552
3553/* Check if loading this module will taint the kernel. */
3554static void check_tainted_module(struct obj_file *f, const char *m_name)
3555{
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003556 int fd, kernel_has_tainted;
3557 const char *ptr;
3558
3559 kernel_has_tainted = 1;
Denys Vlasenkoea8b2522010-06-02 12:57:26 +02003560 fd = open(TAINT_FILENAME, O_RDWR);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003561 if (fd < 0) {
3562 if (errno == ENOENT)
3563 kernel_has_tainted = 0;
3564 else if (errno == EACCES)
3565 kernel_has_tainted = 1;
3566 else {
Marek Polacek7dd61e32010-09-12 17:06:43 +02003567 bb_simple_perror_msg(TAINT_FILENAME);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003568 kernel_has_tainted = 0;
3569 }
3570 }
3571
3572 switch (obj_gpl_license(f, &ptr)) {
3573 case 0:
3574 break;
3575 case 1:
3576 set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3577 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003578 default: /* case 2: */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003579 /* The module has a non-GPL license so we pretend that the
3580 * kernel always has a taint flag to get a warning even on
3581 * kernels without the proc flag.
3582 */
3583 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3584 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003585 }
3586
3587 if (flag_force_load)
3588 set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3589
3590 if (fd >= 0)
3591 close(fd);
3592}
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003593#else /* !FEATURE_CHECK_TAINTED_MODULE */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003594#define check_tainted_module(x, y) do { } while (0);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003595#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003596
3597#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3598/* add module source, timestamp, kernel version and a symbol for the
3599 * start of some sections. this info is used by ksymoops to do better
3600 * debugging.
3601 */
3602#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3603#define get_module_version(f, str) get_module_version(str)
3604#endif
3605static int
3606get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3607{
3608#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3609 return new_get_module_version(f, str);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003610#else
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003611 strncpy(str, "???", sizeof(str));
3612 return -1;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003613#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003614}
3615
3616/* add module source, timestamp, kernel version and a symbol for the
3617 * start of some sections. this info is used by ksymoops to do better
3618 * debugging.
3619 */
3620static void
3621add_ksymoops_symbols(struct obj_file *f, const char *filename,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02003622 const char *m_name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003623{
3624 static const char symprefix[] ALIGN1 = "__insmod_";
3625 static const char section_names[][8] = {
3626 ".text",
3627 ".rodata",
3628 ".data",
3629 ".bss",
3630 ".sbss"
3631 };
3632
3633 struct obj_section *sec;
3634 struct obj_symbol *sym;
3635 char *name, *absolute_filename;
3636 char str[STRVERSIONLEN];
3637 unsigned i;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003638 int lm_name, lfilename, use_ksymtab, version;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003639 struct stat statbuf;
3640
3641 /* WARNING: was using realpath, but replaced by readlink to stop using
3642 * lots of stack. But here it seems to be able to cause problems? */
3643 absolute_filename = xmalloc_readlink(filename);
3644 if (!absolute_filename)
3645 absolute_filename = xstrdup(filename);
3646
3647 lm_name = strlen(m_name);
3648 lfilename = strlen(absolute_filename);
3649
3650 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3651 * are not to be exported. otherwise leave ksymtab alone for now, the
3652 * "export all symbols" compatibility code will export these symbols later.
3653 */
3654 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
3655
3656 sec = obj_find_section(f, ".this");
3657 if (sec) {
3658 /* tag the module header with the object name, last modified
3659 * timestamp and module version. worst case for module version
3660 * is 0xffffff, decimal 16777215. putting all three fields in
3661 * one symbol is less readable but saves kernel space.
3662 */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003663 if (stat(absolute_filename, &statbuf) != 0)
3664 statbuf.st_mtime = 0;
3665 version = get_module_version(f, str); /* -1 if not found */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003666 name = xasprintf("%s%s_O%s_M%0*lX_V%d",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003667 symprefix, m_name, absolute_filename,
Denis Vlasenko49325962009-01-31 23:33:54 +00003668 (int)(2 * sizeof(statbuf.st_mtime)),
3669 (long)statbuf.st_mtime,
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003670 version);
3671 sym = obj_add_symbol(f, name, -1,
3672 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3673 sec->idx, sec->header.sh_addr, 0);
3674 if (use_ksymtab)
3675 new_add_ksymtab(f, sym);
3676 }
3677 free(absolute_filename);
3678#ifdef _NOT_SUPPORTED_
3679 /* record where the persistent data is going, same address as previous symbol */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003680 if (f->persist) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003681 name = xasprintf("%s%s_P%s",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003682 symprefix, m_name, f->persist);
3683 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3684 sec->idx, sec->header.sh_addr, 0);
3685 if (use_ksymtab)
3686 new_add_ksymtab(f, sym);
3687 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003688#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003689 /* tag the desired sections if size is non-zero */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003690 for (i = 0; i < ARRAY_SIZE(section_names); ++i) {
3691 sec = obj_find_section(f, section_names[i]);
3692 if (sec && sec->header.sh_size) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003693 name = xasprintf("%s%s_S%s_L%ld",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003694 symprefix, m_name, sec->name,
3695 (long)sec->header.sh_size);
3696 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3697 sec->idx, sec->header.sh_addr, 0);
3698 if (use_ksymtab)
3699 new_add_ksymtab(f, sym);
3700 }
3701 }
3702}
3703#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3704
3705#if ENABLE_FEATURE_INSMOD_LOAD_MAP
3706static void print_load_map(struct obj_file *f)
3707{
3708 struct obj_section *sec;
3709#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3710 struct obj_symbol **all, **p;
Denis Vlasenko49325962009-01-31 23:33:54 +00003711 int i, nsyms;
3712 char *loaded; /* array of booleans */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003713 struct obj_symbol *sym;
3714#endif
3715 /* Report on the section layout. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003716 printf("Sections: Size %-*s Align\n",
3717 (int) (2 * sizeof(void *)), "Address");
3718
3719 for (sec = f->load_order; sec; sec = sec->load_next) {
3720 int a;
3721 unsigned long tmp;
3722
3723 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3724 tmp >>= 1;
3725 if (a == -1)
3726 a = 0;
3727
3728 printf("%-15s %08lx %0*lx 2**%d\n",
3729 sec->name,
3730 (long)sec->header.sh_size,
3731 (int) (2 * sizeof(void *)),
3732 (long)sec->header.sh_addr,
3733 a);
3734 }
3735#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3736 /* Quick reference which section indices are loaded. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003737 i = f->header.e_shnum;
Denis Vlasenko49325962009-01-31 23:33:54 +00003738 loaded = alloca(i * sizeof(loaded[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003739 while (--i >= 0)
3740 loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0);
3741
3742 /* Collect the symbols we'll be listing. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003743 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3744 for (sym = f->symtab[i]; sym; sym = sym->next)
3745 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003746 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3747 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003748 ++nsyms;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003749 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003750
Denis Vlasenko49325962009-01-31 23:33:54 +00003751 all = alloca(nsyms * sizeof(all[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003752
3753 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3754 for (sym = f->symtab[i]; sym; sym = sym->next)
3755 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003756 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3757 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003758 *p++ = sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003759 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003760
3761 /* And list them. */
3762 printf("\nSymbols:\n");
3763 for (p = all; p < all + nsyms; ++p) {
3764 char type = '?';
3765 unsigned long value;
3766
3767 sym = *p;
3768 if (sym->secidx == SHN_ABS) {
3769 type = 'A';
3770 value = sym->value;
3771 } else if (sym->secidx == SHN_UNDEF) {
3772 type = 'U';
3773 value = 0;
3774 } else {
3775 sec = f->sections[sym->secidx];
3776
3777 if (sec->header.sh_type == SHT_NOBITS)
3778 type = 'B';
3779 else if (sec->header.sh_flags & SHF_ALLOC) {
3780 if (sec->header.sh_flags & SHF_EXECINSTR)
3781 type = 'T';
3782 else if (sec->header.sh_flags & SHF_WRITE)
3783 type = 'D';
3784 else
3785 type = 'R';
3786 }
3787 value = sym->value + sec->header.sh_addr;
3788 }
3789
3790 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
Denis Vlasenko49325962009-01-31 23:33:54 +00003791 type |= 0x20; /* tolower. safe for '?' too */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003792
3793 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3794 type, sym->name);
3795 }
3796#endif
3797}
3798#else /* !FEATURE_INSMOD_LOAD_MAP */
3799static void print_load_map(struct obj_file *f UNUSED_PARAM)
3800{
3801}
3802#endif
3803
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003804int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003805{
3806 int k_crcs;
3807 unsigned long m_size;
3808 ElfW(Addr) m_addr;
3809 struct obj_file *f;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003810 int exit_status = EXIT_FAILURE;
Denis Vlasenkof4393042009-04-05 23:25:09 +00003811 char *m_name;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003812#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003813 int m_has_modinfo;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003814#endif
Denis Vlasenkof4393042009-04-05 23:25:09 +00003815 char *image;
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003816 size_t image_size;
3817 bool mmaped;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003818
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003819 image_size = INT_MAX - 4095;
3820 mmaped = 0;
3821 image = try_to_mmap_module(m_filename, &image_size);
3822 if (image) {
3823 mmaped = 1;
3824 } else {
3825 /* Load module into memory and unzip if compressed */
3826 image = xmalloc_open_zipped_read_close(m_filename, &image_size);
3827 if (!image)
3828 return EXIT_FAILURE;
3829 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003830
3831 m_name = xstrdup(bb_basename(m_filename));
Denis Vlasenkof4393042009-04-05 23:25:09 +00003832 /* "module.o[.gz]" -> "module" */
3833 *strchrnul(m_name, '.') = '\0';
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003834
Denis Vlasenkof4393042009-04-05 23:25:09 +00003835 f = obj_load(image, image_size, LOADBITS);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003836
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003837#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3838 /* Version correspondence? */
Denis Vlasenko51056b32009-04-12 14:21:29 +00003839 m_has_modinfo = (get_modinfo_value(f, "kernel_version") != NULL);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003840 if (!flag_quiet) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003841 char m_strversion[STRVERSIONLEN];
3842 struct utsname uts;
3843
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003844 if (m_has_modinfo) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003845 int m_version = new_get_module_version(f, m_strversion);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003846 if (m_version == -1) {
Denis Vlasenko1f632292009-04-13 02:25:40 +00003847 bb_error_msg_and_die("can't find the kernel version "
Denis Vlasenko51056b32009-04-12 14:21:29 +00003848 "the module was compiled for");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003849 }
3850 }
3851
Denis Vlasenko51056b32009-04-12 14:21:29 +00003852 uname(&uts);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003853 if (strncmp(uts.release, m_strversion, STRVERSIONLEN) != 0) {
3854 bb_error_msg("%skernel-module version mismatch\n"
3855 "\t%s was compiled for kernel version %s\n"
3856 "\twhile this kernel is version %s",
3857 flag_force_load ? "warning: " : "",
3858 m_name, m_strversion, uts.release);
3859 if (!flag_force_load)
3860 goto out;
3861 }
3862 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003863#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003864
3865 if (query_module(NULL, 0, NULL, 0, NULL))
Denis Vlasenkof4393042009-04-05 23:25:09 +00003866 bb_error_msg_and_die("old (unsupported) kernel");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003867 new_get_kernel_symbols();
3868 k_crcs = new_is_kernel_checksummed();
3869
3870#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003871 {
3872 int m_crcs = 0;
3873 if (m_has_modinfo)
3874 m_crcs = new_is_module_checksummed(f);
3875 if (m_crcs != k_crcs)
3876 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3877 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003878#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003879
3880 /* Let the module know about the kernel symbols. */
3881 add_kernel_symbols(f);
3882
3883 /* Allocate common symbols, symbol tables, and string tables. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003884 new_create_this_module(f, m_name);
3885 obj_check_undefineds(f);
3886 obj_allocate_commons(f);
3887 check_tainted_module(f, m_name);
3888
Denis Vlasenko49325962009-01-31 23:33:54 +00003889 /* Done with the module name, on to the optional var=value arguments */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003890 new_process_module_arguments(f, options);
3891
3892 arch_create_got(f);
3893 hide_special_symbols(f);
3894
3895#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3896 add_ksymoops_symbols(f, m_filename, m_name);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003897#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003898
3899 new_create_module_ksymtab(f);
3900
3901 /* Find current size of the module */
3902 m_size = obj_load_size(f);
3903
3904 m_addr = create_module(m_name, m_size);
3905 if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003906 case EEXIST:
3907 bb_error_msg_and_die("a module named %s already exists", m_name);
3908 case ENOMEM:
3909 bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes",
3910 m_size);
3911 default:
3912 bb_perror_msg_and_die("create_module: %s", m_name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003913 }
3914
3915#if !LOADBITS
3916 /*
3917 * the PROGBITS section was not loaded by the obj_load
3918 * now we can load them directly into the kernel memory
3919 */
Denis Vlasenkof4393042009-04-05 23:25:09 +00003920 if (!obj_load_progbits(image, image_size, f, (char*)m_addr)) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003921 delete_module(m_name, 0);
3922 goto out;
3923 }
3924#endif
3925
3926 if (!obj_relocate(f, m_addr)) {
3927 delete_module(m_name, 0);
3928 goto out;
3929 }
3930
3931 if (!new_init_module(m_name, f, m_size)) {
3932 delete_module(m_name, 0);
3933 goto out;
3934 }
3935
3936 if (flag_print_load_map)
3937 print_load_map(f);
3938
3939 exit_status = EXIT_SUCCESS;
3940
3941 out:
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003942 if (mmaped)
3943 munmap(image, image_size);
3944 else
3945 free(image);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003946 free(m_name);
3947
3948 return exit_status;
3949}