aboutsummaryrefslogtreecommitdiff
path: root/modutils
diff options
context:
space:
mode:
Diffstat (limited to 'modutils')
-rw-r--r--modutils/Config.in158
-rw-r--r--modutils/Kbuild11
-rw-r--r--modutils/insmod.c4316
-rw-r--r--modutils/lsmod.c188
-rw-r--r--modutils/modprobe.c905
-rw-r--r--modutils/rmmod.c96
6 files changed, 5674 insertions, 0 deletions
diff --git a/modutils/Config.in b/modutils/Config.in
new file mode 100644
index 000000000..6a6956755
--- /dev/null
+++ b/modutils/Config.in
@@ -0,0 +1,158 @@
1#
2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt.
4#
5
6menu "Linux Module Utilities"
7
8config INSMOD
9 bool "insmod"
10 default n
11 help
12 insmod is used to load specified modules in the running kernel.
13
14config FEATURE_INSMOD_VERSION_CHECKING
15 bool "Module version checking"
16 default n
17 depends on INSMOD && FEATURE_2_4_MODULES
18 help
19 Support checking of versions for modules. This is used to
20 ensure that the kernel and module are made for each other.
21
22config FEATURE_INSMOD_KSYMOOPS_SYMBOLS
23 bool "Add module symbols to kernel symbol table"
24 default n
25 depends on INSMOD && FEATURE_2_4_MODULES
26 help
27 By adding module symbols to the kernel symbol table, Oops messages
28 occuring within kernel modules can be properly debugged. By enabling
29 this feature, module symbols will always be added to the kernel symbol
30 table for properly debugging support. If you are not interested in
31 Oops messages from kernel modules, say N.
32
33config FEATURE_INSMOD_LOADINKMEM
34 bool "In kernel memory optimization (uClinux only)"
35 default n
36 depends on INSMOD && FEATURE_2_4_MODULES
37 help
38 This is a special uClinux only memory optimization that lets insmod
39 load the specified kernel module directly into kernel space, reducing
40 memory usage by preventing the need for two copies of the module
41 being loaded into memory.
42
43config FEATURE_INSMOD_LOAD_MAP
44 bool "Enable load map (-m) option"
45 default n
46 depends on INSMOD && ( FEATURE_2_4_MODULES || FEATURE_2_6_MODULES )
47 help
48 Enabling this, one would be able to get a load map
49 output on stdout. This makes kernel module debugging
50 easier.
51 If you don't plan to debug kernel modules, you
52 don't need this option.
53
54config FEATURE_INSMOD_LOAD_MAP_FULL
55 bool "Symbols in load map"
56 default y
57 depends on FEATURE_INSMOD_LOAD_MAP
58 help
59 Without this option, -m will only output section
60 load map. With this option, -m will also output
61 symbols load map.
62
63config RMMOD
64 bool "rmmod"
65 default n
66 help
67 rmmod is used to unload specified modules from the kernel.
68
69config LSMOD
70 bool "lsmod"
71 default n
72 help
73 lsmod is used to display a list of loaded modules.
74
75config FEATURE_LSMOD_PRETTY_2_6_OUTPUT
76 bool "lsmod pretty output for 2.6.x Linux kernels "
77 default n
78 depends on LSMOD
79 help
80 This option makes output format of lsmod adjusted to
81 the format of module-init-tools for Linux kernel 2.6.
82
83config MODPROBE
84 bool "modprobe"
85 default n
86 help
87 Handle the loading of modules, and their dependencies on a high
88 level.
89
90 Note that in the state, modprobe does not understand multiple
91 module options from the configuration file. See option below.
92
93config FEATURE_MODPROBE_MULTIPLE_OPTIONS
94 bool
95 prompt "Multiple options parsing" if NITPICK
96 default y
97 depends on MODPROBE
98 help
99 Allow modprobe to understand more than one option to pass to
100 modules.
101
102 This is a WIP, while waiting for a common argument parsing
103 common amongst all BB applets (shell, modprobe, etc...) and
104 adds around 600 bytes on x86, 700 bytes on ARM. The code is
105 biggish and uggly, but just works.
106
107 Saying Y here is not a bad idea if you're not that short
108 on storage capacity.
109
110config FEATURE_MODPROBE_FANCY_ALIAS
111 bool
112 prompt "Fancy alias parsing" if NITPICK
113 default y
114 depends on MODPROBE && FEATURE_2_6_MODULES
115 help
116 Say 'y' here to enable parsing of aliases with underscore/dash
117 mismatch between module name and file name, along with bus-specific
118 aliases (such as pci:... or usb:... aliases).
119
120comment "Options common to multiple modutils"
121 depends on INSMOD || RMMOD || MODPROBE || LSMOD
122
123config FEATURE_CHECK_TAINTED_MODULE
124 # Simulate indentation
125 bool "Support tainted module checking with new kernels"
126 default y
127 depends on INSMOD || LSMOD
128 help
129 Support checking for tainted modules. These are usually binary
130 only modules that will make the linux-kernel list ignore your
131 support request.
132 This option is required to support GPLONLY modules.
133
134config FEATURE_2_4_MODULES
135 # Simulate indentation
136 bool "Support version 2.2.x to 2.4.x Linux kernels"
137 default y
138 depends on INSMOD || RMMOD || MODPROBE
139 help
140 Support module loading for 2.2.x and 2.4.x Linux kernels.
141
142config FEATURE_2_6_MODULES
143 # Simulate indentation
144 bool "Support version 2.6.x Linux kernels"
145 default y
146 depends on INSMOD || RMMOD || MODPROBE
147 help
148 Support module loading for newer 2.6.x Linux kernels.
149
150
151config FEATURE_QUERY_MODULE_INTERFACE
152 bool
153 default y
154 depends on FEATURE_2_4_MODULES && !FEATURE_2_6_MODULES
155
156
157endmenu
158
diff --git a/modutils/Kbuild b/modutils/Kbuild
new file mode 100644
index 000000000..cff02b4f2
--- /dev/null
+++ b/modutils/Kbuild
@@ -0,0 +1,11 @@
1# Makefile for busybox
2#
3# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
4#
5# Licensed under the GPL v2, see the file LICENSE in this tarball.
6
7lib-y:=
8lib-$(CONFIG_INSMOD) += insmod.o
9lib-$(CONFIG_LSMOD) += lsmod.o
10lib-$(CONFIG_MODPROBE) += modprobe.o
11lib-$(CONFIG_RMMOD) += rmmod.o
diff --git a/modutils/insmod.c b/modutils/insmod.c
new file mode 100644
index 000000000..7b715b9c3
--- /dev/null
+++ b/modutils/insmod.c
@@ -0,0 +1,4316 @@
1/* 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 *
58 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
59 */
60
61#include "busybox.h"
62#include <libgen.h>
63#include <sys/utsname.h>
64
65#if !ENABLE_FEATURE_2_4_MODULES && !ENABLE_FEATURE_2_6_MODULES
66#define ENABLE_FEATURE_2_4_MODULES 1
67#endif
68
69#if !ENABLE_FEATURE_2_4_MODULES
70#define insmod_ng_main insmod_main
71#endif
72
73#if ENABLE_FEATURE_2_6_MODULES
74extern int insmod_ng_main( int argc, char **argv);
75#endif
76
77
78#if ENABLE_FEATURE_2_4_MODULES
79
80
81#if ENABLE_FEATURE_INSMOD_LOADINKMEM
82#define LOADBITS 0
83#else
84#define LOADBITS 1
85#endif
86
87
88/* Alpha */
89#if defined(__alpha__)
90#define MATCH_MACHINE(x) (x == EM_ALPHA)
91#define SHT_RELM SHT_RELA
92#define Elf64_RelM Elf64_Rela
93#define ELFCLASSM ELFCLASS64
94#endif
95
96/* ARM support */
97#if defined(__arm__)
98#define MATCH_MACHINE(x) (x == EM_ARM)
99#define SHT_RELM SHT_REL
100#define Elf32_RelM Elf32_Rel
101#define ELFCLASSM ELFCLASS32
102#define USE_PLT_ENTRIES
103#define PLT_ENTRY_SIZE 8
104#define USE_GOT_ENTRIES
105#define GOT_ENTRY_SIZE 8
106#define USE_SINGLE
107#endif
108
109/* blackfin */
110#if defined(BFIN)
111#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
112#define SHT_RELM SHT_RELA
113#define Elf32_RelM Elf32_Rela
114#define ELFCLASSM ELFCLASS32
115#endif
116
117/* CRIS */
118#if defined(__cris__)
119#define MATCH_MACHINE(x) (x == EM_CRIS)
120#define SHT_RELM SHT_RELA
121#define Elf32_RelM Elf32_Rela
122#define ELFCLASSM ELFCLASS32
123#ifndef EM_CRIS
124#define EM_CRIS 76
125#define R_CRIS_NONE 0
126#define R_CRIS_32 3
127#endif
128#endif
129
130/* H8/300 */
131#if defined(__H8300H__) || defined(__H8300S__)
132#define MATCH_MACHINE(x) (x == EM_H8_300)
133#define SHT_RELM SHT_RELA
134#define Elf32_RelM Elf32_Rela
135#define ELFCLASSM ELFCLASS32
136#define USE_SINGLE
137#define SYMBOL_PREFIX "_"
138#endif
139
140/* PA-RISC / HP-PA */
141#if defined(__hppa__)
142#define MATCH_MACHINE(x) (x == EM_PARISC)
143#define SHT_RELM SHT_RELA
144#if defined(__LP64__)
145#define Elf64_RelM Elf64_Rela
146#define ELFCLASSM ELFCLASS64
147#else
148#define Elf32_RelM Elf32_Rela
149#define ELFCLASSM ELFCLASS32
150#endif
151#endif
152
153/* x86 */
154#if defined(__i386__)
155#ifndef EM_486
156#define MATCH_MACHINE(x) (x == EM_386)
157#else
158#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
159#endif
160#define SHT_RELM SHT_REL
161#define Elf32_RelM Elf32_Rel
162#define ELFCLASSM ELFCLASS32
163#define USE_GOT_ENTRIES
164#define GOT_ENTRY_SIZE 4
165#define USE_SINGLE
166#endif
167
168/* IA64, aka Itanium */
169#if defined(__ia64__)
170#define MATCH_MACHINE(x) (x == EM_IA_64)
171#define SHT_RELM SHT_RELA
172#define Elf64_RelM Elf64_Rela
173#define ELFCLASSM ELFCLASS64
174#endif
175
176/* m68k */
177#if defined(__mc68000__)
178#define MATCH_MACHINE(x) (x == EM_68K)
179#define SHT_RELM SHT_RELA
180#define Elf32_RelM Elf32_Rela
181#define ELFCLASSM ELFCLASS32
182#define USE_GOT_ENTRIES
183#define GOT_ENTRY_SIZE 4
184#define USE_SINGLE
185#endif
186
187/* Microblaze */
188#if defined(__microblaze__)
189#define USE_SINGLE
190#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
191#define SHT_RELM SHT_RELA
192#define Elf32_RelM Elf32_Rela
193#define ELFCLASSM ELFCLASS32
194#endif
195
196/* MIPS */
197#if defined(__mips__)
198#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
199#define SHT_RELM SHT_REL
200#define Elf32_RelM Elf32_Rel
201#define ELFCLASSM ELFCLASS32
202/* Account for ELF spec changes. */
203#ifndef EM_MIPS_RS3_LE
204#ifdef EM_MIPS_RS4_BE
205#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
206#else
207#define EM_MIPS_RS3_LE 10
208#endif
209#endif /* !EM_MIPS_RS3_LE */
210#define ARCHDATAM "__dbe_table"
211#endif
212
213/* Nios II */
214#if defined(__nios2__)
215#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
216#define SHT_RELM SHT_RELA
217#define Elf32_RelM Elf32_Rela
218#define ELFCLASSM ELFCLASS32
219#endif
220
221/* PowerPC */
222#if defined(__powerpc64__)
223#define MATCH_MACHINE(x) (x == EM_PPC64)
224#define SHT_RELM SHT_RELA
225#define Elf64_RelM Elf64_Rela
226#define ELFCLASSM ELFCLASS64
227#elif defined(__powerpc__)
228#define MATCH_MACHINE(x) (x == EM_PPC)
229#define SHT_RELM SHT_RELA
230#define Elf32_RelM Elf32_Rela
231#define ELFCLASSM ELFCLASS32
232#define USE_PLT_ENTRIES
233#define PLT_ENTRY_SIZE 16
234#define USE_PLT_LIST
235#define LIST_ARCHTYPE ElfW(Addr)
236#define USE_LIST
237#define ARCHDATAM "__ftr_fixup"
238#endif
239
240/* S390 */
241#if defined(__s390__)
242#define MATCH_MACHINE(x) (x == EM_S390)
243#define SHT_RELM SHT_RELA
244#define Elf32_RelM Elf32_Rela
245#define ELFCLASSM ELFCLASS32
246#define USE_PLT_ENTRIES
247#define PLT_ENTRY_SIZE 8
248#define USE_GOT_ENTRIES
249#define GOT_ENTRY_SIZE 8
250#define USE_SINGLE
251#endif
252
253/* SuperH */
254#if defined(__sh__)
255#define MATCH_MACHINE(x) (x == EM_SH)
256#define SHT_RELM SHT_RELA
257#define Elf32_RelM Elf32_Rela
258#define ELFCLASSM ELFCLASS32
259#define USE_GOT_ENTRIES
260#define GOT_ENTRY_SIZE 4
261#define USE_SINGLE
262/* the SH changes have only been tested in =little endian= mode */
263/* I'm not sure about big endian, so let's warn: */
264#if defined(__sh__) && BB_BIG_ENDIAN
265# error insmod.c may require changes for use on big endian SH
266#endif
267/* it may or may not work on the SH1/SH2... Error on those also */
268#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
269#error insmod.c may require changes for SH1 or SH2 use
270#endif
271#endif
272
273/* Sparc */
274#if defined(__sparc__)
275#define MATCH_MACHINE(x) (x == EM_SPARC)
276#define SHT_RELM SHT_RELA
277#define Elf32_RelM Elf32_Rela
278#define ELFCLASSM ELFCLASS32
279#endif
280
281/* v850e */
282#if defined (__v850e__)
283#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
284#define SHT_RELM SHT_RELA
285#define Elf32_RelM Elf32_Rela
286#define ELFCLASSM ELFCLASS32
287#define USE_PLT_ENTRIES
288#define PLT_ENTRY_SIZE 8
289#define USE_SINGLE
290#ifndef EM_CYGNUS_V850 /* grumble */
291#define EM_CYGNUS_V850 0x9080
292#endif
293#define SYMBOL_PREFIX "_"
294#endif
295
296/* X86_64 */
297#if defined(__x86_64__)
298#define MATCH_MACHINE(x) (x == EM_X86_64)
299#define SHT_RELM SHT_RELA
300#define USE_GOT_ENTRIES
301#define GOT_ENTRY_SIZE 8
302#define USE_SINGLE
303#define Elf64_RelM Elf64_Rela
304#define ELFCLASSM ELFCLASS64
305#endif
306
307#ifndef SHT_RELM
308#error Sorry, but insmod.c does not yet support this architecture...
309#endif
310
311
312//----------------------------------------------------------------------------
313//--------modutils module.h, lines 45-242
314//----------------------------------------------------------------------------
315
316/* Definitions for the Linux module syscall interface.
317 Copyright 1996, 1997 Linux International.
318
319 Contributed by Richard Henderson <rth@tamu.edu>
320
321 This file is part of the Linux modutils.
322
323 This program is free software; you can redistribute it and/or modify it
324 under the terms of the GNU General Public License as published by the
325 Free Software Foundation; either version 2 of the License, or (at your
326 option) any later version.
327
328 This program is distributed in the hope that it will be useful, but
329 WITHOUT ANY WARRANTY; without even the implied warranty of
330 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
331 General Public License for more details.
332
333 You should have received a copy of the GNU General Public License
334 along with this program; if not, write to the Free Software Foundation,
335 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
336
337
338#ifndef MODUTILS_MODULE_H
339/* Why? static const int MODUTILS_MODULE_H = 1;*/
340
341/*======================================================================*/
342/* For sizeof() which are related to the module platform and not to the
343 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
344
345#define tgt_sizeof_char sizeof(char)
346#define tgt_sizeof_short sizeof(short)
347#define tgt_sizeof_int sizeof(int)
348#define tgt_sizeof_long sizeof(long)
349#define tgt_sizeof_char_p sizeof(char *)
350#define tgt_sizeof_void_p sizeof(void *)
351#define tgt_long long
352
353#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
354#undef tgt_sizeof_long
355#undef tgt_sizeof_char_p
356#undef tgt_sizeof_void_p
357#undef tgt_long
358enum {
359 tgt_sizeof_long = 8,
360 tgt_sizeof_char_p = 8,
361 tgt_sizeof_void_p = 8
362};
363#define tgt_long long long
364#endif
365
366/*======================================================================*/
367/* The structures used in Linux 2.1. */
368
369/* Note: new_module_symbol does not use tgt_long intentionally */
370struct new_module_symbol {
371 unsigned long value;
372 unsigned long name;
373};
374
375struct new_module_persist;
376
377struct new_module_ref {
378 unsigned tgt_long dep; /* kernel addresses */
379 unsigned tgt_long ref;
380 unsigned tgt_long next_ref;
381};
382
383struct new_module {
384 unsigned tgt_long size_of_struct; /* == sizeof(module) */
385 unsigned tgt_long next;
386 unsigned tgt_long name;
387 unsigned tgt_long size;
388
389 tgt_long usecount;
390 unsigned tgt_long flags; /* AUTOCLEAN et al */
391
392 unsigned nsyms;
393 unsigned ndeps;
394
395 unsigned tgt_long syms;
396 unsigned tgt_long deps;
397 unsigned tgt_long refs;
398 unsigned tgt_long init;
399 unsigned tgt_long cleanup;
400 unsigned tgt_long ex_table_start;
401 unsigned tgt_long ex_table_end;
402#ifdef __alpha__
403 unsigned tgt_long gp;
404#endif
405 /* Everything after here is extension. */
406 unsigned tgt_long persist_start;
407 unsigned tgt_long persist_end;
408 unsigned tgt_long can_unload;
409 unsigned tgt_long runsize;
410 const char *kallsyms_start; /* All symbols for kernel debugging */
411 const char *kallsyms_end;
412 const char *archdata_start; /* arch specific data for module */
413 const char *archdata_end;
414 const char *kernel_data; /* Reserved for kernel internal use */
415};
416
417#ifdef ARCHDATAM
418#define ARCHDATA_SEC_NAME ARCHDATAM
419#else
420#define ARCHDATA_SEC_NAME "__archdata"
421#endif
422#define KALLSYMS_SEC_NAME "__kallsyms"
423
424
425struct new_module_info {
426 unsigned long addr;
427 unsigned long size;
428 unsigned long flags;
429 long usecount;
430};
431
432/* Bits of module.flags. */
433enum {
434 NEW_MOD_RUNNING = 1,
435 NEW_MOD_DELETED = 2,
436 NEW_MOD_AUTOCLEAN = 4,
437 NEW_MOD_VISITED = 8,
438 NEW_MOD_USED_ONCE = 16
439};
440
441int init_module(const char *name, const struct new_module *);
442int query_module(const char *name, int which, void *buf,
443 size_t bufsize, size_t *ret);
444
445/* Values for query_module's which. */
446enum {
447 QM_MODULES = 1,
448 QM_DEPS = 2,
449 QM_REFS = 3,
450 QM_SYMBOLS = 4,
451 QM_INFO = 5
452};
453
454/*======================================================================*/
455/* The system calls unchanged between 2.0 and 2.1. */
456
457unsigned long create_module(const char *, size_t);
458int delete_module(const char *);
459
460
461#endif /* module.h */
462
463//----------------------------------------------------------------------------
464//--------end of modutils module.h
465//----------------------------------------------------------------------------
466
467
468
469//----------------------------------------------------------------------------
470//--------modutils obj.h, lines 253-462
471//----------------------------------------------------------------------------
472
473/* Elf object file loading and relocation routines.
474 Copyright 1996, 1997 Linux International.
475
476 Contributed by Richard Henderson <rth@tamu.edu>
477
478 This file is part of the Linux modutils.
479
480 This program is free software; you can redistribute it and/or modify it
481 under the terms of the GNU General Public License as published by the
482 Free Software Foundation; either version 2 of the License, or (at your
483 option) any later version.
484
485 This program is distributed in the hope that it will be useful, but
486 WITHOUT ANY WARRANTY; without even the implied warranty of
487 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
488 General Public License for more details.
489
490 You should have received a copy of the GNU General Public License
491 along with this program; if not, write to the Free Software Foundation,
492 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
493
494
495#ifndef MODUTILS_OBJ_H
496/* Why? static const int MODUTILS_OBJ_H = 1; */
497
498/* The relocatable object is manipulated using elfin types. */
499
500#include <stdio.h>
501#include <elf.h>
502#include <endian.h>
503
504#ifndef ElfW
505# if ELFCLASSM == ELFCLASS32
506# define ElfW(x) Elf32_ ## x
507# define ELFW(x) ELF32_ ## x
508# else
509# define ElfW(x) Elf64_ ## x
510# define ELFW(x) ELF64_ ## x
511# endif
512#endif
513
514/* For some reason this is missing from some ancient C libraries.... */
515#ifndef ELF32_ST_INFO
516# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
517#endif
518
519#ifndef ELF64_ST_INFO
520# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
521#endif
522
523#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
524#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
525#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
526#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
527#define ELF_R_SYM(val) ELFW(R_SYM)(val)
528
529struct obj_string_patch;
530struct obj_symbol_patch;
531
532struct obj_section
533{
534 ElfW(Shdr) header;
535 const char *name;
536 char *contents;
537 struct obj_section *load_next;
538 int idx;
539};
540
541struct obj_symbol
542{
543 struct obj_symbol *next; /* hash table link */
544 const char *name;
545 unsigned long value;
546 unsigned long size;
547 int secidx; /* the defining section index/module */
548 int info;
549 int ksymidx; /* for export to the kernel symtab */
550 int referenced; /* actually used in the link */
551};
552
553/* Hardcode the hash table size. We shouldn't be needing so many
554 symbols that we begin to degrade performance, and we get a big win
555 by giving the compiler a constant divisor. */
556
557#define HASH_BUCKETS 521
558
559struct obj_file {
560 ElfW(Ehdr) header;
561 ElfW(Addr) baseaddr;
562 struct obj_section **sections;
563 struct obj_section *load_order;
564 struct obj_section **load_order_search_start;
565 struct obj_string_patch *string_patches;
566 struct obj_symbol_patch *symbol_patches;
567 int (*symbol_cmp)(const char *, const char *);
568 unsigned long (*symbol_hash)(const char *);
569 unsigned long local_symtab_size;
570 struct obj_symbol **local_symtab;
571 struct obj_symbol *symtab[HASH_BUCKETS];
572};
573
574enum obj_reloc {
575 obj_reloc_ok,
576 obj_reloc_overflow,
577 obj_reloc_dangerous,
578 obj_reloc_unhandled
579};
580
581struct obj_string_patch {
582 struct obj_string_patch *next;
583 int reloc_secidx;
584 ElfW(Addr) reloc_offset;
585 ElfW(Addr) string_offset;
586};
587
588struct obj_symbol_patch {
589 struct obj_symbol_patch *next;
590 int reloc_secidx;
591 ElfW(Addr) reloc_offset;
592 struct obj_symbol *sym;
593};
594
595
596/* Generic object manipulation routines. */
597
598static unsigned long obj_elf_hash(const char *);
599
600static unsigned long obj_elf_hash_n(const char *, unsigned long len);
601
602static struct obj_symbol *obj_find_symbol (struct obj_file *f,
603 const char *name);
604
605static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
606 struct obj_symbol *sym);
607
608#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
609static void obj_set_symbol_compare(struct obj_file *f,
610 int (*cmp)(const char *, const char *),
611 unsigned long (*hash)(const char *));
612#endif
613
614static struct obj_section *obj_find_section (struct obj_file *f,
615 const char *name);
616
617static void obj_insert_section_load_order (struct obj_file *f,
618 struct obj_section *sec);
619
620static struct obj_section *obj_create_alloced_section (struct obj_file *f,
621 const char *name,
622 unsigned long align,
623 unsigned long size);
624
625static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
626 const char *name,
627 unsigned long align,
628 unsigned long size);
629
630static void *obj_extend_section (struct obj_section *sec, unsigned long more);
631
632static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
633 const char *string);
634
635static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
636 struct obj_symbol *sym);
637
638static int obj_check_undefineds(struct obj_file *f);
639
640static void obj_allocate_commons(struct obj_file *f);
641
642static unsigned long obj_load_size (struct obj_file *f);
643
644static int obj_relocate (struct obj_file *f, ElfW(Addr) base);
645
646static struct obj_file *obj_load(FILE *f, int loadprogbits);
647
648static int obj_create_image (struct obj_file *f, char *image);
649
650/* Architecture specific manipulation routines. */
651
652static struct obj_file *arch_new_file (void);
653
654static struct obj_section *arch_new_section (void);
655
656static struct obj_symbol *arch_new_symbol (void);
657
658static enum obj_reloc arch_apply_relocation (struct obj_file *f,
659 struct obj_section *targsec,
660 struct obj_section *symsec,
661 struct obj_symbol *sym,
662 ElfW(RelM) *rel, ElfW(Addr) value);
663
664static void arch_create_got (struct obj_file *f);
665#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
666static int obj_gpl_license(struct obj_file *f, const char **license);
667#endif /* FEATURE_CHECK_TAINTED_MODULE */
668#endif /* obj.h */
669//----------------------------------------------------------------------------
670//--------end of modutils obj.h
671//----------------------------------------------------------------------------
672
673
674/* SPFX is always a string, so it can be concatenated to string constants. */
675#ifdef SYMBOL_PREFIX
676#define SPFX SYMBOL_PREFIX
677#else
678#define SPFX ""
679#endif
680
681
682#define _PATH_MODULES "/lib/modules"
683enum { STRVERSIONLEN = 64 };
684
685/*======================================================================*/
686
687#define OPTION_STR "sLo:fkvqx" USE_FEATURE_INSMOD_LOAD_MAP("m")
688enum {
689 OPT_s = 0x1, // -s /* log to syslog */
690 /* Not supported but kernel needs this for request_module(),
691 as this calls: modprobe -k -s -- <module>
692 so silently ignore this flag */
693 OPT_L = 0x2, // -L /* Stub warning */
694 /* Compatibility with modprobe.
695 In theory, this does locking, but we don't do
696 that. So be careful and plan your life around not
697 loading the same module 50 times concurrently. */
698 OPT_o = 0x4, // -o /* name the output module */
699 OPT_f = 0x8, // -f /* force loading */
700 OPT_k = 0x10, // -k /* module loaded by kerneld, auto-cleanable */
701 OPT_v = 0x20, // -v /* verbose output */
702 OPT_q = 0x40, // -q /* silent */
703 OPT_x = 0x80, // -x /* do not export externs */
704 OPT_m = 0x100, // -m /* print module load map */
705};
706#define flag_force_load (option_mask32 & OPT_f)
707#define flag_autoclean (option_mask32 & OPT_k)
708#define flag_verbose (option_mask32 & OPT_v)
709#define flag_quiet (option_mask32 & OPT_q)
710#define flag_noexport (option_mask32 & OPT_x)
711#if ENABLE_FEATURE_INSMOD_LOAD_MAP
712#define flag_print_load_map (option_mask32 & OPT_m)
713#else
714#define flag_print_load_map 0
715#endif
716
717/*======================================================================*/
718
719#if defined(USE_LIST)
720
721struct arch_list_entry
722{
723 struct arch_list_entry *next;
724 LIST_ARCHTYPE addend;
725 int offset;
726 int inited : 1;
727};
728
729#endif
730
731#if defined(USE_SINGLE)
732
733struct arch_single_entry
734{
735 int offset;
736 int inited : 1;
737 int allocated : 1;
738};
739
740#endif
741
742#if defined(__mips__)
743struct mips_hi16
744{
745 struct mips_hi16 *next;
746 ElfW(Addr) *addr;
747 ElfW(Addr) value;
748};
749#endif
750
751struct arch_file {
752 struct obj_file root;
753#if defined(USE_PLT_ENTRIES)
754 struct obj_section *plt;
755#endif
756#if defined(USE_GOT_ENTRIES)
757 struct obj_section *got;
758#endif
759#if defined(__mips__)
760 struct mips_hi16 *mips_hi16_list;
761#endif
762};
763
764struct arch_symbol {
765 struct obj_symbol root;
766#if defined(USE_PLT_ENTRIES)
767#if defined(USE_PLT_LIST)
768 struct arch_list_entry *pltent;
769#else
770 struct arch_single_entry pltent;
771#endif
772#endif
773#if defined(USE_GOT_ENTRIES)
774 struct arch_single_entry gotent;
775#endif
776};
777
778
779struct external_module {
780 const char *name;
781 ElfW(Addr) addr;
782 int used;
783 size_t nsyms;
784 struct new_module_symbol *syms;
785};
786
787static struct new_module_symbol *ksyms;
788static size_t nksyms;
789
790static struct external_module *ext_modules;
791static int n_ext_modules;
792static int n_ext_modules_used;
793extern int delete_module(const char *);
794
795static char *m_filename;
796static char *m_fullName;
797
798
799/*======================================================================*/
800
801
802static int check_module_name_match(const char *filename, struct stat *statbuf,
803 void *userdata, int depth)
804{
805 char *fullname = (char *) userdata;
806
807 if (fullname[0] == '\0')
808 return FALSE;
809 else {
810 char *tmp, *tmp1 = xstrdup(filename);
811 tmp = bb_get_last_path_component(tmp1);
812 if (strcmp(tmp, fullname) == 0) {
813 free(tmp1);
814 /* Stop searching if we find a match */
815 m_filename = xstrdup(filename);
816 return FALSE;
817 }
818 free(tmp1);
819 }
820 return TRUE;
821}
822
823
824/*======================================================================*/
825
826static struct obj_file *arch_new_file(void)
827{
828 struct arch_file *f;
829 f = xmalloc(sizeof(*f));
830
831 memset(f, 0, sizeof(*f));
832
833 return &f->root;
834}
835
836static struct obj_section *arch_new_section(void)
837{
838 return xmalloc(sizeof(struct obj_section));
839}
840
841static struct obj_symbol *arch_new_symbol(void)
842{
843 struct arch_symbol *sym;
844 sym = xmalloc(sizeof(*sym));
845
846 memset(sym, 0, sizeof(*sym));
847
848 return &sym->root;
849}
850
851static enum obj_reloc
852arch_apply_relocation(struct obj_file *f,
853 struct obj_section *targsec,
854 struct obj_section *symsec,
855 struct obj_symbol *sym,
856 ElfW(RelM) *rel, ElfW(Addr) v)
857{
858 struct arch_file *ifile = (struct arch_file *) f;
859 enum obj_reloc ret = obj_reloc_ok;
860 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
861 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
862#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
863 struct arch_symbol *isym = (struct arch_symbol *) sym;
864#endif
865#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) || defined(__sh__) || defined(__s390__)
866#if defined(USE_GOT_ENTRIES)
867 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
868#endif
869#endif
870#if defined(USE_PLT_ENTRIES)
871 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
872 unsigned long *ip;
873# if defined(USE_PLT_LIST)
874 struct arch_list_entry *pe;
875# else
876 struct arch_single_entry *pe;
877# endif
878#endif
879
880 switch (ELF_R_TYPE(rel->r_info)) {
881
882#if defined(__arm__)
883
884 case R_ARM_NONE:
885 break;
886
887 case R_ARM_ABS32:
888 *loc += v;
889 break;
890
891 case R_ARM_GOT32:
892 goto bb_use_got;
893
894 case R_ARM_GOTPC:
895 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
896 * (which is .got) similar to branch,
897 * but is full 32 bits relative */
898
899 *loc += got - dot;
900 break;
901
902 case R_ARM_PC24:
903 case R_ARM_PLT32:
904 goto bb_use_plt;
905
906 case R_ARM_GOTOFF: /* address relative to the got */
907 *loc += v - got;
908 break;
909
910#elif defined(__cris__)
911
912 case R_CRIS_NONE:
913 break;
914
915 case R_CRIS_32:
916 /* CRIS keeps the relocation value in the r_addend field and
917 * should not use whats in *loc at all
918 */
919 *loc = v;
920 break;
921
922#elif defined(__H8300H__) || defined(__H8300S__)
923
924 case R_H8_DIR24R8:
925 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
926 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
927 break;
928 case R_H8_DIR24A8:
929 *loc += v;
930 break;
931 case R_H8_DIR32:
932 case R_H8_DIR32A16:
933 *loc += v;
934 break;
935 case R_H8_PCREL16:
936 v -= dot + 2;
937 if ((ElfW(Sword))v > 0x7fff ||
938 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
939 ret = obj_reloc_overflow;
940 else
941 *(unsigned short *)loc = v;
942 break;
943 case R_H8_PCREL8:
944 v -= dot + 1;
945 if ((ElfW(Sword))v > 0x7f ||
946 (ElfW(Sword))v < -(ElfW(Sword))0x80)
947 ret = obj_reloc_overflow;
948 else
949 *(unsigned char *)loc = v;
950 break;
951
952#elif defined(__i386__)
953
954 case R_386_NONE:
955 break;
956
957 case R_386_32:
958 *loc += v;
959 break;
960
961 case R_386_PLT32:
962 case R_386_PC32:
963 *loc += v - dot;
964 break;
965
966 case R_386_GLOB_DAT:
967 case R_386_JMP_SLOT:
968 *loc = v;
969 break;
970
971 case R_386_RELATIVE:
972 *loc += f->baseaddr;
973 break;
974
975 case R_386_GOTPC:
976 *loc += got - dot;
977 break;
978
979 case R_386_GOT32:
980 goto bb_use_got;
981
982 case R_386_GOTOFF:
983 *loc += v - got;
984 break;
985
986#elif defined (__microblaze__)
987 case R_MICROBLAZE_NONE:
988 case R_MICROBLAZE_64_NONE:
989 case R_MICROBLAZE_32_SYM_OP_SYM:
990 case R_MICROBLAZE_32_PCREL:
991 break;
992
993 case R_MICROBLAZE_64_PCREL: {
994 /* dot is the address of the current instruction.
995 * v is the target symbol address.
996 * So we need to extract the offset in the code,
997 * adding v, then subtrating the current address
998 * of this instruction.
999 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
1000 */
1001
1002 /* Get split offset stored in code */
1003 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
1004 (loc[1] & 0xFFFF);
1005
1006 /* Adjust relative offset. -4 adjustment required
1007 * because dot points to the IMM insn, but branch
1008 * is computed relative to the branch instruction itself.
1009 */
1010 temp += v - dot - 4;
1011
1012 /* Store back into code */
1013 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
1014 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
1015
1016 break;
1017 }
1018
1019 case R_MICROBLAZE_32:
1020 *loc += v;
1021 break;
1022
1023 case R_MICROBLAZE_64: {
1024 /* Get split pointer stored in code */
1025 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
1026 (loc[1] & 0xFFFF);
1027
1028 /* Add reloc offset */
1029 temp1+=v;
1030
1031 /* Store back into code */
1032 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
1033 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
1034
1035 break;
1036 }
1037
1038 case R_MICROBLAZE_32_PCREL_LO:
1039 case R_MICROBLAZE_32_LO:
1040 case R_MICROBLAZE_SRO32:
1041 case R_MICROBLAZE_SRW32:
1042 ret = obj_reloc_unhandled;
1043 break;
1044
1045#elif defined(__mc68000__)
1046
1047 case R_68K_NONE:
1048 break;
1049
1050 case R_68K_32:
1051 *loc += v;
1052 break;
1053
1054 case R_68K_8:
1055 if (v > 0xff) {
1056 ret = obj_reloc_overflow;
1057 }
1058 *(char *)loc = v;
1059 break;
1060
1061 case R_68K_16:
1062 if (v > 0xffff) {
1063 ret = obj_reloc_overflow;
1064 }
1065 *(short *)loc = v;
1066 break;
1067
1068 case R_68K_PC8:
1069 v -= dot;
1070 if ((ElfW(Sword))v > 0x7f ||
1071 (ElfW(Sword))v < -(ElfW(Sword))0x80) {
1072 ret = obj_reloc_overflow;
1073 }
1074 *(char *)loc = v;
1075 break;
1076
1077 case R_68K_PC16:
1078 v -= dot;
1079 if ((ElfW(Sword))v > 0x7fff ||
1080 (ElfW(Sword))v < -(ElfW(Sword))0x8000) {
1081 ret = obj_reloc_overflow;
1082 }
1083 *(short *)loc = v;
1084 break;
1085
1086 case R_68K_PC32:
1087 *(int *)loc = v - dot;
1088 break;
1089
1090 case R_68K_GLOB_DAT:
1091 case R_68K_JMP_SLOT:
1092 *loc = v;
1093 break;
1094
1095 case R_68K_RELATIVE:
1096 *(int *)loc += f->baseaddr;
1097 break;
1098
1099 case R_68K_GOT32:
1100 goto bb_use_got;
1101
1102# ifdef R_68K_GOTOFF
1103 case R_68K_GOTOFF:
1104 *loc += v - got;
1105 break;
1106# endif
1107
1108#elif defined(__mips__)
1109
1110 case R_MIPS_NONE:
1111 break;
1112
1113 case R_MIPS_32:
1114 *loc += v;
1115 break;
1116
1117 case R_MIPS_26:
1118 if (v % 4)
1119 ret = obj_reloc_dangerous;
1120 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1121 ret = obj_reloc_overflow;
1122 *loc =
1123 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1124 0x03ffffff);
1125 break;
1126
1127 case R_MIPS_HI16:
1128 {
1129 struct mips_hi16 *n;
1130
1131 /* We cannot relocate this one now because we don't know the value
1132 of the carry we need to add. Save the information, and let LO16
1133 do the actual relocation. */
1134 n = (struct mips_hi16 *) xmalloc(sizeof *n);
1135 n->addr = loc;
1136 n->value = v;
1137 n->next = ifile->mips_hi16_list;
1138 ifile->mips_hi16_list = n;
1139 break;
1140 }
1141
1142 case R_MIPS_LO16:
1143 {
1144 unsigned long insnlo = *loc;
1145 ElfW(Addr) val, vallo;
1146
1147 /* Sign extend the addend we extract from the lo insn. */
1148 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1149
1150 if (ifile->mips_hi16_list != NULL) {
1151 struct mips_hi16 *l;
1152
1153 l = ifile->mips_hi16_list;
1154 while (l != NULL) {
1155 struct mips_hi16 *next;
1156 unsigned long insn;
1157
1158 /* Do the HI16 relocation. Note that we actually don't
1159 need to know anything about the LO16 itself, except where
1160 to find the low 16 bits of the addend needed by the LO16. */
1161 insn = *l->addr;
1162 val =
1163 ((insn & 0xffff) << 16) +
1164 vallo;
1165 val += v;
1166
1167 /* Account for the sign extension that will happen in the
1168 low bits. */
1169 val =
1170 ((val >> 16) +
1171 ((val & 0x8000) !=
1172 0)) & 0xffff;
1173
1174 insn = (insn & ~0xffff) | val;
1175 *l->addr = insn;
1176
1177 next = l->next;
1178 free(l);
1179 l = next;
1180 }
1181
1182 ifile->mips_hi16_list = NULL;
1183 }
1184
1185 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1186 val = v + vallo;
1187 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1188 *loc = insnlo;
1189 break;
1190 }
1191
1192#elif defined(__nios2__)
1193
1194 case R_NIOS2_NONE:
1195 break;
1196
1197 case R_NIOS2_BFD_RELOC_32:
1198 *loc += v;
1199 break;
1200
1201 case R_NIOS2_BFD_RELOC_16:
1202 if (v > 0xffff) {
1203 ret = obj_reloc_overflow;
1204 }
1205 *(short *)loc = v;
1206 break;
1207
1208 case R_NIOS2_BFD_RELOC_8:
1209 if (v > 0xff) {
1210 ret = obj_reloc_overflow;
1211 }
1212 *(char *)loc = v;
1213 break;
1214
1215 case R_NIOS2_S16:
1216 {
1217 Elf32_Addr word;
1218
1219 if ((Elf32_Sword)v > 0x7fff ||
1220 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1221 ret = obj_reloc_overflow;
1222 }
1223
1224 word = *loc;
1225 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1226 (word & 0x3f);
1227 }
1228 break;
1229
1230 case R_NIOS2_U16:
1231 {
1232 Elf32_Addr word;
1233
1234 if (v > 0xffff) {
1235 ret = obj_reloc_overflow;
1236 }
1237
1238 word = *loc;
1239 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1240 (word & 0x3f);
1241 }
1242 break;
1243
1244 case R_NIOS2_PCREL16:
1245 {
1246 Elf32_Addr word;
1247
1248 v -= dot + 4;
1249 if ((Elf32_Sword)v > 0x7fff ||
1250 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1251 ret = obj_reloc_overflow;
1252 }
1253
1254 word = *loc;
1255 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1256 }
1257 break;
1258
1259 case R_NIOS2_GPREL:
1260 {
1261 Elf32_Addr word, gp;
1262 /* get _gp */
1263 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
1264 v-=gp;
1265 if ((Elf32_Sword)v > 0x7fff ||
1266 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1267 ret = obj_reloc_overflow;
1268 }
1269
1270 word = *loc;
1271 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1272 }
1273 break;
1274
1275 case R_NIOS2_CALL26:
1276 if (v & 3)
1277 ret = obj_reloc_dangerous;
1278 if ((v >> 28) != (dot >> 28))
1279 ret = obj_reloc_overflow;
1280 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1281 break;
1282
1283 case R_NIOS2_IMM5:
1284 {
1285 Elf32_Addr word;
1286
1287 if (v > 0x1f) {
1288 ret = obj_reloc_overflow;
1289 }
1290
1291 word = *loc & ~0x7c0;
1292 *loc = word | ((v & 0x1f) << 6);
1293 }
1294 break;
1295
1296 case R_NIOS2_IMM6:
1297 {
1298 Elf32_Addr word;
1299
1300 if (v > 0x3f) {
1301 ret = obj_reloc_overflow;
1302 }
1303
1304 word = *loc & ~0xfc0;
1305 *loc = word | ((v & 0x3f) << 6);
1306 }
1307 break;
1308
1309 case R_NIOS2_IMM8:
1310 {
1311 Elf32_Addr word;
1312
1313 if (v > 0xff) {
1314 ret = obj_reloc_overflow;
1315 }
1316
1317 word = *loc & ~0x3fc0;
1318 *loc = word | ((v & 0xff) << 6);
1319 }
1320 break;
1321
1322 case R_NIOS2_HI16:
1323 {
1324 Elf32_Addr word;
1325
1326 word = *loc;
1327 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1328 (word & 0x3f);
1329 }
1330 break;
1331
1332 case R_NIOS2_LO16:
1333 {
1334 Elf32_Addr word;
1335
1336 word = *loc;
1337 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1338 (word & 0x3f);
1339 }
1340 break;
1341
1342 case R_NIOS2_HIADJ16:
1343 {
1344 Elf32_Addr word1, word2;
1345
1346 word1 = *loc;
1347 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1348 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1349 (word1 & 0x3f);
1350 }
1351 break;
1352
1353#elif defined(__powerpc64__)
1354 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
1355
1356#elif defined(__powerpc__)
1357
1358 case R_PPC_ADDR16_HA:
1359 *(unsigned short *)loc = (v + 0x8000) >> 16;
1360 break;
1361
1362 case R_PPC_ADDR16_HI:
1363 *(unsigned short *)loc = v >> 16;
1364 break;
1365
1366 case R_PPC_ADDR16_LO:
1367 *(unsigned short *)loc = v;
1368 break;
1369
1370 case R_PPC_REL24:
1371 goto bb_use_plt;
1372
1373 case R_PPC_REL32:
1374 *loc = v - dot;
1375 break;
1376
1377 case R_PPC_ADDR32:
1378 *loc = v;
1379 break;
1380
1381#elif defined(__s390__)
1382
1383 case R_390_32:
1384 *(unsigned int *) loc += v;
1385 break;
1386 case R_390_16:
1387 *(unsigned short *) loc += v;
1388 break;
1389 case R_390_8:
1390 *(unsigned char *) loc += v;
1391 break;
1392
1393 case R_390_PC32:
1394 *(unsigned int *) loc += v - dot;
1395 break;
1396 case R_390_PC16DBL:
1397 *(unsigned short *) loc += (v - dot) >> 1;
1398 break;
1399 case R_390_PC16:
1400 *(unsigned short *) loc += v - dot;
1401 break;
1402
1403 case R_390_PLT32:
1404 case R_390_PLT16DBL:
1405 /* find the plt entry and initialize it. */
1406 pe = (struct arch_single_entry *) &isym->pltent;
1407 if (pe->inited == 0) {
1408 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1409 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1410 ip[1] = 0x100607f1;
1411 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1412 ip[2] = v - 2;
1413 else
1414 ip[2] = v;
1415 pe->inited = 1;
1416 }
1417
1418 /* Insert relative distance to target. */
1419 v = plt + pe->offset - dot;
1420 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1421 *(unsigned int *) loc = (unsigned int) v;
1422 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1423 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1424 break;
1425
1426 case R_390_GLOB_DAT:
1427 case R_390_JMP_SLOT:
1428 *loc = v;
1429 break;
1430
1431 case R_390_RELATIVE:
1432 *loc += f->baseaddr;
1433 break;
1434
1435 case R_390_GOTPC:
1436 *(unsigned long *) loc += got - dot;
1437 break;
1438
1439 case R_390_GOT12:
1440 case R_390_GOT16:
1441 case R_390_GOT32:
1442 if (!isym->gotent.inited)
1443 {
1444 isym->gotent.inited = 1;
1445 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1446 }
1447 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1448 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1449 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1450 *(unsigned short *) loc += isym->gotent.offset;
1451 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1452 *(unsigned int *) loc += isym->gotent.offset;
1453 break;
1454
1455# ifndef R_390_GOTOFF32
1456# define R_390_GOTOFF32 R_390_GOTOFF
1457# endif
1458 case R_390_GOTOFF32:
1459 *loc += v - got;
1460 break;
1461
1462#elif defined(__sh__)
1463
1464 case R_SH_NONE:
1465 break;
1466
1467 case R_SH_DIR32:
1468 *loc += v;
1469 break;
1470
1471 case R_SH_REL32:
1472 *loc += v - dot;
1473 break;
1474
1475 case R_SH_PLT32:
1476 *loc = v - dot;
1477 break;
1478
1479 case R_SH_GLOB_DAT:
1480 case R_SH_JMP_SLOT:
1481 *loc = v;
1482 break;
1483
1484 case R_SH_RELATIVE:
1485 *loc = f->baseaddr + rel->r_addend;
1486 break;
1487
1488 case R_SH_GOTPC:
1489 *loc = got - dot + rel->r_addend;
1490 break;
1491
1492 case R_SH_GOT32:
1493 goto bb_use_got;
1494
1495 case R_SH_GOTOFF:
1496 *loc = v - got;
1497 break;
1498
1499# if defined(__SH5__)
1500 case R_SH_IMM_MEDLOW16:
1501 case R_SH_IMM_LOW16:
1502 {
1503 ElfW(Addr) word;
1504
1505 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1506 v >>= 16;
1507
1508 /*
1509 * movi and shori have the format:
1510 *
1511 * | op | imm | reg | reserved |
1512 * 31..26 25..10 9.. 4 3 .. 0
1513 *
1514 * so we simply mask and or in imm.
1515 */
1516 word = *loc & ~0x3fffc00;
1517 word |= (v & 0xffff) << 10;
1518
1519 *loc = word;
1520
1521 break;
1522 }
1523
1524 case R_SH_IMM_MEDLOW16_PCREL:
1525 case R_SH_IMM_LOW16_PCREL:
1526 {
1527 ElfW(Addr) word;
1528
1529 word = *loc & ~0x3fffc00;
1530
1531 v -= dot;
1532
1533 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1534 v >>= 16;
1535
1536 word |= (v & 0xffff) << 10;
1537
1538 *loc = word;
1539
1540 break;
1541 }
1542# endif /* __SH5__ */
1543
1544#elif defined (__v850e__)
1545
1546 case R_V850_NONE:
1547 break;
1548
1549 case R_V850_32:
1550 /* We write two shorts instead of a long because even
1551 32-bit insns only need half-word alignment, but
1552 32-bit data needs to be long-word aligned. */
1553 v += ((unsigned short *)loc)[0];
1554 v += ((unsigned short *)loc)[1] << 16;
1555 ((unsigned short *)loc)[0] = v & 0xffff;
1556 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1557 break;
1558
1559 case R_V850_22_PCREL:
1560 goto bb_use_plt;
1561
1562#elif defined(__x86_64__)
1563
1564 case R_X86_64_NONE:
1565 break;
1566
1567 case R_X86_64_64:
1568 *loc += v;
1569 break;
1570
1571 case R_X86_64_32:
1572 *(unsigned int *) loc += v;
1573 if (v > 0xffffffff)
1574 {
1575 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1576 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1577 }
1578 break;
1579
1580 case R_X86_64_32S:
1581 *(signed int *) loc += v;
1582 break;
1583
1584 case R_X86_64_16:
1585 *(unsigned short *) loc += v;
1586 break;
1587
1588 case R_X86_64_8:
1589 *(unsigned char *) loc += v;
1590 break;
1591
1592 case R_X86_64_PC32:
1593 *(unsigned int *) loc += v - dot;
1594 break;
1595
1596 case R_X86_64_PC16:
1597 *(unsigned short *) loc += v - dot;
1598 break;
1599
1600 case R_X86_64_PC8:
1601 *(unsigned char *) loc += v - dot;
1602 break;
1603
1604 case R_X86_64_GLOB_DAT:
1605 case R_X86_64_JUMP_SLOT:
1606 *loc = v;
1607 break;
1608
1609 case R_X86_64_RELATIVE:
1610 *loc += f->baseaddr;
1611 break;
1612
1613 case R_X86_64_GOT32:
1614 case R_X86_64_GOTPCREL:
1615 goto bb_use_got;
1616# if 0
1617 if (!isym->gotent.reloc_done)
1618 {
1619 isym->gotent.reloc_done = 1;
1620 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1621 }
1622 /* XXX are these really correct? */
1623 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1624 *(unsigned int *) loc += v + isym->gotent.offset;
1625 else
1626 *loc += isym->gotent.offset;
1627 break;
1628# endif
1629
1630#else
1631# warning "no idea how to handle relocations on your arch"
1632#endif
1633
1634 default:
1635 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1636 ret = obj_reloc_unhandled;
1637 break;
1638
1639#if defined(USE_PLT_ENTRIES)
1640
1641bb_use_plt:
1642
1643 /* find the plt entry and initialize it if necessary */
1644
1645#if defined(USE_PLT_LIST)
1646 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1647 pe = pe->next;
1648#else
1649 pe = &isym->pltent;
1650#endif
1651
1652 if (! pe->inited) {
1653 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1654
1655 /* generate some machine code */
1656
1657#if defined(__arm__)
1658 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1659 ip[1] = v; /* sym@ */
1660#endif
1661#if defined(__powerpc__)
1662 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1663 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1664 ip[2] = 0x7d6903a6; /* mtctr r11 */
1665 ip[3] = 0x4e800420; /* bctr */
1666#endif
1667#if defined (__v850e__)
1668 /* We have to trash a register, so we assume that any control
1669 transfer more than 21-bits away must be a function call
1670 (so we can use a call-clobbered register). */
1671 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1672 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
1673#endif
1674 pe->inited = 1;
1675 }
1676
1677 /* relative distance to target */
1678 v -= dot;
1679 /* if the target is too far away.... */
1680#if defined (__arm__) || defined (__powerpc__)
1681 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1682#elif defined (__v850e__)
1683 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1684#endif
1685 /* go via the plt */
1686 v = plt + pe->offset - dot;
1687
1688#if defined (__v850e__)
1689 if (v & 1)
1690#else
1691 if (v & 3)
1692#endif
1693 ret = obj_reloc_dangerous;
1694
1695 /* merge the offset into the instruction. */
1696#if defined(__arm__)
1697 /* Convert to words. */
1698 v >>= 2;
1699
1700 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1701#endif
1702#if defined(__powerpc__)
1703 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1704#endif
1705#if defined (__v850e__)
1706 /* We write two shorts instead of a long because even 32-bit insns
1707 only need half-word alignment, but the 32-bit data write needs
1708 to be long-word aligned. */
1709 ((unsigned short *)loc)[0] =
1710 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1711 | ((v >> 16) & 0x3f); /* offs high part */
1712 ((unsigned short *)loc)[1] =
1713 (v & 0xffff); /* offs low part */
1714#endif
1715 break;
1716#endif /* USE_PLT_ENTRIES */
1717
1718#if defined(USE_GOT_ENTRIES)
1719bb_use_got:
1720
1721 /* needs an entry in the .got: set it, once */
1722 if (!isym->gotent.inited) {
1723 isym->gotent.inited = 1;
1724 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1725 }
1726 /* make the reloc with_respect_to_.got */
1727#if defined(__sh__)
1728 *loc += isym->gotent.offset + rel->r_addend;
1729#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1730 *loc += isym->gotent.offset;
1731#endif
1732 break;
1733
1734#endif /* USE_GOT_ENTRIES */
1735 }
1736
1737 return ret;
1738}
1739
1740
1741#if defined(USE_LIST)
1742
1743static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1744 int offset, int size)
1745{
1746 struct arch_list_entry *pe;
1747
1748 for (pe = *list; pe != NULL; pe = pe->next) {
1749 if (pe->addend == rel->r_addend) {
1750 break;
1751 }
1752 }
1753
1754 if (pe == NULL) {
1755 pe = xmalloc(sizeof(struct arch_list_entry));
1756 pe->next = *list;
1757 pe->addend = rel->r_addend;
1758 pe->offset = offset;
1759 pe->inited = 0;
1760 *list = pe;
1761 return size;
1762 }
1763 return 0;
1764}
1765
1766#endif
1767
1768#if defined(USE_SINGLE)
1769
1770static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
1771 int offset, int size)
1772{
1773 if (single->allocated == 0) {
1774 single->allocated = 1;
1775 single->offset = offset;
1776 single->inited = 0;
1777 return size;
1778 }
1779 return 0;
1780}
1781
1782#endif
1783
1784#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1785
1786static struct obj_section *arch_xsect_init(struct obj_file *f, char *name,
1787 int offset, int size)
1788{
1789 struct obj_section *myrelsec = obj_find_section(f, name);
1790
1791 if (offset == 0) {
1792 offset += size;
1793 }
1794
1795 if (myrelsec) {
1796 obj_extend_section(myrelsec, offset);
1797 } else {
1798 myrelsec = obj_create_alloced_section(f, name,
1799 size, offset);
1800 }
1801
1802 return myrelsec;
1803}
1804
1805#endif
1806
1807static void arch_create_got(struct obj_file *f)
1808{
1809#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1810 struct arch_file *ifile = (struct arch_file *) f;
1811 int i;
1812#if defined(USE_GOT_ENTRIES)
1813 int got_offset = 0, got_needed = 0, got_allocate;
1814#endif
1815#if defined(USE_PLT_ENTRIES)
1816 int plt_offset = 0, plt_needed = 0, plt_allocate;
1817#endif
1818 struct obj_section *relsec, *symsec, *strsec;
1819 ElfW(RelM) *rel, *relend;
1820 ElfW(Sym) *symtab, *extsym;
1821 const char *strtab, *name;
1822 struct arch_symbol *intsym;
1823
1824 for (i = 0; i < f->header.e_shnum; ++i) {
1825 relsec = f->sections[i];
1826 if (relsec->header.sh_type != SHT_RELM)
1827 continue;
1828
1829 symsec = f->sections[relsec->header.sh_link];
1830 strsec = f->sections[symsec->header.sh_link];
1831
1832 rel = (ElfW(RelM) *) relsec->contents;
1833 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1834 symtab = (ElfW(Sym) *) symsec->contents;
1835 strtab = (const char *) strsec->contents;
1836
1837 for (; rel < relend; ++rel) {
1838 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1839
1840#if defined(USE_GOT_ENTRIES)
1841 got_allocate = 0;
1842#endif
1843#if defined(USE_PLT_ENTRIES)
1844 plt_allocate = 0;
1845#endif
1846
1847 switch (ELF_R_TYPE(rel->r_info)) {
1848#if defined(__arm__)
1849 case R_ARM_PC24:
1850 case R_ARM_PLT32:
1851 plt_allocate = 1;
1852 break;
1853
1854 case R_ARM_GOTOFF:
1855 case R_ARM_GOTPC:
1856 got_needed = 1;
1857 continue;
1858
1859 case R_ARM_GOT32:
1860 got_allocate = 1;
1861 break;
1862
1863#elif defined(__i386__)
1864 case R_386_GOTPC:
1865 case R_386_GOTOFF:
1866 got_needed = 1;
1867 continue;
1868
1869 case R_386_GOT32:
1870 got_allocate = 1;
1871 break;
1872
1873#elif defined(__powerpc__)
1874 case R_PPC_REL24:
1875 plt_allocate = 1;
1876 break;
1877
1878#elif defined(__mc68000__)
1879 case R_68K_GOT32:
1880 got_allocate = 1;
1881 break;
1882
1883#ifdef R_68K_GOTOFF
1884 case R_68K_GOTOFF:
1885 got_needed = 1;
1886 continue;
1887#endif
1888
1889#elif defined(__sh__)
1890 case R_SH_GOT32:
1891 got_allocate = 1;
1892 break;
1893
1894 case R_SH_GOTPC:
1895 case R_SH_GOTOFF:
1896 got_needed = 1;
1897 continue;
1898
1899#elif defined (__v850e__)
1900 case R_V850_22_PCREL:
1901 plt_needed = 1;
1902 break;
1903
1904#endif
1905 default:
1906 continue;
1907 }
1908
1909 if (extsym->st_name != 0) {
1910 name = strtab + extsym->st_name;
1911 } else {
1912 name = f->sections[extsym->st_shndx]->name;
1913 }
1914 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1915#if defined(USE_GOT_ENTRIES)
1916 if (got_allocate) {
1917 got_offset += arch_single_init(
1918 rel, &intsym->gotent,
1919 got_offset, GOT_ENTRY_SIZE);
1920
1921 got_needed = 1;
1922 }
1923#endif
1924#if defined(USE_PLT_ENTRIES)
1925 if (plt_allocate) {
1926#if defined(USE_PLT_LIST)
1927 plt_offset += arch_list_add(
1928 rel, &intsym->pltent,
1929 plt_offset, PLT_ENTRY_SIZE);
1930#else
1931 plt_offset += arch_single_init(
1932 rel, &intsym->pltent,
1933 plt_offset, PLT_ENTRY_SIZE);
1934#endif
1935 plt_needed = 1;
1936 }
1937#endif
1938 }
1939 }
1940
1941#if defined(USE_GOT_ENTRIES)
1942 if (got_needed) {
1943 ifile->got = arch_xsect_init(f, ".got", got_offset,
1944 GOT_ENTRY_SIZE);
1945 }
1946#endif
1947
1948#if defined(USE_PLT_ENTRIES)
1949 if (plt_needed) {
1950 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1951 PLT_ENTRY_SIZE);
1952 }
1953#endif
1954
1955#endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */
1956}
1957
1958/*======================================================================*/
1959
1960/* Standard ELF hash function. */
1961static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1962{
1963 unsigned long h = 0;
1964 unsigned long g;
1965 unsigned char ch;
1966
1967 while (n > 0) {
1968 ch = *name++;
1969 h = (h << 4) + ch;
1970 if ((g = (h & 0xf0000000)) != 0) {
1971 h ^= g >> 24;
1972 h &= ~g;
1973 }
1974 n--;
1975 }
1976 return h;
1977}
1978
1979static unsigned long obj_elf_hash(const char *name)
1980{
1981 return obj_elf_hash_n(name, strlen(name));
1982}
1983
1984#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
1985/* String comparison for non-co-versioned kernel and module. */
1986
1987static int ncv_strcmp(const char *a, const char *b)
1988{
1989 size_t alen = strlen(a), blen = strlen(b);
1990
1991 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1992 return strncmp(a, b, alen);
1993 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1994 return strncmp(a, b, blen);
1995 else
1996 return strcmp(a, b);
1997}
1998
1999/* String hashing for non-co-versioned kernel and module. Here
2000 we are simply forced to drop the crc from the hash. */
2001
2002static unsigned long ncv_symbol_hash(const char *str)
2003{
2004 size_t len = strlen(str);
2005 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
2006 len -= 10;
2007 return obj_elf_hash_n(str, len);
2008}
2009
2010static void
2011obj_set_symbol_compare(struct obj_file *f,
2012 int (*cmp) (const char *, const char *),
2013 unsigned long (*hash) (const char *))
2014{
2015 if (cmp)
2016 f->symbol_cmp = cmp;
2017 if (hash) {
2018 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
2019 int i;
2020
2021 f->symbol_hash = hash;
2022
2023 memcpy(tmptab, f->symtab, sizeof(tmptab));
2024 memset(f->symtab, 0, sizeof(f->symtab));
2025
2026 for (i = 0; i < HASH_BUCKETS; ++i)
2027 for (sym = tmptab[i]; sym; sym = next) {
2028 unsigned long h = hash(sym->name) % HASH_BUCKETS;
2029 next = sym->next;
2030 sym->next = f->symtab[h];
2031 f->symtab[h] = sym;
2032 }
2033 }
2034}
2035
2036#endif /* FEATURE_INSMOD_VERSION_CHECKING */
2037
2038static struct obj_symbol *
2039obj_add_symbol(struct obj_file *f, const char *name,
2040 unsigned long symidx, int info,
2041 int secidx, ElfW(Addr) value,
2042 unsigned long size)
2043{
2044 struct obj_symbol *sym;
2045 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2046 int n_type = ELF_ST_TYPE(info);
2047 int n_binding = ELF_ST_BIND(info);
2048
2049 for (sym = f->symtab[hash]; sym; sym = sym->next)
2050 if (f->symbol_cmp(sym->name, name) == 0) {
2051 int o_secidx = sym->secidx;
2052 int o_info = sym->info;
2053 int o_type = ELF_ST_TYPE(o_info);
2054 int o_binding = ELF_ST_BIND(o_info);
2055
2056 /* A redefinition! Is it legal? */
2057
2058 if (secidx == SHN_UNDEF)
2059 return sym;
2060 else if (o_secidx == SHN_UNDEF)
2061 goto found;
2062 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2063 /* Cope with local and global symbols of the same name
2064 in the same object file, as might have been created
2065 by ld -r. The only reason locals are now seen at this
2066 level at all is so that we can do semi-sensible things
2067 with parameters. */
2068
2069 struct obj_symbol *nsym, **p;
2070
2071 nsym = arch_new_symbol();
2072 nsym->next = sym->next;
2073 nsym->ksymidx = -1;
2074
2075 /* Excise the old (local) symbol from the hash chain. */
2076 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2077 continue;
2078 *p = sym = nsym;
2079 goto found;
2080 } else if (n_binding == STB_LOCAL) {
2081 /* Another symbol of the same name has already been defined.
2082 Just add this to the local table. */
2083 sym = arch_new_symbol();
2084 sym->next = NULL;
2085 sym->ksymidx = -1;
2086 f->local_symtab[symidx] = sym;
2087 goto found;
2088 } else if (n_binding == STB_WEAK)
2089 return sym;
2090 else if (o_binding == STB_WEAK)
2091 goto found;
2092 /* Don't unify COMMON symbols with object types the programmer
2093 doesn't expect. */
2094 else if (secidx == SHN_COMMON
2095 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2096 return sym;
2097 else if (o_secidx == SHN_COMMON
2098 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2099 goto found;
2100 else {
2101 /* Don't report an error if the symbol is coming from
2102 the kernel or some external module. */
2103 if (secidx <= SHN_HIRESERVE)
2104 bb_error_msg("%s multiply defined", name);
2105 return sym;
2106 }
2107 }
2108
2109 /* Completely new symbol. */
2110 sym = arch_new_symbol();
2111 sym->next = f->symtab[hash];
2112 f->symtab[hash] = sym;
2113 sym->ksymidx = -1;
2114
2115 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) {
2116 if (symidx >= f->local_symtab_size)
2117 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2118 name, (long) symidx, (long) f->local_symtab_size);
2119 else
2120 f->local_symtab[symidx] = sym;
2121 }
2122
2123found:
2124 sym->name = name;
2125 sym->value = value;
2126 sym->size = size;
2127 sym->secidx = secidx;
2128 sym->info = info;
2129
2130 return sym;
2131}
2132
2133static struct obj_symbol *
2134obj_find_symbol(struct obj_file *f, const char *name)
2135{
2136 struct obj_symbol *sym;
2137 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2138
2139 for (sym = f->symtab[hash]; sym; sym = sym->next)
2140 if (f->symbol_cmp(sym->name, name) == 0)
2141 return sym;
2142
2143 return NULL;
2144}
2145
2146static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2147{
2148 if (sym) {
2149 if (sym->secidx >= SHN_LORESERVE)
2150 return sym->value;
2151
2152 return sym->value + f->sections[sym->secidx]->header.sh_addr;
2153 } else {
2154 /* As a special case, a NULL sym has value zero. */
2155 return 0;
2156 }
2157}
2158
2159static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2160{
2161 int i, n = f->header.e_shnum;
2162
2163 for (i = 0; i < n; ++i)
2164 if (strcmp(f->sections[i]->name, name) == 0)
2165 return f->sections[i];
2166
2167 return NULL;
2168}
2169
2170static int obj_load_order_prio(struct obj_section *a)
2171{
2172 unsigned long af, ac;
2173
2174 af = a->header.sh_flags;
2175
2176 ac = 0;
2177 if (a->name[0] != '.' || strlen(a->name) != 10 ||
2178 strcmp(a->name + 5, ".init"))
2179 ac |= 32;
2180 if (af & SHF_ALLOC)
2181 ac |= 16;
2182 if (!(af & SHF_WRITE))
2183 ac |= 8;
2184 if (af & SHF_EXECINSTR)
2185 ac |= 4;
2186 if (a->header.sh_type != SHT_NOBITS)
2187 ac |= 2;
2188
2189 return ac;
2190}
2191
2192static void
2193obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2194{
2195 struct obj_section **p;
2196 int prio = obj_load_order_prio(sec);
2197 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2198 if (obj_load_order_prio(*p) < prio)
2199 break;
2200 sec->load_next = *p;
2201 *p = sec;
2202}
2203
2204static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2205 const char *name,
2206 unsigned long align,
2207 unsigned long size)
2208{
2209 int newidx = f->header.e_shnum++;
2210 struct obj_section *sec;
2211
2212 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2213 f->sections[newidx] = sec = arch_new_section();
2214
2215 memset(sec, 0, sizeof(*sec));
2216 sec->header.sh_type = SHT_PROGBITS;
2217 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2218 sec->header.sh_size = size;
2219 sec->header.sh_addralign = align;
2220 sec->name = name;
2221 sec->idx = newidx;
2222 if (size)
2223 sec->contents = xmalloc(size);
2224
2225 obj_insert_section_load_order(f, sec);
2226
2227 return sec;
2228}
2229
2230static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2231 const char *name,
2232 unsigned long align,
2233 unsigned long size)
2234{
2235 int newidx = f->header.e_shnum++;
2236 struct obj_section *sec;
2237
2238 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2239 f->sections[newidx] = sec = arch_new_section();
2240
2241 memset(sec, 0, sizeof(*sec));
2242 sec->header.sh_type = SHT_PROGBITS;
2243 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2244 sec->header.sh_size = size;
2245 sec->header.sh_addralign = align;
2246 sec->name = name;
2247 sec->idx = newidx;
2248 if (size)
2249 sec->contents = xmalloc(size);
2250
2251 sec->load_next = f->load_order;
2252 f->load_order = sec;
2253 if (f->load_order_search_start == &f->load_order)
2254 f->load_order_search_start = &sec->load_next;
2255
2256 return sec;
2257}
2258
2259static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2260{
2261 unsigned long oldsize = sec->header.sh_size;
2262 if (more) {
2263 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
2264 }
2265 return sec->contents + oldsize;
2266}
2267
2268
2269/* Conditionally add the symbols from the given symbol set to the
2270 new module. */
2271
2272static int
2273add_symbols_from( struct obj_file *f,
2274 int idx, struct new_module_symbol *syms, size_t nsyms)
2275{
2276 struct new_module_symbol *s;
2277 size_t i;
2278 int used = 0;
2279#ifdef SYMBOL_PREFIX
2280 char *name_buf = 0;
2281 size_t name_alloced_size = 0;
2282#endif
2283#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2284 int gpl;
2285
2286 gpl = obj_gpl_license(f, NULL) == 0;
2287#endif
2288 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2289 /* Only add symbols that are already marked external.
2290 If we override locals we may cause problems for
2291 argument initialization. We will also create a false
2292 dependency on the module. */
2293 struct obj_symbol *sym;
2294 char *name;
2295
2296 /* GPL licensed modules can use symbols exported with
2297 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2298 * exported names. Non-GPL modules never see any GPLONLY_
2299 * symbols so they cannot fudge it by adding the prefix on
2300 * their references.
2301 */
2302 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2303#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2304 if (gpl)
2305 s->name += 8;
2306 else
2307#endif
2308 continue;
2309 }
2310 name = (char *)s->name;
2311
2312#ifdef SYMBOL_PREFIX
2313 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2314 kernel exports `C names', but module object files
2315 reference `linker names'). */
2316 size_t extra = sizeof SYMBOL_PREFIX;
2317 size_t name_size = strlen (name) + extra;
2318 if (name_size > name_alloced_size) {
2319 name_alloced_size = name_size * 2;
2320 name_buf = alloca (name_alloced_size);
2321 }
2322 strcpy (name_buf, SYMBOL_PREFIX);
2323 strcpy (name_buf + extra - 1, name);
2324 name = name_buf;
2325#endif /* SYMBOL_PREFIX */
2326
2327 sym = obj_find_symbol(f, name);
2328 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2329#ifdef SYMBOL_PREFIX
2330 /* Put NAME_BUF into more permanent storage. */
2331 name = xmalloc (name_size);
2332 strcpy (name, name_buf);
2333#endif
2334 sym = obj_add_symbol(f, name, -1,
2335 ELF_ST_INFO(STB_GLOBAL,
2336 STT_NOTYPE),
2337 idx, s->value, 0);
2338 /* Did our symbol just get installed? If so, mark the
2339 module as "used". */
2340 if (sym->secidx == idx)
2341 used = 1;
2342 }
2343 }
2344
2345 return used;
2346}
2347
2348static void add_kernel_symbols(struct obj_file *f)
2349{
2350 struct external_module *m;
2351 int i, nused = 0;
2352
2353 /* Add module symbols first. */
2354
2355 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
2356 if (m->nsyms
2357 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
2358 m->nsyms)) m->used = 1, ++nused;
2359
2360 n_ext_modules_used = nused;
2361
2362 /* And finally the symbols from the kernel proper. */
2363
2364 if (nksyms)
2365 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2366}
2367
2368static char *get_modinfo_value(struct obj_file *f, const char *key)
2369{
2370 struct obj_section *sec;
2371 char *p, *v, *n, *ep;
2372 size_t klen = strlen(key);
2373
2374 sec = obj_find_section(f, ".modinfo");
2375 if (sec == NULL)
2376 return NULL;
2377 p = sec->contents;
2378 ep = p + sec->header.sh_size;
2379 while (p < ep) {
2380 v = strchr(p, '=');
2381 n = strchr(p, '\0');
2382 if (v) {
2383 if (p + klen == v && strncmp(p, key, klen) == 0)
2384 return v + 1;
2385 } else {
2386 if (p + klen == n && strcmp(p, key) == 0)
2387 return n;
2388 }
2389 p = n + 1;
2390 }
2391
2392 return NULL;
2393}
2394
2395
2396/*======================================================================*/
2397/* Functions relating to module loading after 2.1.18. */
2398
2399static int
2400new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2401{
2402 while (argc > 0) {
2403 char *p, *q, *key, *sym_name;
2404 struct obj_symbol *sym;
2405 char *contents, *loc;
2406 int min, max, n;
2407
2408 p = *argv;
2409 if ((q = strchr(p, '=')) == NULL) {
2410 argc--;
2411 continue;
2412 }
2413
2414 key = alloca(q - p + 6);
2415 memcpy(key, "parm_", 5);
2416 memcpy(key + 5, p, q - p);
2417 key[q - p + 5] = 0;
2418
2419 p = get_modinfo_value(f, key);
2420 key += 5;
2421 if (p == NULL) {
2422 bb_error_msg("invalid parameter %s", key);
2423 return 0;
2424 }
2425
2426#ifdef SYMBOL_PREFIX
2427 sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);
2428 strcpy (sym_name, SYMBOL_PREFIX);
2429 strcat (sym_name, key);
2430#else
2431 sym_name = key;
2432#endif
2433 sym = obj_find_symbol(f, sym_name);
2434
2435 /* Also check that the parameter was not resolved from the kernel. */
2436 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
2437 bb_error_msg("symbol for parameter %s not found", key);
2438 return 0;
2439 }
2440
2441 if (isdigit(*p)) {
2442 min = strtoul(p, &p, 10);
2443 if (*p == '-')
2444 max = strtoul(p + 1, &p, 10);
2445 else
2446 max = min;
2447 } else
2448 min = max = 1;
2449
2450 contents = f->sections[sym->secidx]->contents;
2451 loc = contents + sym->value;
2452 n = (*++q != '\0');
2453
2454 while (1) {
2455 if ((*p == 's') || (*p == 'c')) {
2456 char *str;
2457
2458 /* Do C quoting if we begin with a ", else slurp the lot. */
2459 if (*q == '"') {
2460 char *r;
2461
2462 str = alloca(strlen(q));
2463 for (r = str, q++; *q != '"'; ++q, ++r) {
2464 if (*q == '\0') {
2465 bb_error_msg("improperly terminated string argument for %s",
2466 key);
2467 return 0;
2468 } else if (*q == '\\')
2469 switch (*++q) {
2470 case 'a':
2471 *r = '\a';
2472 break;
2473 case 'b':
2474 *r = '\b';
2475 break;
2476 case 'e':
2477 *r = '\033';
2478 break;
2479 case 'f':
2480 *r = '\f';
2481 break;
2482 case 'n':
2483 *r = '\n';
2484 break;
2485 case 'r':
2486 *r = '\r';
2487 break;
2488 case 't':
2489 *r = '\t';
2490 break;
2491
2492 case '0':
2493 case '1':
2494 case '2':
2495 case '3':
2496 case '4':
2497 case '5':
2498 case '6':
2499 case '7':
2500 {
2501 int c = *q - '0';
2502 if (q[1] >= '0' && q[1] <= '7') {
2503 c = (c * 8) + *++q - '0';
2504 if (q[1] >= '0' && q[1] <= '7')
2505 c = (c * 8) + *++q - '0';
2506 }
2507 *r = c;
2508 }
2509 break;
2510
2511 default:
2512 *r = *q;
2513 break;
2514 } else
2515 *r = *q;
2516 }
2517 *r = '\0';
2518 ++q;
2519 } else {
2520 char *r;
2521
2522 /* In this case, the string is not quoted. We will break
2523 it using the coma (like for ints). If the user wants to
2524 include comas in a string, he just has to quote it */
2525
2526 /* Search the next coma */
2527 r = strchr(q, ',');
2528
2529 /* Found ? */
2530 if (r != (char *) NULL) {
2531 /* Recopy the current field */
2532 str = alloca(r - q + 1);
2533 memcpy(str, q, r - q);
2534
2535 /* I don't know if it is useful, as the previous case
2536 doesn't nul terminate the string ??? */
2537 str[r - q] = '\0';
2538
2539 /* Keep next fields */
2540 q = r;
2541 } else {
2542 /* last string */
2543 str = q;
2544 q = "";
2545 }
2546 }
2547
2548 if (*p == 's') {
2549 /* Normal string */
2550 obj_string_patch(f, sym->secidx, loc - contents, str);
2551 loc += tgt_sizeof_char_p;
2552 } else {
2553 /* Array of chars (in fact, matrix !) */
2554 unsigned long charssize; /* size of each member */
2555
2556 /* Get the size of each member */
2557 /* Probably we should do that outside the loop ? */
2558 if (!isdigit(*(p + 1))) {
2559 bb_error_msg("parameter type 'c' for %s must be followed by"
2560 " the maximum size", key);
2561 return 0;
2562 }
2563 charssize = strtoul(p + 1, (char **) NULL, 10);
2564
2565 /* Check length */
2566 if (strlen(str) >= charssize) {
2567 bb_error_msg("string too long for %s (max %ld)", key,
2568 charssize - 1);
2569 return 0;
2570 }
2571
2572 /* Copy to location */
2573 strcpy((char *) loc, str);
2574 loc += charssize;
2575 }
2576 } else {
2577 long v = strtoul(q, &q, 0);
2578 switch (*p) {
2579 case 'b':
2580 *loc++ = v;
2581 break;
2582 case 'h':
2583 *(short *) loc = v;
2584 loc += tgt_sizeof_short;
2585 break;
2586 case 'i':
2587 *(int *) loc = v;
2588 loc += tgt_sizeof_int;
2589 break;
2590 case 'l':
2591 *(long *) loc = v;
2592 loc += tgt_sizeof_long;
2593 break;
2594
2595 default:
2596 bb_error_msg("unknown parameter type '%c' for %s", *p, key);
2597 return 0;
2598 }
2599 }
2600
2601retry_end_of_value:
2602 switch (*q) {
2603 case '\0':
2604 goto end_of_arg;
2605
2606 case ' ':
2607 case '\t':
2608 case '\n':
2609 case '\r':
2610 ++q;
2611 goto retry_end_of_value;
2612
2613 case ',':
2614 if (++n > max) {
2615 bb_error_msg("too many values for %s (max %d)", key, max);
2616 return 0;
2617 }
2618 ++q;
2619 break;
2620
2621 default:
2622 bb_error_msg("invalid argument syntax for %s", key);
2623 return 0;
2624 }
2625 }
2626
2627end_of_arg:
2628 if (n < min) {
2629 bb_error_msg("too few values for %s (min %d)", key, min);
2630 return 0;
2631 }
2632
2633 argc--, argv++;
2634 }
2635
2636 return 1;
2637}
2638
2639#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
2640static int new_is_module_checksummed(struct obj_file *f)
2641{
2642 const char *p = get_modinfo_value(f, "using_checksums");
2643 if (p)
2644 return xatoi(p);
2645 else
2646 return 0;
2647}
2648
2649/* Get the module's kernel version in the canonical integer form. */
2650
2651static int
2652new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2653{
2654 char *p, *q;
2655 int a, b, c;
2656
2657 p = get_modinfo_value(f, "kernel_version");
2658 if (p == NULL)
2659 return -1;
2660 safe_strncpy(str, p, STRVERSIONLEN);
2661
2662 a = strtoul(p, &p, 10);
2663 if (*p != '.')
2664 return -1;
2665 b = strtoul(p + 1, &p, 10);
2666 if (*p != '.')
2667 return -1;
2668 c = strtoul(p + 1, &q, 10);
2669 if (p + 1 == q)
2670 return -1;
2671
2672 return a << 16 | b << 8 | c;
2673}
2674
2675#endif /* FEATURE_INSMOD_VERSION_CHECKING */
2676
2677
2678/* Fetch the loaded modules, and all currently exported symbols. */
2679
2680static int new_get_kernel_symbols(void)
2681{
2682 char *module_names, *mn;
2683 struct external_module *modules, *m;
2684 struct new_module_symbol *syms, *s;
2685 size_t ret, bufsize, nmod, nsyms, i, j;
2686
2687 /* Collect the loaded modules. */
2688
2689 module_names = xmalloc(bufsize = 256);
2690retry_modules_load:
2691 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2692 if (errno == ENOSPC && bufsize < ret) {
2693 module_names = xrealloc(module_names, bufsize = ret);
2694 goto retry_modules_load;
2695 }
2696 bb_perror_msg("QM_MODULES");
2697 return 0;
2698 }
2699
2700 n_ext_modules = nmod = ret;
2701
2702 /* Collect the modules' symbols. */
2703
2704 if (nmod) {
2705 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2706 memset(modules, 0, nmod * sizeof(*modules));
2707 for (i = 0, mn = module_names, m = modules;
2708 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2709 struct new_module_info info;
2710
2711 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2712 if (errno == ENOENT) {
2713 /* The module was removed out from underneath us. */
2714 continue;
2715 }
2716 bb_perror_msg("query_module: QM_INFO: %s", mn);
2717 return 0;
2718 }
2719
2720 syms = xmalloc(bufsize = 1024);
2721retry_mod_sym_load:
2722 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2723 switch (errno) {
2724 case ENOSPC:
2725 syms = xrealloc(syms, bufsize = ret);
2726 goto retry_mod_sym_load;
2727 case ENOENT:
2728 /* The module was removed out from underneath us. */
2729 continue;
2730 default:
2731 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn);
2732 return 0;
2733 }
2734 }
2735 nsyms = ret;
2736
2737 m->name = mn;
2738 m->addr = info.addr;
2739 m->nsyms = nsyms;
2740 m->syms = syms;
2741
2742 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2743 s->name += (unsigned long) syms;
2744 }
2745 }
2746 }
2747
2748 /* Collect the kernel's symbols. */
2749
2750 syms = xmalloc(bufsize = 16 * 1024);
2751retry_kern_sym_load:
2752 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2753 if (errno == ENOSPC && bufsize < ret) {
2754 syms = xrealloc(syms, bufsize = ret);
2755 goto retry_kern_sym_load;
2756 }
2757 bb_perror_msg("kernel: QM_SYMBOLS");
2758 return 0;
2759 }
2760 nksyms = nsyms = ret;
2761 ksyms = syms;
2762
2763 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2764 s->name += (unsigned long) syms;
2765 }
2766 return 1;
2767}
2768
2769
2770/* Return the kernel symbol checksum version, or zero if not used. */
2771
2772static int new_is_kernel_checksummed(void)
2773{
2774 struct new_module_symbol *s;
2775 size_t i;
2776
2777 /* Using_Versions is not the first symbol, but it should be in there. */
2778
2779 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2780 if (strcmp((char *) s->name, "Using_Versions") == 0)
2781 return s->value;
2782
2783 return 0;
2784}
2785
2786
2787static int new_create_this_module(struct obj_file *f, const char *m_name)
2788{
2789 struct obj_section *sec;
2790
2791 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2792 sizeof(struct new_module));
2793 memset(sec->contents, 0, sizeof(struct new_module));
2794
2795 obj_add_symbol(f, SPFX "__this_module", -1,
2796 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2797 sizeof(struct new_module));
2798
2799 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2800 m_name);
2801
2802 return 1;
2803}
2804
2805#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2806/* add an entry to the __ksymtab section, creating it if necessary */
2807static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2808{
2809 struct obj_section *sec;
2810 ElfW(Addr) ofs;
2811
2812 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2813 * If __ksymtab is defined but not marked alloc, x out the first character
2814 * (no obj_delete routine) and create a new __ksymtab with the correct
2815 * characteristics.
2816 */
2817 sec = obj_find_section(f, "__ksymtab");
2818 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2819 *((char *)(sec->name)) = 'x'; /* override const */
2820 sec = NULL;
2821 }
2822 if (!sec)
2823 sec = obj_create_alloced_section(f, "__ksymtab",
2824 tgt_sizeof_void_p, 0);
2825 if (!sec)
2826 return;
2827 sec->header.sh_flags |= SHF_ALLOC;
2828 /* Empty section might be byte-aligned */
2829 sec->header.sh_addralign = tgt_sizeof_void_p;
2830 ofs = sec->header.sh_size;
2831 obj_symbol_patch(f, sec->idx, ofs, sym);
2832 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2833 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2834}
2835#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
2836
2837static int new_create_module_ksymtab(struct obj_file *f)
2838{
2839 struct obj_section *sec;
2840 int i;
2841
2842 /* We must always add the module references. */
2843
2844 if (n_ext_modules_used) {
2845 struct new_module_ref *dep;
2846 struct obj_symbol *tm;
2847
2848 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2849 (sizeof(struct new_module_ref)
2850 * n_ext_modules_used));
2851 if (!sec)
2852 return 0;
2853
2854 tm = obj_find_symbol(f, SPFX "__this_module");
2855 dep = (struct new_module_ref *) sec->contents;
2856 for (i = 0; i < n_ext_modules; ++i)
2857 if (ext_modules[i].used) {
2858 dep->dep = ext_modules[i].addr;
2859 obj_symbol_patch(f, sec->idx,
2860 (char *) &dep->ref - sec->contents, tm);
2861 dep->next_ref = 0;
2862 ++dep;
2863 }
2864 }
2865
2866 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
2867 size_t nsyms;
2868 int *loaded;
2869
2870 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
2871
2872 /* We don't want to export symbols residing in sections that
2873 aren't loaded. There are a number of these created so that
2874 we make sure certain module options don't appear twice. */
2875
2876 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2877 while (--i >= 0)
2878 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2879
2880 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2881 struct obj_symbol *sym;
2882 for (sym = f->symtab[i]; sym; sym = sym->next)
2883 if (ELF_ST_BIND(sym->info) != STB_LOCAL
2884 && sym->secidx <= SHN_HIRESERVE
2885 && (sym->secidx >= SHN_LORESERVE
2886 || loaded[sym->secidx])) {
2887 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2888
2889 obj_symbol_patch(f, sec->idx, ofs, sym);
2890 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2891 sym->name);
2892
2893 nsyms++;
2894 }
2895 }
2896
2897 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2898 }
2899
2900 return 1;
2901}
2902
2903
2904static int
2905new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2906{
2907 struct new_module *module;
2908 struct obj_section *sec;
2909 void *image;
2910 int ret;
2911 tgt_long m_addr;
2912
2913 sec = obj_find_section(f, ".this");
2914 if (!sec || !sec->contents) {
2915 bb_perror_msg_and_die("corrupt module %s?",m_name);
2916 }
2917 module = (struct new_module *) sec->contents;
2918 m_addr = sec->header.sh_addr;
2919
2920 module->size_of_struct = sizeof(*module);
2921 module->size = m_size;
2922 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2923
2924 sec = obj_find_section(f, "__ksymtab");
2925 if (sec && sec->header.sh_size) {
2926 module->syms = sec->header.sh_addr;
2927 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2928 }
2929
2930 if (n_ext_modules_used) {
2931 sec = obj_find_section(f, ".kmodtab");
2932 module->deps = sec->header.sh_addr;
2933 module->ndeps = n_ext_modules_used;
2934 }
2935
2936 module->init =
2937 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2938 module->cleanup =
2939 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
2940
2941 sec = obj_find_section(f, "__ex_table");
2942 if (sec) {
2943 module->ex_table_start = sec->header.sh_addr;
2944 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2945 }
2946
2947 sec = obj_find_section(f, ".text.init");
2948 if (sec) {
2949 module->runsize = sec->header.sh_addr - m_addr;
2950 }
2951 sec = obj_find_section(f, ".data.init");
2952 if (sec) {
2953 if (!module->runsize ||
2954 module->runsize > sec->header.sh_addr - m_addr)
2955 module->runsize = sec->header.sh_addr - m_addr;
2956 }
2957 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2958 if (sec && sec->header.sh_size) {
2959 module->archdata_start = (void*)sec->header.sh_addr;
2960 module->archdata_end = module->archdata_start + sec->header.sh_size;
2961 }
2962 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2963 if (sec && sec->header.sh_size) {
2964 module->kallsyms_start = (void*)sec->header.sh_addr;
2965 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2966 }
2967
2968 /* Whew! All of the initialization is complete. Collect the final
2969 module image and give it to the kernel. */
2970
2971 image = xmalloc(m_size);
2972 obj_create_image(f, image);
2973
2974 ret = init_module(m_name, (struct new_module *) image);
2975 if (ret)
2976 bb_perror_msg("init_module: %s", m_name);
2977
2978 free(image);
2979
2980 return ret == 0;
2981}
2982
2983
2984/*======================================================================*/
2985
2986static int
2987obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2988 const char *string)
2989{
2990 struct obj_string_patch *p;
2991 struct obj_section *strsec;
2992 size_t len = strlen(string) + 1;
2993 char *loc;
2994
2995 p = xmalloc(sizeof(*p));
2996 p->next = f->string_patches;
2997 p->reloc_secidx = secidx;
2998 p->reloc_offset = offset;
2999 f->string_patches = p;
3000
3001 strsec = obj_find_section(f, ".kstrtab");
3002 if (strsec == NULL) {
3003 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
3004 p->string_offset = 0;
3005 loc = strsec->contents;
3006 } else {
3007 p->string_offset = strsec->header.sh_size;
3008 loc = obj_extend_section(strsec, len);
3009 }
3010 memcpy(loc, string, len);
3011
3012 return 1;
3013}
3014
3015static int
3016obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3017 struct obj_symbol *sym)
3018{
3019 struct obj_symbol_patch *p;
3020
3021 p = xmalloc(sizeof(*p));
3022 p->next = f->symbol_patches;
3023 p->reloc_secidx = secidx;
3024 p->reloc_offset = offset;
3025 p->sym = sym;
3026 f->symbol_patches = p;
3027
3028 return 1;
3029}
3030
3031static int obj_check_undefineds(struct obj_file *f)
3032{
3033 unsigned long i;
3034 int ret = 1;
3035
3036 for (i = 0; i < HASH_BUCKETS; ++i) {
3037 struct obj_symbol *sym;
3038 for (sym = f->symtab[i]; sym; sym = sym->next)
3039 if (sym->secidx == SHN_UNDEF) {
3040 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
3041 sym->secidx = SHN_ABS;
3042 sym->value = 0;
3043 } else {
3044 if (!flag_quiet) {
3045 bb_error_msg("unresolved symbol %s", sym->name);
3046 }
3047 ret = 0;
3048 }
3049 }
3050 }
3051
3052 return ret;
3053}
3054
3055static void obj_allocate_commons(struct obj_file *f)
3056{
3057 struct common_entry {
3058 struct common_entry *next;
3059 struct obj_symbol *sym;
3060 } *common_head = NULL;
3061
3062 unsigned long i;
3063
3064 for (i = 0; i < HASH_BUCKETS; ++i) {
3065 struct obj_symbol *sym;
3066 for (sym = f->symtab[i]; sym; sym = sym->next)
3067 if (sym->secidx == SHN_COMMON) {
3068 /* Collect all COMMON symbols and sort them by size so as to
3069 minimize space wasted by alignment requirements. */
3070 {
3071 struct common_entry **p, *n;
3072 for (p = &common_head; *p; p = &(*p)->next)
3073 if (sym->size <= (*p)->sym->size)
3074 break;
3075
3076 n = alloca(sizeof(*n));
3077 n->next = *p;
3078 n->sym = sym;
3079 *p = n;
3080 }
3081 }
3082 }
3083
3084 for (i = 1; i < f->local_symtab_size; ++i) {
3085 struct obj_symbol *sym = f->local_symtab[i];
3086 if (sym && sym->secidx == SHN_COMMON) {
3087 struct common_entry **p, *n;
3088 for (p = &common_head; *p; p = &(*p)->next)
3089 if (sym == (*p)->sym)
3090 break;
3091 else if (sym->size < (*p)->sym->size) {
3092 n = alloca(sizeof(*n));
3093 n->next = *p;
3094 n->sym = sym;
3095 *p = n;
3096 break;
3097 }
3098 }
3099 }
3100
3101 if (common_head) {
3102 /* Find the bss section. */
3103 for (i = 0; i < f->header.e_shnum; ++i)
3104 if (f->sections[i]->header.sh_type == SHT_NOBITS)
3105 break;
3106
3107 /* If for some reason there hadn't been one, create one. */
3108 if (i == f->header.e_shnum) {
3109 struct obj_section *sec;
3110
3111 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
3112 f->sections[i] = sec = arch_new_section();
3113 f->header.e_shnum = i + 1;
3114
3115 memset(sec, 0, sizeof(*sec));
3116 sec->header.sh_type = SHT_PROGBITS;
3117 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
3118 sec->name = ".bss";
3119 sec->idx = i;
3120 }
3121
3122 /* Allocate the COMMONS. */
3123 {
3124 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
3125 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
3126 struct common_entry *c;
3127
3128 for (c = common_head; c; c = c->next) {
3129 ElfW(Addr) align = c->sym->value;
3130
3131 if (align > max_align)
3132 max_align = align;
3133 if (bss_size & (align - 1))
3134 bss_size = (bss_size | (align - 1)) + 1;
3135
3136 c->sym->secidx = i;
3137 c->sym->value = bss_size;
3138
3139 bss_size += c->sym->size;
3140 }
3141
3142 f->sections[i]->header.sh_size = bss_size;
3143 f->sections[i]->header.sh_addralign = max_align;
3144 }
3145 }
3146
3147 /* For the sake of patch relocation and parameter initialization,
3148 allocate zeroed data for NOBITS sections now. Note that after
3149 this we cannot assume NOBITS are really empty. */
3150 for (i = 0; i < f->header.e_shnum; ++i) {
3151 struct obj_section *s = f->sections[i];
3152 if (s->header.sh_type == SHT_NOBITS) {
3153 if (s->header.sh_size != 0)
3154 s->contents = memset(xmalloc(s->header.sh_size),
3155 0, s->header.sh_size);
3156 else
3157 s->contents = NULL;
3158
3159 s->header.sh_type = SHT_PROGBITS;
3160 }
3161 }
3162}
3163
3164static unsigned long obj_load_size(struct obj_file *f)
3165{
3166 unsigned long dot = 0;
3167 struct obj_section *sec;
3168
3169 /* Finalize the positions of the sections relative to one another. */
3170
3171 for (sec = f->load_order; sec; sec = sec->load_next) {
3172 ElfW(Addr) align;
3173
3174 align = sec->header.sh_addralign;
3175 if (align && (dot & (align - 1)))
3176 dot = (dot | (align - 1)) + 1;
3177
3178 sec->header.sh_addr = dot;
3179 dot += sec->header.sh_size;
3180 }
3181
3182 return dot;
3183}
3184
3185static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3186{
3187 int i, n = f->header.e_shnum;
3188 int ret = 1;
3189
3190 /* Finalize the addresses of the sections. */
3191
3192 f->baseaddr = base;
3193 for (i = 0; i < n; ++i)
3194 f->sections[i]->header.sh_addr += base;
3195
3196 /* And iterate over all of the relocations. */
3197
3198 for (i = 0; i < n; ++i) {
3199 struct obj_section *relsec, *symsec, *targsec, *strsec;
3200 ElfW(RelM) * rel, *relend;
3201 ElfW(Sym) * symtab;
3202 const char *strtab;
3203
3204 relsec = f->sections[i];
3205 if (relsec->header.sh_type != SHT_RELM)
3206 continue;
3207
3208 symsec = f->sections[relsec->header.sh_link];
3209 targsec = f->sections[relsec->header.sh_info];
3210 strsec = f->sections[symsec->header.sh_link];
3211
3212 rel = (ElfW(RelM) *) relsec->contents;
3213 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3214 symtab = (ElfW(Sym) *) symsec->contents;
3215 strtab = (const char *) strsec->contents;
3216
3217 for (; rel < relend; ++rel) {
3218 ElfW(Addr) value = 0;
3219 struct obj_symbol *intsym = NULL;
3220 unsigned long symndx;
3221 ElfW(Sym) * extsym = 0;
3222 const char *errmsg;
3223
3224 /* Attempt to find a value to use for this relocation. */
3225
3226 symndx = ELF_R_SYM(rel->r_info);
3227 if (symndx) {
3228 /* Note we've already checked for undefined symbols. */
3229
3230 extsym = &symtab[symndx];
3231 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3232 /* Local symbols we look up in the local table to be sure
3233 we get the one that is really intended. */
3234 intsym = f->local_symtab[symndx];
3235 } else {
3236 /* Others we look up in the hash table. */
3237 const char *name;
3238 if (extsym->st_name)
3239 name = strtab + extsym->st_name;
3240 else
3241 name = f->sections[extsym->st_shndx]->name;
3242 intsym = obj_find_symbol(f, name);
3243 }
3244
3245 value = obj_symbol_final_value(f, intsym);
3246 intsym->referenced = 1;
3247 }
3248#if SHT_RELM == SHT_RELA
3249#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3250 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
3251 if (!extsym || !extsym->st_name ||
3252 ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
3253#endif
3254 value += rel->r_addend;
3255#endif
3256
3257 /* Do it! */
3258 switch (arch_apply_relocation
3259 (f, targsec, symsec, intsym, rel, value)
3260 ) {
3261 case obj_reloc_ok:
3262 break;
3263
3264 case obj_reloc_overflow:
3265 errmsg = "Relocation overflow";
3266 goto bad_reloc;
3267 case obj_reloc_dangerous:
3268 errmsg = "Dangerous relocation";
3269 goto bad_reloc;
3270 case obj_reloc_unhandled:
3271 errmsg = "Unhandled relocation";
3272bad_reloc:
3273 if (extsym) {
3274 bb_error_msg("%s of type %ld for %s", errmsg,
3275 (long) ELF_R_TYPE(rel->r_info),
3276 strtab + extsym->st_name);
3277 } else {
3278 bb_error_msg("%s of type %ld", errmsg,
3279 (long) ELF_R_TYPE(rel->r_info));
3280 }
3281 ret = 0;
3282 break;
3283 }
3284 }
3285 }
3286
3287 /* Finally, take care of the patches. */
3288
3289 if (f->string_patches) {
3290 struct obj_string_patch *p;
3291 struct obj_section *strsec;
3292 ElfW(Addr) strsec_base;
3293 strsec = obj_find_section(f, ".kstrtab");
3294 strsec_base = strsec->header.sh_addr;
3295
3296 for (p = f->string_patches; p; p = p->next) {
3297 struct obj_section *targsec = f->sections[p->reloc_secidx];
3298 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3299 = strsec_base + p->string_offset;
3300 }
3301 }
3302
3303 if (f->symbol_patches) {
3304 struct obj_symbol_patch *p;
3305
3306 for (p = f->symbol_patches; p; p = p->next) {
3307 struct obj_section *targsec = f->sections[p->reloc_secidx];
3308 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3309 = obj_symbol_final_value(f, p->sym);
3310 }
3311 }
3312
3313 return ret;
3314}
3315
3316static int obj_create_image(struct obj_file *f, char *image)
3317{
3318 struct obj_section *sec;
3319 ElfW(Addr) base = f->baseaddr;
3320
3321 for (sec = f->load_order; sec; sec = sec->load_next) {
3322 char *secimg;
3323
3324 if (sec->contents == 0 || sec->header.sh_size == 0)
3325 continue;
3326
3327 secimg = image + (sec->header.sh_addr - base);
3328
3329 /* Note that we allocated data for NOBITS sections earlier. */
3330 memcpy(secimg, sec->contents, sec->header.sh_size);
3331 }
3332
3333 return 1;
3334}
3335
3336/*======================================================================*/
3337
3338static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3339{
3340 struct obj_file *f;
3341 ElfW(Shdr) * section_headers;
3342 int shnum, i;
3343 char *shstrtab;
3344
3345 /* Read the file header. */
3346
3347 f = arch_new_file();
3348 memset(f, 0, sizeof(*f));
3349 f->symbol_cmp = strcmp;
3350 f->symbol_hash = obj_elf_hash;
3351 f->load_order_search_start = &f->load_order;
3352
3353 fseek(fp, 0, SEEK_SET);
3354 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
3355 bb_perror_msg("error reading ELF header");
3356 return NULL;
3357 }
3358
3359 if (f->header.e_ident[EI_MAG0] != ELFMAG0
3360 || f->header.e_ident[EI_MAG1] != ELFMAG1
3361 || f->header.e_ident[EI_MAG2] != ELFMAG2
3362 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
3363 bb_error_msg("not an ELF file");
3364 return NULL;
3365 }
3366 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3367 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN
3368 ? ELFDATA2MSB : ELFDATA2LSB)
3369 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3370 || !MATCH_MACHINE(f->header.e_machine)) {
3371 bb_error_msg("ELF file not for this architecture");
3372 return NULL;
3373 }
3374 if (f->header.e_type != ET_REL) {
3375 bb_error_msg("ELF file not a relocatable object");
3376 return NULL;
3377 }
3378
3379 /* Read the section headers. */
3380
3381 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3382 bb_error_msg("section header size mismatch: %lu != %lu",
3383 (unsigned long) f->header.e_shentsize,
3384 (unsigned long) sizeof(ElfW(Shdr)));
3385 return NULL;
3386 }
3387
3388 shnum = f->header.e_shnum;
3389 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3390 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3391
3392 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3393 fseek(fp, f->header.e_shoff, SEEK_SET);
3394 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
3395 bb_perror_msg("error reading ELF section headers");
3396 return NULL;
3397 }
3398
3399 /* Read the section data. */
3400
3401 for (i = 0; i < shnum; ++i) {
3402 struct obj_section *sec;
3403
3404 f->sections[i] = sec = arch_new_section();
3405 memset(sec, 0, sizeof(*sec));
3406
3407 sec->header = section_headers[i];
3408 sec->idx = i;
3409
3410 if(sec->header.sh_size) {
3411 switch (sec->header.sh_type) {
3412 case SHT_NULL:
3413 case SHT_NOTE:
3414 case SHT_NOBITS:
3415 /* ignore */
3416 break;
3417
3418 case SHT_PROGBITS:
3419#if LOADBITS
3420 if (!loadprogbits) {
3421 sec->contents = NULL;
3422 break;
3423 }
3424#endif
3425 case SHT_SYMTAB:
3426 case SHT_STRTAB:
3427 case SHT_RELM:
3428 if (sec->header.sh_size > 0) {
3429 sec->contents = xmalloc(sec->header.sh_size);
3430 fseek(fp, sec->header.sh_offset, SEEK_SET);
3431 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3432 bb_perror_msg("error reading ELF section data");
3433 return NULL;
3434 }
3435 } else {
3436 sec->contents = NULL;
3437 }
3438 break;
3439
3440#if SHT_RELM == SHT_REL
3441 case SHT_RELA:
3442 bb_error_msg("RELA relocations not supported on this architecture");
3443 return NULL;
3444#else
3445 case SHT_REL:
3446 bb_error_msg("REL relocations not supported on this architecture");
3447 return NULL;
3448#endif
3449
3450 default:
3451 if (sec->header.sh_type >= SHT_LOPROC) {
3452 /* Assume processor specific section types are debug
3453 info and can safely be ignored. If this is ever not
3454 the case (Hello MIPS?), don't put ifdefs here but
3455 create an arch_load_proc_section(). */
3456 break;
3457 }
3458
3459 bb_error_msg("can't handle sections of type %ld",
3460 (long) sec->header.sh_type);
3461 return NULL;
3462 }
3463 }
3464 }
3465
3466 /* Do what sort of interpretation as needed by each section. */
3467
3468 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3469
3470 for (i = 0; i < shnum; ++i) {
3471 struct obj_section *sec = f->sections[i];
3472 sec->name = shstrtab + sec->header.sh_name;
3473 }
3474
3475 for (i = 0; i < shnum; ++i) {
3476 struct obj_section *sec = f->sections[i];
3477
3478 /* .modinfo should be contents only but gcc has no attribute for that.
3479 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3480 */
3481 if (strcmp(sec->name, ".modinfo") == 0)
3482 sec->header.sh_flags &= ~SHF_ALLOC;
3483
3484 if (sec->header.sh_flags & SHF_ALLOC)
3485 obj_insert_section_load_order(f, sec);
3486
3487 switch (sec->header.sh_type) {
3488 case SHT_SYMTAB:
3489 {
3490 unsigned long nsym, j;
3491 char *strtab;
3492 ElfW(Sym) * sym;
3493
3494 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3495 bb_error_msg("symbol size mismatch: %lu != %lu",
3496 (unsigned long) sec->header.sh_entsize,
3497 (unsigned long) sizeof(ElfW(Sym)));
3498 return NULL;
3499 }
3500
3501 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3502 strtab = f->sections[sec->header.sh_link]->contents;
3503 sym = (ElfW(Sym) *) sec->contents;
3504
3505 /* Allocate space for a table of local symbols. */
3506 j = f->local_symtab_size = sec->header.sh_info;
3507 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
3508
3509 /* Insert all symbols into the hash table. */
3510 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3511 ElfW(Addr) val = sym->st_value;
3512 const char *name;
3513 if (sym->st_name)
3514 name = strtab + sym->st_name;
3515 else if (sym->st_shndx < shnum)
3516 name = f->sections[sym->st_shndx]->name;
3517 else
3518 continue;
3519#if defined(__SH5__)
3520 /*
3521 * For sh64 it is possible that the target of a branch
3522 * requires a mode switch (32 to 16 and back again).
3523 *
3524 * This is implied by the lsb being set in the target
3525 * address for SHmedia mode and clear for SHcompact.
3526 */
3527 val |= sym->st_other & 4;
3528#endif
3529
3530 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3531 val, sym->st_size);
3532 }
3533 }
3534 break;
3535
3536 case SHT_RELM:
3537 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3538 bb_error_msg("relocation entry size mismatch: %lu != %lu",
3539 (unsigned long) sec->header.sh_entsize,
3540 (unsigned long) sizeof(ElfW(RelM)));
3541 return NULL;
3542 }
3543 break;
3544 /* XXX Relocation code from modutils-2.3.19 is not here.
3545 * Why? That's about 20 lines of code from obj/obj_load.c,
3546 * which gets done in a second pass through the sections.
3547 * This BusyBox insmod does similar work in obj_relocate(). */
3548 }
3549 }
3550
3551 return f;
3552}
3553
3554#if ENABLE_FEATURE_INSMOD_LOADINKMEM
3555/*
3556 * load the unloaded sections directly into the memory allocated by
3557 * kernel for the module
3558 */
3559
3560static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase)
3561{
3562 ElfW(Addr) base = f->baseaddr;
3563 struct obj_section* sec;
3564
3565 for (sec = f->load_order; sec; sec = sec->load_next) {
3566
3567 /* section already loaded? */
3568 if (sec->contents != NULL)
3569 continue;
3570
3571 if (sec->header.sh_size == 0)
3572 continue;
3573
3574 sec->contents = imagebase + (sec->header.sh_addr - base);
3575 fseek(fp, sec->header.sh_offset, SEEK_SET);
3576 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3577 bb_perror_msg("error reading ELF section data");
3578 return 0;
3579 }
3580
3581 }
3582 return 1;
3583}
3584#endif
3585
3586static void hide_special_symbols(struct obj_file *f)
3587{
3588 static const char *const specials[] = {
3589 SPFX "cleanup_module",
3590 SPFX "init_module",
3591 SPFX "kernel_version",
3592 NULL
3593 };
3594
3595 struct obj_symbol *sym;
3596 const char *const *p;
3597
3598 for (p = specials; *p; ++p) {
3599 sym = obj_find_symbol(f, *p);
3600 if (sym != NULL)
3601 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3602 }
3603}
3604
3605
3606#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
3607static int obj_gpl_license(struct obj_file *f, const char **license)
3608{
3609 struct obj_section *sec;
3610 /* This list must match *exactly* the list of allowable licenses in
3611 * linux/include/linux/module.h. Checking for leading "GPL" will not
3612 * work, somebody will use "GPL sucks, this is proprietary".
3613 */
3614 static const char * const gpl_licenses[] = {
3615 "GPL",
3616 "GPL v2",
3617 "GPL and additional rights",
3618 "Dual BSD/GPL",
3619 "Dual MPL/GPL",
3620 };
3621
3622 sec = obj_find_section(f, ".modinfo");
3623 if (sec) {
3624 const char *value, *ptr, *endptr;
3625 ptr = sec->contents;
3626 endptr = ptr + sec->header.sh_size;
3627 while (ptr < endptr) {
3628 value = strchr(ptr, '=');
3629 if (value && strncmp(ptr, "license", value-ptr) == 0) {
3630 int i;
3631 if (license)
3632 *license = value+1;
3633 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3634 if (strcmp(value+1, gpl_licenses[i]) == 0)
3635 return 0;
3636 }
3637 return 2;
3638 }
3639 if (strchr(ptr, '\0'))
3640 ptr = strchr(ptr, '\0') + 1;
3641 else
3642 ptr = endptr;
3643 }
3644 }
3645 return 1;
3646}
3647
3648#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3649#define TAINT_PROPRIETORY_MODULE (1<<0)
3650#define TAINT_FORCED_MODULE (1<<1)
3651#define TAINT_UNSAFE_SMP (1<<2)
3652#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3653
3654static void set_tainted(struct obj_file *f, int fd, char *m_name,
3655 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3656{
3657 char buf[80];
3658 int oldval;
3659 static int first = 1;
3660 if (fd < 0 && !kernel_has_tainted)
3661 return; /* New modutils on old kernel */
3662 printf("Warning: loading %s will taint the kernel: %s%s\n",
3663 m_name, text1, text2);
3664 if (first) {
3665 printf(" See %s for information about tainted modules\n", TAINT_URL);
3666 first = 0;
3667 }
3668 if (fd >= 0) {
3669 read(fd, buf, sizeof(buf)-1);
3670 buf[sizeof(buf)-1] = '\0';
3671 oldval = strtoul(buf, NULL, 10);
3672 sprintf(buf, "%d\n", oldval | taint);
3673 write(fd, buf, strlen(buf));
3674 }
3675}
3676
3677/* Check if loading this module will taint the kernel. */
3678static void check_tainted_module(struct obj_file *f, char *m_name)
3679{
3680 static const char tainted_file[] = TAINT_FILENAME;
3681 int fd, kernel_has_tainted;
3682 const char *ptr;
3683
3684 kernel_has_tainted = 1;
3685 fd = open(tainted_file, O_RDWR);
3686 if (fd < 0) {
3687 if (errno == ENOENT)
3688 kernel_has_tainted = 0;
3689 else if (errno == EACCES)
3690 kernel_has_tainted = 1;
3691 else {
3692 perror(tainted_file);
3693 kernel_has_tainted = 0;
3694 }
3695 }
3696
3697 switch (obj_gpl_license(f, &ptr)) {
3698 case 0:
3699 break;
3700 case 1:
3701 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3702 break;
3703 case 2:
3704 /* The module has a non-GPL license so we pretend that the
3705 * kernel always has a taint flag to get a warning even on
3706 * kernels without the proc flag.
3707 */
3708 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3709 break;
3710 default:
3711 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3712 break;
3713 }
3714
3715 if (flag_force_load)
3716 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3717
3718 if (fd >= 0)
3719 close(fd);
3720}
3721#else /* FEATURE_CHECK_TAINTED_MODULE */
3722#define check_tainted_module(x, y) do { } while(0);
3723#endif /* FEATURE_CHECK_TAINTED_MODULE */
3724
3725#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3726/* add module source, timestamp, kernel version and a symbol for the
3727 * start of some sections. this info is used by ksymoops to do better
3728 * debugging.
3729 */
3730static int
3731get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3732{
3733#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3734 return new_get_module_version(f, str);
3735#else /* FEATURE_INSMOD_VERSION_CHECKING */
3736 strncpy(str, "???", sizeof(str));
3737 return -1;
3738#endif /* FEATURE_INSMOD_VERSION_CHECKING */
3739}
3740
3741/* add module source, timestamp, kernel version and a symbol for the
3742 * start of some sections. this info is used by ksymoops to do better
3743 * debugging.
3744 */
3745static void
3746add_ksymoops_symbols(struct obj_file *f, const char *filename,
3747 const char *m_name)
3748{
3749 static const char symprefix[] = "__insmod_";
3750 struct obj_section *sec;
3751 struct obj_symbol *sym;
3752 char *name, *absolute_filename;
3753 char str[STRVERSIONLEN], real[PATH_MAX];
3754 int i, l, lm_name, lfilename, use_ksymtab, version;
3755 struct stat statbuf;
3756
3757 static const char *section_names[] = {
3758 ".text",
3759 ".rodata",
3760 ".data",
3761 ".bss",
3762 ".sbss"
3763 };
3764
3765 if (realpath(filename, real)) {
3766 absolute_filename = xstrdup(real);
3767 }
3768 else {
3769 int save_errno = errno;
3770 bb_error_msg("cannot get realpath for %s", filename);
3771 errno = save_errno;
3772 perror("");
3773 absolute_filename = xstrdup(filename);
3774 }
3775
3776 lm_name = strlen(m_name);
3777 lfilename = strlen(absolute_filename);
3778
3779 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3780 * are not to be exported. otherwise leave ksymtab alone for now, the
3781 * "export all symbols" compatibility code will export these symbols later.
3782 */
3783 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
3784
3785 if ((sec = obj_find_section(f, ".this"))) {
3786 /* tag the module header with the object name, last modified
3787 * timestamp and module version. worst case for module version
3788 * is 0xffffff, decimal 16777215. putting all three fields in
3789 * one symbol is less readable but saves kernel space.
3790 */
3791 l = sizeof(symprefix)+ /* "__insmod_" */
3792 lm_name+ /* module name */
3793 2+ /* "_O" */
3794 lfilename+ /* object filename */
3795 2+ /* "_M" */
3796 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */
3797 2+ /* "_V" */
3798 8+ /* version in dec */
3799 1; /* nul */
3800 name = xmalloc(l);
3801 if (stat(absolute_filename, &statbuf) != 0)
3802 statbuf.st_mtime = 0;
3803 version = get_module_version(f, str); /* -1 if not found */
3804 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
3805 symprefix, m_name, absolute_filename,
3806 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3807 version);
3808 sym = obj_add_symbol(f, name, -1,
3809 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3810 sec->idx, sec->header.sh_addr, 0);
3811 if (use_ksymtab)
3812 new_add_ksymtab(f, sym);
3813 }
3814 free(absolute_filename);
3815#ifdef _NOT_SUPPORTED_
3816 /* record where the persistent data is going, same address as previous symbol */
3817
3818 if (f->persist) {
3819 l = sizeof(symprefix)+ /* "__insmod_" */
3820 lm_name+ /* module name */
3821 2+ /* "_P" */
3822 strlen(f->persist)+ /* data store */
3823 1; /* nul */
3824 name = xmalloc(l);
3825 snprintf(name, l, "%s%s_P%s",
3826 symprefix, m_name, f->persist);
3827 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3828 sec->idx, sec->header.sh_addr, 0);
3829 if (use_ksymtab)
3830 new_add_ksymtab(f, sym);
3831 }
3832#endif /* _NOT_SUPPORTED_ */
3833 /* tag the desired sections if size is non-zero */
3834
3835 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
3836 if ((sec = obj_find_section(f, section_names[i])) &&
3837 sec->header.sh_size) {
3838 l = sizeof(symprefix)+ /* "__insmod_" */
3839 lm_name+ /* module name */
3840 2+ /* "_S" */
3841 strlen(sec->name)+ /* section name */
3842 2+ /* "_L" */
3843 8+ /* length in dec */
3844 1; /* nul */
3845 name = xmalloc(l);
3846 snprintf(name, l, "%s%s_S%s_L%ld",
3847 symprefix, m_name, sec->name,
3848 (long)sec->header.sh_size);
3849 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3850 sec->idx, sec->header.sh_addr, 0);
3851 if (use_ksymtab)
3852 new_add_ksymtab(f, sym);
3853 }
3854 }
3855}
3856#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3857
3858#if ENABLE_FEATURE_INSMOD_LOAD_MAP
3859static void print_load_map(struct obj_file *f)
3860{
3861 struct obj_symbol *sym;
3862 struct obj_symbol **all, **p;
3863 struct obj_section *sec;
3864 int i, nsyms, *loaded;
3865
3866 /* Report on the section layout. */
3867
3868 printf("Sections: Size %-*s Align\n",
3869 (int) (2 * sizeof(void *)), "Address");
3870
3871 for (sec = f->load_order; sec; sec = sec->load_next) {
3872 int a;
3873 unsigned long tmp;
3874
3875 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3876 tmp >>= 1;
3877 if (a == -1)
3878 a = 0;
3879
3880 printf("%-15s %08lx %0*lx 2**%d\n",
3881 sec->name,
3882 (long)sec->header.sh_size,
3883 (int) (2 * sizeof(void *)),
3884 (long)sec->header.sh_addr,
3885 a);
3886 }
3887#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3888 /* Quick reference which section indicies are loaded. */
3889
3890 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3891 while (--i >= 0)
3892 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3893
3894 /* Collect the symbols we'll be listing. */
3895
3896 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3897 for (sym = f->symtab[i]; sym; sym = sym->next)
3898 if (sym->secidx <= SHN_HIRESERVE
3899 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3900 ++nsyms;
3901
3902 all = alloca(nsyms * sizeof(struct obj_symbol *));
3903
3904 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3905 for (sym = f->symtab[i]; sym; sym = sym->next)
3906 if (sym->secidx <= SHN_HIRESERVE
3907 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3908 *p++ = sym;
3909
3910 /* And list them. */
3911 printf("\nSymbols:\n");
3912 for (p = all; p < all + nsyms; ++p) {
3913 char type = '?';
3914 unsigned long value;
3915
3916 sym = *p;
3917 if (sym->secidx == SHN_ABS) {
3918 type = 'A';
3919 value = sym->value;
3920 } else if (sym->secidx == SHN_UNDEF) {
3921 type = 'U';
3922 value = 0;
3923 } else {
3924 sec = f->sections[sym->secidx];
3925
3926 if (sec->header.sh_type == SHT_NOBITS)
3927 type = 'B';
3928 else if (sec->header.sh_flags & SHF_ALLOC) {
3929 if (sec->header.sh_flags & SHF_EXECINSTR)
3930 type = 'T';
3931 else if (sec->header.sh_flags & SHF_WRITE)
3932 type = 'D';
3933 else
3934 type = 'R';
3935 }
3936 value = sym->value + sec->header.sh_addr;
3937 }
3938
3939 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
3940 type = tolower(type);
3941
3942 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3943 type, sym->name);
3944 }
3945#endif
3946}
3947#else /* !FEATURE_INSMOD_LOAD_MAP */
3948void print_load_map(struct obj_file *f);
3949#endif
3950
3951int insmod_main( int argc, char **argv)
3952{
3953 char *opt_o, *arg1;
3954 int len;
3955 int k_crcs;
3956 char *tmp, *tmp1;
3957 unsigned long m_size;
3958 ElfW(Addr) m_addr;
3959 struct obj_file *f;
3960 struct stat st;
3961 char *m_name = 0;
3962 int exit_status = EXIT_FAILURE;
3963 int m_has_modinfo;
3964#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3965 struct utsname uts_info;
3966 char m_strversion[STRVERSIONLEN];
3967 int m_version, m_crcs;
3968#endif
3969#if ENABLE_FEATURE_CLEAN_UP
3970 FILE *fp = 0;
3971#else
3972 FILE *fp;
3973#endif
3974 int k_version = 0;
3975 struct utsname myuname;
3976
3977 /* Parse any options */
3978 getopt32(argc, argv, OPTION_STR, &opt_o);
3979 arg1 = argv[optind];
3980 if (option_mask32 & OPT_o) { // -o /* name the output module */
3981 free(m_name);
3982 m_name = xstrdup(opt_o);
3983 }
3984
3985 if (arg1 == NULL) {
3986 bb_show_usage();
3987 }
3988
3989 /* Grab the module name */
3990 tmp1 = xstrdup(arg1);
3991 tmp = basename(tmp1);
3992 len = strlen(tmp);
3993
3994 if (uname(&myuname) == 0) {
3995 if (myuname.release[0] == '2') {
3996 k_version = myuname.release[2] - '0';
3997 }
3998 }
3999
4000#if ENABLE_FEATURE_2_6_MODULES
4001 if (k_version > 4 && len > 3 && tmp[len - 3] == '.'
4002 && tmp[len - 2] == 'k' && tmp[len - 1] == 'o'
4003 ) {
4004 len -= 3;
4005 tmp[len] = '\0';
4006 } else
4007#endif
4008 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
4009 len -= 2;
4010 tmp[len] = '\0';
4011 }
4012
4013
4014#if ENABLE_FEATURE_2_6_MODULES
4015 if (k_version > 4)
4016 m_fullName = xasprintf("%s.ko", tmp);
4017 else
4018#endif
4019 m_fullName = xasprintf("%s.o", tmp);
4020
4021 if (!m_name) {
4022 m_name = tmp;
4023 } else {
4024 free(tmp1);
4025 tmp1 = 0; /* flag for free(m_name) before exit() */
4026 }
4027
4028 /* Get a filedesc for the module. Check we we have a complete path */
4029 if (stat(arg1, &st) < 0 || !S_ISREG(st.st_mode)
4030 || (fp = fopen(arg1, "r")) == NULL
4031 ) {
4032 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
4033 * but do not error out yet if we fail to find it... */
4034 if (k_version) { /* uname succeedd */
4035 char *module_dir;
4036 char *tmdn;
4037 char real_module_dir[FILENAME_MAX];
4038
4039 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
4040 /* Jump through hoops in case /lib/modules/`uname -r`
4041 * is a symlink. We do not want recursive_action to
4042 * follow symlinks, but we do want to follow the
4043 * /lib/modules/`uname -r` dir, So resolve it ourselves
4044 * if it is a link... */
4045 if (realpath(tmdn, real_module_dir) == NULL)
4046 module_dir = tmdn;
4047 else
4048 module_dir = real_module_dir;
4049 recursive_action(module_dir, TRUE, FALSE, FALSE,
4050 check_module_name_match, 0, m_fullName, 0);
4051 free(tmdn);
4052 }
4053
4054 /* Check if we have found anything yet */
4055 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) {
4056 char module_dir[FILENAME_MAX];
4057
4058 free(m_filename);
4059 m_filename = 0;
4060 if (realpath (_PATH_MODULES, module_dir) == NULL)
4061 strcpy(module_dir, _PATH_MODULES);
4062 /* No module found under /lib/modules/`uname -r`, this
4063 * time cast the net a bit wider. Search /lib/modules/ */
4064 if (!recursive_action(module_dir, TRUE, FALSE, FALSE,
4065 check_module_name_match, 0, m_fullName, 0)
4066 ) {
4067 if (m_filename == 0
4068 || ((fp = fopen(m_filename, "r")) == NULL)
4069 ) {
4070 bb_error_msg("%s: no module by that name found", m_fullName);
4071 goto out;
4072 }
4073 } else
4074 bb_error_msg_and_die("%s: no module by that name found", m_fullName);
4075 }
4076 } else
4077 m_filename = xstrdup(arg1);
4078
4079 if (flag_verbose)
4080 printf("Using %s\n", m_filename);
4081
4082#if ENABLE_FEATURE_2_6_MODULES
4083 if (k_version > 4) {
4084 argv[optind] = m_filename;
4085 optind--;
4086 return insmod_ng_main(argc - optind, argv + optind);
4087 }
4088#endif
4089
4090 f = obj_load(fp, LOADBITS);
4091 if (f == NULL)
4092 bb_perror_msg_and_die("cannot load the module");
4093
4094 if (get_modinfo_value(f, "kernel_version") == NULL)
4095 m_has_modinfo = 0;
4096 else
4097 m_has_modinfo = 1;
4098
4099#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
4100 /* Version correspondence? */
4101 if (!flag_quiet) {
4102 if (uname(&uts_info) < 0)
4103 uts_info.release[0] = '\0';
4104 if (m_has_modinfo) {
4105 m_version = new_get_module_version(f, m_strversion);
4106 if (m_version == -1) {
4107 bb_error_msg("cannot find the kernel version the module was "
4108 "compiled for");
4109 goto out;
4110 }
4111 }
4112
4113 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
4114 if (flag_force_load) {
4115 bb_error_msg("warning: kernel-module version mismatch\n"
4116 "\t%s was compiled for kernel version %s\n"
4117 "\twhile this kernel is version %s",
4118 m_filename, m_strversion, uts_info.release);
4119 } else {
4120 bb_error_msg("kernel-module version mismatch\n"
4121 "\t%s was compiled for kernel version %s\n"
4122 "\twhile this kernel is version %s.",
4123 m_filename, m_strversion, uts_info.release);
4124 goto out;
4125 }
4126 }
4127 }
4128 k_crcs = 0;
4129#endif /* FEATURE_INSMOD_VERSION_CHECKING */
4130
4131 if (!query_module(NULL, 0, NULL, 0, NULL)) {
4132 if (!new_get_kernel_symbols())
4133 goto out;
4134 k_crcs = new_is_kernel_checksummed();
4135 } else {
4136 bb_error_msg("not configured to support old kernels");
4137 goto out;
4138 }
4139
4140#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
4141 m_crcs = 0;
4142 if (m_has_modinfo)
4143 m_crcs = new_is_module_checksummed(f);
4144
4145 if (m_crcs != k_crcs)
4146 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
4147#endif /* FEATURE_INSMOD_VERSION_CHECKING */
4148
4149 /* Let the module know about the kernel symbols. */
4150 add_kernel_symbols(f);
4151
4152 /* Allocate common symbols, symbol tables, and string tables. */
4153
4154 if (!new_create_this_module(f, m_name)) {
4155 goto out;
4156 }
4157
4158 if (!obj_check_undefineds(f)) {
4159 goto out;
4160 }
4161 obj_allocate_commons(f);
4162 check_tainted_module(f, m_name);
4163
4164 /* done with the module name, on to the optional var=value arguments */
4165 ++optind;
4166 if (optind < argc) {
4167 if (!new_process_module_arguments(f, argc - optind, argv + optind)) {
4168 goto out;
4169 }
4170 }
4171
4172 arch_create_got(f);
4173 hide_special_symbols(f);
4174
4175#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
4176 add_ksymoops_symbols(f, m_filename, m_name);
4177#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
4178
4179 new_create_module_ksymtab(f);
4180
4181 /* Find current size of the module */
4182 m_size = obj_load_size(f);
4183
4184
4185 m_addr = create_module(m_name, m_size);
4186 if (m_addr == -1) switch (errno) {
4187 case EEXIST:
4188 bb_error_msg("a module named %s already exists", m_name);
4189 goto out;
4190 case ENOMEM:
4191 bb_error_msg("can't allocate kernel memory for module; needed %lu bytes",
4192 m_size);
4193 goto out;
4194 default:
4195 bb_perror_msg("create_module: %s", m_name);
4196 goto out;
4197 }
4198
4199#if !LOADBITS
4200 /*
4201 * the PROGBITS section was not loaded by the obj_load
4202 * now we can load them directly into the kernel memory
4203 */
4204 if (!obj_load_progbits(fp, f, (char*)m_addr)) {
4205 delete_module(m_name);
4206 goto out;
4207 }
4208#endif
4209
4210 if (!obj_relocate(f, m_addr)) {
4211 delete_module(m_name);
4212 goto out;
4213 }
4214
4215 if (!new_init_module(m_name, f, m_size)) {
4216 delete_module(m_name);
4217 goto out;
4218 }
4219
4220 if(flag_print_load_map)
4221 print_load_map(f);
4222
4223 exit_status = EXIT_SUCCESS;
4224
4225out:
4226#if ENABLE_FEATURE_CLEAN_UP
4227 if(fp)
4228 fclose(fp);
4229 free(tmp1);
4230 if(!tmp1)
4231 free(m_name);
4232 free(m_filename);
4233#endif
4234 return exit_status;
4235}
4236
4237
4238#endif
4239
4240
4241#if ENABLE_FEATURE_2_6_MODULES
4242
4243#include <sys/mman.h>
4244#include <asm/unistd.h>
4245#include <sys/syscall.h>
4246
4247/* We use error numbers in a loose translation... */
4248static const char *moderror(int err)
4249{
4250 switch (err) {
4251 case ENOEXEC:
4252 return "Invalid module format";
4253 case ENOENT:
4254 return "Unknown symbol in module";
4255 case ESRCH:
4256 return "Module has wrong symbol version";
4257 case EINVAL:
4258 return "Invalid parameters";
4259 default:
4260 return strerror(err);
4261 }
4262}
4263
4264int insmod_ng_main(int argc, char **argv)
4265{
4266 long ret;
4267 size_t len;
4268 void *map;
4269 char *filename, *options;
4270
4271 filename = *++argv;
4272 if (!filename)
4273 bb_show_usage();
4274
4275 /* Rest is options */
4276 options = xstrdup("");
4277 while (*++argv) {
4278 int optlen = strlen(options);
4279 options = xrealloc(options, optlen + 2 + strlen(*argv) + 2);
4280 /* Spaces handled by "" pairs, but no way of escaping quotes */
4281 sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv);
4282 }
4283
4284#if 0
4285 /* Any special reason why mmap? It isn't performace critical... */
4286 int fd;
4287 struct stat st;
4288 unsigned long len;
4289 fd = xopen(filename, O_RDONLY);
4290 fstat(fd, &st);
4291 len = st.st_size;
4292 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
4293 if (map == MAP_FAILED) {
4294 bb_perror_msg_and_die("cannot mmap '%s'", filename);
4295 }
4296
4297 /* map == NULL on Blackfin, probably on other MMU-less systems too. Workaround. */
4298 if (map == NULL) {
4299 map = xmalloc(len);
4300 xread(fd, map, len);
4301 }
4302#else
4303 len = MAXINT(ssize_t);
4304 map = xmalloc_open_read_close(filename, &len);
4305#endif
4306
4307 ret = syscall(__NR_init_module, map, len, options);
4308 if (ret != 0) {
4309 bb_perror_msg_and_die("cannot insert '%s': %s (%li)",
4310 filename, moderror(errno), ret);
4311 }
4312
4313 return 0;
4314}
4315
4316#endif
diff --git a/modutils/lsmod.c b/modutils/lsmod.c
new file mode 100644
index 000000000..ffde3d829
--- /dev/null
+++ b/modutils/lsmod.c
@@ -0,0 +1,188 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini lsmod implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
8 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels
9 * (which lack the query_module() interface).
10 *
11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
12 */
13
14#include "busybox.h"
15
16
17#ifndef CONFIG_FEATURE_CHECK_TAINTED_MODULE
18static void check_tainted(void) { puts(""); }
19#else
20#define TAINT_FILENAME "/proc/sys/kernel/tainted"
21#define TAINT_PROPRIETORY_MODULE (1<<0)
22#define TAINT_FORCED_MODULE (1<<1)
23#define TAINT_UNSAFE_SMP (1<<2)
24
25static void check_tainted(void)
26{
27 int tainted;
28 FILE *f;
29
30 tainted = 0;
31 if ((f = fopen(TAINT_FILENAME, "r"))) {
32 fscanf(f, "%d", &tainted);
33 fclose(f);
34 }
35 if (f && tainted) {
36 printf(" Tainted: %c%c%c\n",
37 tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
38 tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
39 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
40 }
41 else {
42 printf(" Not tainted\n");
43 }
44}
45#endif
46
47#ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE
48
49struct module_info
50{
51 unsigned long addr;
52 unsigned long size;
53 unsigned long flags;
54 long usecount;
55};
56
57
58int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
59
60enum {
61/* Values for query_module's which. */
62 QM_MODULES = 1,
63 QM_DEPS = 2,
64 QM_REFS = 3,
65 QM_SYMBOLS = 4,
66 QM_INFO = 5,
67
68/* Bits of module.flags. */
69 NEW_MOD_RUNNING = 1,
70 NEW_MOD_DELETED = 2,
71 NEW_MOD_AUTOCLEAN = 4,
72 NEW_MOD_VISITED = 8,
73 NEW_MOD_USED_ONCE = 16,
74 NEW_MOD_INITIALIZING = 64
75};
76
77int lsmod_main(int argc, char **argv)
78{
79 struct module_info info;
80 char *module_names, *mn, *deps, *dn;
81 size_t bufsize, depsize, nmod, count, i, j;
82
83 module_names = deps = NULL;
84 bufsize = depsize = 0;
85 while(query_module(NULL, QM_MODULES, module_names, bufsize, &nmod)) {
86 if (errno != ENOSPC) bb_perror_msg_and_die("QM_MODULES");
87 module_names = xmalloc(bufsize = nmod);
88 }
89
90 deps = xmalloc(depsize = 256);
91 printf("Module\t\t\tSize Used by");
92 check_tainted();
93
94 for (i = 0, mn = module_names; i < nmod; mn += strlen(mn) + 1, i++) {
95 if (query_module(mn, QM_INFO, &info, sizeof(info), &count)) {
96 if (errno == ENOENT) {
97 /* The module was removed out from underneath us. */
98 continue;
99 }
100 /* else choke */
101 bb_perror_msg_and_die("module %s: QM_INFO", mn);
102 }
103 while (query_module(mn, QM_REFS, deps, depsize, &count)) {
104 if (errno == ENOENT) {
105 /* The module was removed out from underneath us. */
106 continue;
107 } else if (errno != ENOSPC)
108 bb_perror_msg_and_die("module %s: QM_REFS", mn);
109 deps = xrealloc(deps, count);
110 }
111 printf("%-20s%8lu%4ld", mn, info.size, info.usecount);
112 if (info.flags & NEW_MOD_DELETED)
113 printf(" (deleted)");
114 else if (info.flags & NEW_MOD_INITIALIZING)
115 printf(" (initializing)");
116 else if (!(info.flags & NEW_MOD_RUNNING))
117 printf(" (uninitialized)");
118 else {
119 if (info.flags & NEW_MOD_AUTOCLEAN)
120 printf(" (autoclean) ");
121 if (!(info.flags & NEW_MOD_USED_ONCE))
122 printf(" (unused)");
123 }
124 if (count) printf(" [");
125 for (j = 0, dn = deps; j < count; dn += strlen(dn) + 1, j++) {
126 printf("%s%s", dn, (j==count-1)? "":" ");
127 }
128 if (count) printf("]");
129
130 puts("");
131 }
132
133#ifdef CONFIG_FEATURE_CLEAN_UP
134 free(module_names);
135#endif
136
137 return 0;
138}
139
140#else /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */
141
142int lsmod_main(int argc, char **argv)
143{
144 FILE *file = xfopen("/proc/modules", "r");
145
146 printf("Module Size Used by");
147 check_tainted();
148#if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT)
149 {
150 char *line;
151 while ((line = xmalloc_fgets(file)) != NULL) {
152 char *tok;
153
154 tok = strtok(line, " \t");
155 printf("%-19s", tok);
156 tok = strtok(NULL, " \t\n");
157 printf(" %8s", tok);
158 tok = strtok(NULL, " \t\n");
159 /* Null if no module unloading support. */
160 if (tok) {
161 printf(" %s", tok);
162 tok = strtok(NULL, "\n");
163 if (!tok)
164 tok = "";
165 /* New-style has commas, or -. If so,
166 truncate (other fields might follow). */
167 else if (strchr(tok, ',')) {
168 tok = strtok(tok, "\t ");
169 /* Strip trailing comma. */
170 if (tok[strlen(tok)-1] == ',')
171 tok[strlen(tok)-1] = '\0';
172 } else if (tok[0] == '-'
173 && (tok[1] == '\0' || isspace(tok[1])))
174 tok = "";
175 printf(" %s", tok);
176 }
177 puts("");
178 free(line);
179 }
180 fclose(file);
181 }
182#else
183 xprint_and_close_file(file);
184#endif /* CONFIG_FEATURE_2_6_MODULES */
185 return EXIT_SUCCESS;
186}
187
188#endif /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
new file mode 100644
index 000000000..dcab493f1
--- /dev/null
+++ b/modutils/modprobe.c
@@ -0,0 +1,905 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Modprobe written from scratch for BusyBox
4 *
5 * Copyright (c) 2002 by Robert Griebl, griebl@gmx.de
6 * Copyright (c) 2003 by Andrew Dennison, andrew.dennison@motec.com.au
7 * Copyright (c) 2005 by Jim Bauer, jfbauer@nfr.com
8 *
9 * Portions Copyright (c) 2005 by Yann E. MORIN, yann.morin.1998@anciens.enib.fr
10 *
11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
12*/
13
14#include "busybox.h"
15#include <sys/utsname.h>
16#include <fnmatch.h>
17
18struct mod_opt_t { /* one-way list of options to pass to a module */
19 char * m_opt_val;
20 struct mod_opt_t * m_next;
21};
22
23struct dep_t { /* one-way list of dependency rules */
24 /* a dependency rule */
25 char * m_name; /* the module name*/
26 char * m_path; /* the module file path */
27 struct mod_opt_t * m_options; /* the module options */
28
29 int m_isalias : 1; /* the module is an alias */
30 int m_reserved : 15; /* stuffin' */
31
32 int m_depcnt : 16; /* the number of dependable module(s) */
33 char ** m_deparr; /* the list of dependable module(s) */
34
35 struct dep_t * m_next; /* the next dependency rule */
36};
37
38struct mod_list_t { /* two-way list of modules to process */
39 /* a module description */
40 char * m_name;
41 char * m_path;
42 struct mod_opt_t * m_options;
43
44 struct mod_list_t * m_prev;
45 struct mod_list_t * m_next;
46};
47
48
49static struct dep_t *depend;
50
51#define main_options "acdklnqrst:vVC:"
52#define INSERT_ALL 1 /* a */
53#define DUMP_CONF_EXIT 2 /* c */
54#define D_OPT_IGNORED 4 /* d */
55#define AUTOCLEAN_FLG 8 /* k */
56#define LIST_ALL 16 /* l */
57#define SHOW_ONLY 32 /* n */
58#define QUIET 64 /* q */
59#define REMOVE_OPT 128 /* r */
60#define DO_SYSLOG 256 /* s */
61#define RESTRICT_DIR 512 /* t */
62#define VERBOSE 1024 /* v */
63#define VERSION_ONLY 2048 /* V */
64#define CONFIG_FILE 4096 /* C */
65
66#define autoclean (main_opts & AUTOCLEAN_FLG)
67#define show_only (main_opts & SHOW_ONLY)
68#define quiet (main_opts & QUIET)
69#define remove_opt (main_opts & REMOVE_OPT)
70#define do_syslog (main_opts & DO_SYSLOG)
71#define verbose (main_opts & VERBOSE)
72
73static int main_opts;
74
75static int parse_tag_value(char *buffer, char **ptag, char **pvalue)
76{
77 char *tag, *value;
78
79 buffer = skip_whitespace(buffer);
80 tag = value = buffer;
81 while (!isspace(*value))
82 if (!*value) return 0;
83 else value++;
84 *value++ = 0;
85 value = skip_whitespace(value);
86 if (!*value) return 0;
87
88 *ptag = tag;
89 *pvalue = value;
90
91 return 1;
92}
93
94/*
95 * This function appends an option to a list
96 */
97static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt)
98{
99 struct mod_opt_t *ol = opt_list;
100
101 if (ol) {
102 while (ol->m_next) {
103 ol = ol->m_next;
104 }
105 ol->m_next = xmalloc(sizeof(struct mod_opt_t));
106 ol = ol->m_next;
107 } else {
108 ol = opt_list = xmalloc(sizeof(struct mod_opt_t));
109 }
110
111 ol->m_opt_val = xstrdup(opt);
112 ol->m_next = NULL;
113
114 return opt_list;
115}
116
117#if ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS
118/* static char* parse_command_string(char* src, char **dst);
119 * src: pointer to string containing argument
120 * dst: pointer to where to store the parsed argument
121 * return value: the pointer to the first char after the parsed argument,
122 * NULL if there was no argument parsed (only trailing spaces).
123 * Note that memory is allocated with xstrdup when a new argument was
124 * parsed. Don't forget to free it!
125 */
126#define ARG_EMPTY 0x00
127#define ARG_IN_DQUOTES 0x01
128#define ARG_IN_SQUOTES 0x02
129static char *parse_command_string(char *src, char **dst)
130{
131 int opt_status = ARG_EMPTY;
132 char* tmp_str;
133
134 /* Dumb you, I have nothing to do... */
135 if (src == NULL) return src;
136
137 /* Skip leading spaces */
138 while (*src == ' ') {
139 src++;
140 }
141 /* Is the end of string reached? */
142 if (*src == '\0') {
143 return NULL;
144 }
145 /* Reached the start of an argument
146 * By the way, we duplicate a little too much
147 * here but what is too much is freed later. */
148 *dst = tmp_str = xstrdup(src);
149 /* Get to the end of that argument */
150 while (*tmp_str != '\0'
151 && (*tmp_str != ' ' || (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)))
152 ) {
153 switch (*tmp_str) {
154 case '\'':
155 if (opt_status & ARG_IN_DQUOTES) {
156 /* Already in double quotes, keep current char as is */
157 } else {
158 /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
159 memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
160 /* mark me: we enter or leave single quotes */
161 opt_status ^= ARG_IN_SQUOTES;
162 /* Back one char, as we need to re-scan the new char there. */
163 tmp_str--;
164 }
165 break;
166 case '"':
167 if (opt_status & ARG_IN_SQUOTES) {
168 /* Already in single quotes, keep current char as is */
169 } else {
170 /* shift left 1 char, until end of string: get rid of the opening/closing quotes */
171 memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
172 /* mark me: we enter or leave double quotes */
173 opt_status ^= ARG_IN_DQUOTES;
174 /* Back one char, as we need to re-scan the new char there. */
175 tmp_str--;
176 }
177 break;
178 case '\\':
179 if (opt_status & ARG_IN_SQUOTES) {
180 /* Between single quotes: keep as is. */
181 } else {
182 switch (*(tmp_str+1)) {
183 case 'a':
184 case 'b':
185 case 't':
186 case 'n':
187 case 'v':
188 case 'f':
189 case 'r':
190 case '0':
191 /* We escaped a special character. For now, keep
192 * both the back-slash and the following char. */
193 tmp_str++; src++;
194 break;
195 default:
196 /* We escaped a space or a single or double quote,
197 * or a back-slash, or a non-escapable char. Remove
198 * the '\' and keep the new current char as is. */
199 memmove(tmp_str, tmp_str + 1, strlen(tmp_str));
200 break;
201 }
202 }
203 break;
204 /* Any other char that is special shall appear here.
205 * Example: $ starts a variable
206 case '$':
207 do_variable_expansion();
208 break;
209 * */
210 default:
211 /* any other char is kept as is. */
212 break;
213 }
214 tmp_str++; /* Go to next char */
215 src++; /* Go to next char to find the end of the argument. */
216 }
217 /* End of string, but still no ending quote */
218 if (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)) {
219 bb_error_msg_and_die("unterminated (single or double) quote in options list: %s", src);
220 }
221 *tmp_str++ = '\0';
222 *dst = xrealloc(*dst, (tmp_str - *dst));
223 return src;
224}
225#else
226#define parse_command_string(src, dst) (0)
227#endif /* ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS */
228
229/*
230 * This function reads aliases and default module options from a configuration file
231 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
232 */
233static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd)
234{
235 int continuation_line = 0;
236
237 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) !
238
239 while (reads(fd, buffer, buflen)) {
240 int l;
241 char *p;
242
243 p = strchr(buffer, '#');
244 if (p)
245 *p = 0;
246
247 l = strlen(buffer);
248
249 while (l && isspace(buffer[l-1])) {
250 buffer[l-1] = 0;
251 l--;
252 }
253
254 if (l == 0) {
255 continuation_line = 0;
256 continue;
257 }
258
259 if (!continuation_line) {
260 if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
261 char *alias, *mod;
262
263 if (parse_tag_value(buffer + 6, &alias, &mod)) {
264 /* handle alias as a module dependent on the aliased module */
265 if (!*current) {
266 (*first) = (*current) = xzalloc(sizeof(struct dep_t));
267 }
268 else {
269 (*current)->m_next = xzalloc(sizeof(struct dep_t));
270 (*current) = (*current)->m_next;
271 }
272 (*current)->m_name = xstrdup(alias);
273 (*current)->m_isalias = 1;
274
275 if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) {
276 (*current)->m_depcnt = 0;
277 (*current)->m_deparr = 0;
278 }
279 else {
280 (*current)->m_depcnt = 1;
281 (*current)->m_deparr = xmalloc(1 * sizeof(char *));
282 (*current)->m_deparr[0] = xstrdup(mod);
283 }
284 (*current)->m_next = 0;
285 }
286 }
287 else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
288 char *mod, *opt;
289
290 /* split the line in the module/alias name, and options */
291 if (parse_tag_value(buffer + 8, &mod, &opt)) {
292 struct dep_t *dt;
293
294 /* find the corresponding module */
295 for (dt = *first; dt; dt = dt->m_next) {
296 if (strcmp(dt->m_name, mod) == 0)
297 break;
298 }
299 if (dt) {
300 if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) {
301 char* new_opt = NULL;
302 while ((opt = parse_command_string(opt, &new_opt))) {
303 dt->m_options = append_option(dt->m_options, new_opt);
304 }
305 } else {
306 dt->m_options = append_option(dt->m_options, opt);
307 }
308 }
309 }
310 }
311 else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
312 int fdi; char *filename;
313
314 filename = skip_whitespace(buffer + 8);
315
316 if ((fdi = open(filename, O_RDONLY)) >= 0) {
317 include_conf(first, current, buffer, buflen, fdi);
318 close(fdi);
319 }
320 }
321 }
322 }
323}
324
325/*
326 * This function builds a list of dependency rules from /lib/modules/`uname -r`\modules.dep.
327 * It then fills every modules and aliases with their default options, found by parsing
328 * modprobe.conf (or modules.conf, or conf.modules).
329 */
330static struct dep_t *build_dep(void)
331{
332 int fd;
333 struct utsname un;
334 struct dep_t *first = 0;
335 struct dep_t *current = 0;
336 char buffer[2048];
337 char *filename;
338 int continuation_line = 0;
339 int k_version;
340
341 if (uname(&un))
342 bb_error_msg_and_die("can't determine kernel version");
343
344 k_version = 0;
345 if (un.release[0] == '2') {
346 k_version = un.release[2] - '0';
347 }
348
349 filename = xasprintf("/lib/modules/%s/modules.dep", un.release);
350 fd = open(filename, O_RDONLY);
351 if (ENABLE_FEATURE_CLEAN_UP)
352 free(filename);
353 if (fd < 0) {
354 /* Ok, that didn't work. Fall back to looking in /lib/modules */
355 fd = open("/lib/modules/modules.dep", O_RDONLY);
356 if (fd < 0) {
357 return 0;
358 }
359 }
360
361 while (reads(fd, buffer, sizeof(buffer))) {
362 int l = strlen(buffer);
363 char *p = 0;
364
365 while (l > 0 && isspace(buffer[l-1])) {
366 buffer[l-1] = 0;
367 l--;
368 }
369
370 if (l == 0) {
371 continuation_line = 0;
372 continue;
373 }
374
375 /* Is this a new module dep description? */
376 if (!continuation_line) {
377 /* find the dep beginning */
378 char *col = strchr(buffer, ':');
379 char *dot = col;
380
381 if (col) {
382 /* This line is a dep description */
383 char *mods;
384 char *modpath;
385 char *mod;
386
387 /* Find the beginning of the module file name */
388 *col = 0;
389 mods = strrchr(buffer, '/');
390
391 if (!mods)
392 mods = buffer; /* no path for this module */
393 else
394 mods++; /* there was a path for this module... */
395
396 /* find the path of the module */
397 modpath = strchr(buffer, '/'); /* ... and this is the path */
398 if (!modpath)
399 modpath = buffer; /* module with no path */
400 /* find the end of the module name in the file name */
401 if (ENABLE_FEATURE_2_6_MODULES &&
402 (k_version > 4) && (*(col-3) == '.') &&
403 (*(col-2) == 'k') && (*(col-1) == 'o'))
404 dot = col - 3;
405 else
406 if ((*(col-2) == '.') && (*(col-1) == 'o'))
407 dot = col - 2;
408
409 mod = xstrndup(mods, dot - mods);
410
411 /* enqueue new module */
412 if (!current) {
413 first = current = xmalloc(sizeof(struct dep_t));
414 }
415 else {
416 current->m_next = xmalloc(sizeof(struct dep_t));
417 current = current->m_next;
418 }
419 current->m_name = mod;
420 current->m_path = xstrdup(modpath);
421 current->m_options = NULL;
422 current->m_isalias = 0;
423 current->m_depcnt = 0;
424 current->m_deparr = 0;
425 current->m_next = 0;
426
427 p = col + 1;
428 }
429 else
430 /* this line is not a dep description */
431 p = 0;
432 }
433 else
434 /* It's a dep description continuation */
435 p = buffer;
436
437 while (p && *p && isblank(*p))
438 p++;
439
440 /* p points to the first dependable module; if NULL, no dependable module */
441 if (p && *p) {
442 char *end = &buffer[l-1];
443 char *deps;
444 char *dep;
445 char *next;
446 int ext = 0;
447
448 while (isblank(*end) || (*end == '\\'))
449 end--;
450
451 do {
452 /* search the end of the dependency */
453 next = strchr(p, ' ');
454 if (next) {
455 *next = 0;
456 next--;
457 }
458 else
459 next = end;
460
461 /* find the beginning of the module file name */
462 deps = strrchr(p, '/');
463
464 if (!deps || (deps < p)) {
465 deps = p;
466
467 while (isblank(*deps))
468 deps++;
469 } else
470 deps++;
471
472 /* find the end of the module name in the file name */
473 if (ENABLE_FEATURE_2_6_MODULES
474 && (k_version > 4) && (*(next-2) == '.')
475 && (*(next-1) == 'k') && (*next == 'o'))
476 ext = 3;
477 else
478 if ((*(next-1) == '.') && (*next == 'o'))
479 ext = 2;
480
481 /* Cope with blank lines */
482 if ((next-deps-ext+1) <= 0)
483 continue;
484 dep = xstrndup(deps, next - deps - ext + 1);
485
486 /* Add the new dependable module name */
487 current->m_depcnt++;
488 current->m_deparr = xrealloc(current->m_deparr,
489 sizeof(char *) * current->m_depcnt);
490 current->m_deparr[current->m_depcnt - 1] = dep;
491
492 p = next + 2;
493 } while (next < end);
494 }
495
496 /* is there other dependable module(s) ? */
497 if (buffer[l-1] == '\\')
498 continuation_line = 1;
499 else
500 continuation_line = 0;
501 }
502 close(fd);
503
504 /*
505 * First parse system-specific options and aliases
506 * as they take precedence over the kernel ones.
507 */
508 if (!ENABLE_FEATURE_2_6_MODULES
509 || (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0)
510 if ((fd = open("/etc/modules.conf", O_RDONLY)) < 0)
511 fd = open("/etc/conf.modules", O_RDONLY);
512
513 if (fd >= 0) {
514 include_conf(&first, &current, buffer, sizeof(buffer), fd);
515 close(fd);
516 }
517
518 /* Only 2.6 has a modules.alias file */
519 if (ENABLE_FEATURE_2_6_MODULES) {
520 /* Parse kernel-declared aliases */
521 filename = xasprintf("/lib/modules/%s/modules.alias", un.release);
522 fd = open(filename, O_RDONLY);
523 if (fd < 0) {
524 /* Ok, that didn't work. Fall back to looking in /lib/modules */
525 fd = open("/lib/modules/modules.alias", O_RDONLY);
526 }
527 if (ENABLE_FEATURE_CLEAN_UP)
528 free(filename);
529
530 if (fd >= 0) {
531 include_conf(&first, &current, buffer, sizeof(buffer), fd);
532 close(fd);
533 }
534 }
535
536 return first;
537}
538
539/* return 1 = loaded, 0 = not loaded, -1 = can't tell */
540static int already_loaded(const char *name)
541{
542 int fd, ret = 0;
543 char buffer[4096];
544
545 fd = open("/proc/modules", O_RDONLY);
546 if (fd < 0)
547 return -1;
548
549 while (reads(fd, buffer, sizeof(buffer))) {
550 char *p;
551
552 p = strchr (buffer, ' ');
553 if (p) {
554 const char *n;
555
556 // Truncate buffer at first space and check for matches, with
557 // the idiosyncrasy that _ and - are interchangeable because the
558 // 2.6 kernel does weird things.
559
560 *p = 0;
561 for (p = buffer, n = name; ; p++, n++) {
562 if (*p != *n) {
563 if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-'))
564 continue;
565 break;
566 }
567 // If we made it to the end, that's a match.
568 if (!*p) {
569 ret = 1;
570 goto done;
571 }
572 }
573 }
574 }
575done:
576 close (fd);
577 return ret;
578}
579
580static int mod_process(struct mod_list_t *list, int do_insert)
581{
582 int rc = 0;
583 char **argv = NULL;
584 struct mod_opt_t *opts;
585 int argc_malloc; /* never used when CONFIG_FEATURE_CLEAN_UP not defined */
586 int argc;
587
588 while (list) {
589 argc = 0;
590 if (ENABLE_FEATURE_CLEAN_UP)
591 argc_malloc = 0;
592 /* If CONFIG_FEATURE_CLEAN_UP is not defined, then we leak memory
593 * each time we allocate memory for argv.
594 * But it is (quite) small amounts of memory that leak each
595 * time a module is loaded, and it is reclaimed when modprobe
596 * exits anyway (even when standalone shell?).
597 * This could become a problem when loading a module with LOTS of
598 * dependencies, with LOTS of options for each dependencies, with
599 * very little memory on the target... But in that case, the module
600 * would not load because there is no more memory, so there's no
601 * problem. */
602 /* enough for minimal insmod (5 args + NULL) or rmmod (3 args + NULL) */
603 argv = xmalloc(6 * sizeof(char*));
604 if (do_insert) {
605 if (already_loaded(list->m_name) != 1) {
606 argv[argc++] = "insmod";
607 if (ENABLE_FEATURE_2_4_MODULES) {
608 if (do_syslog)
609 argv[argc++] = "-s";
610 if (autoclean)
611 argv[argc++] = "-k";
612 if (quiet)
613 argv[argc++] = "-q";
614 else if (verbose) /* verbose and quiet are mutually exclusive */
615 argv[argc++] = "-v";
616 }
617 argv[argc++] = list->m_path;
618 if (ENABLE_FEATURE_CLEAN_UP)
619 argc_malloc = argc;
620 opts = list->m_options;
621 while (opts) {
622 /* Add one more option */
623 argc++;
624 argv = xrealloc(argv,(argc + 1)* sizeof(char*));
625 argv[argc-1] = opts->m_opt_val;
626 opts = opts->m_next;
627 }
628 }
629 } else {
630 /* modutils uses short name for removal */
631 if (already_loaded(list->m_name) != 0) {
632 argv[argc++] = "rmmod";
633 if (do_syslog)
634 argv[argc++] = "-s";
635 argv[argc++] = list->m_name;
636 if (ENABLE_FEATURE_CLEAN_UP)
637 argc_malloc = argc;
638 }
639 }
640 argv[argc] = NULL;
641
642 if (argc) {
643 if (verbose) {
644 printf("%s module %s\n", do_insert?"Loading":"Unloading", list->m_name);
645 }
646 if (!show_only) {
647 int rc2 = wait4pid(spawn(argv));
648
649 if (do_insert) {
650 rc = rc2; /* only last module matters */
651 }
652 else if (!rc2) {
653 rc = 0; /* success if remove any mod */
654 }
655 }
656 if (ENABLE_FEATURE_CLEAN_UP) {
657 /* the last value in the array has index == argc, but
658 * it is the terminating NULL, so we must not free it. */
659 while (argc_malloc < argc) {
660 free(argv[argc_malloc++]);
661 }
662 }
663 }
664 if (ENABLE_FEATURE_CLEAN_UP) {
665 free(argv);
666 argv = NULL;
667 }
668 list = do_insert ? list->m_prev : list->m_next;
669 }
670 return (show_only) ? 0 : rc;
671}
672
673/*
674 * Check the matching between a pattern and a module name.
675 * We need this as *_* is equivalent to *-*, even in pattern matching.
676 */
677static int check_pattern(const char* pat_src, const char* mod_src) {
678 int ret;
679
680 if (ENABLE_FEATURE_MODPROBE_FANCY_ALIAS) {
681 char* pat;
682 char* mod;
683 char* p;
684
685 pat = xstrdup (pat_src);
686 mod = xstrdup (mod_src);
687
688 for (p = pat; (p = strchr(p, '-')); *p++ = '_');
689 for (p = mod; (p = strchr(p, '-')); *p++ = '_');
690
691 ret = fnmatch(pat, mod, 0);
692
693 if (ENABLE_FEATURE_CLEAN_UP) {
694 free (pat);
695 free (mod);
696 }
697
698 return ret;
699 } else {
700 return fnmatch(pat_src, mod_src, 0);
701 }
702}
703
704/*
705 * Builds the dependency list (aka stack) of a module.
706 * head: the highest module in the stack (last to insmod, first to rmmod)
707 * tail: the lowest module in the stack (first to insmod, last to rmmod)
708 */
709static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **tail)
710{
711 struct mod_list_t *find;
712 struct dep_t *dt;
713 struct mod_opt_t *opt = 0;
714 char *path = 0;
715
716 /* Search for the given module name amongst all dependency rules.
717 * The module name in a dependency rule can be a shell pattern,
718 * so try to match the given module name against such a pattern.
719 * Of course if the name in the dependency rule is a plain string,
720 * then we consider it a pattern, and matching will still work. */
721 for (dt = depend; dt; dt = dt->m_next) {
722 if (check_pattern(dt->m_name, mod) == 0) {
723 break;
724 }
725 }
726
727 if (!dt) {
728 bb_error_msg("module %s not found", mod);
729 return;
730 }
731
732 // resolve alias names
733 while (dt->m_isalias) {
734 if (dt->m_depcnt == 1) {
735 struct dep_t *adt;
736
737 for (adt = depend; adt; adt = adt->m_next) {
738 if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0)
739 break;
740 }
741 if (adt) {
742 /* This is the module we are aliased to */
743 struct mod_opt_t *opts = dt->m_options;
744 /* Option of the alias are appended to the options of the module */
745 while (opts) {
746 adt->m_options = append_option(adt->m_options, opts->m_opt_val);
747 opts = opts->m_next;
748 }
749 dt = adt;
750 }
751 else {
752 bb_error_msg("module %s not found", mod);
753 return;
754 }
755 }
756 else {
757 bb_error_msg("bad alias %s", dt->m_name);
758 return;
759 }
760 }
761
762 mod = dt->m_name;
763 path = dt->m_path;
764 opt = dt->m_options;
765
766 // search for duplicates
767 for (find = *head; find; find = find->m_next) {
768 if (!strcmp(mod, find->m_name)) {
769 // found ->dequeue it
770
771 if (find->m_prev)
772 find->m_prev->m_next = find->m_next;
773 else
774 *head = find->m_next;
775
776 if (find->m_next)
777 find->m_next->m_prev = find->m_prev;
778 else
779 *tail = find->m_prev;
780
781 break; // there can be only one duplicate
782 }
783 }
784
785 if (!find) { // did not find a duplicate
786 find = xmalloc(sizeof(struct mod_list_t));
787 find->m_name = mod;
788 find->m_path = path;
789 find->m_options = opt;
790 }
791
792 // enqueue at tail
793 if (*tail)
794 (*tail)->m_next = find;
795 find->m_prev = *tail;
796 find->m_next = 0;
797
798 if (!*head)
799 *head = find;
800 *tail = find;
801
802 if (dt) {
803 int i;
804
805 /* Add all dependable module for that new module */
806 for (i = 0; i < dt->m_depcnt; i++)
807 check_dep(dt->m_deparr[i], head, tail);
808 }
809}
810
811static int mod_insert(char *mod, int argc, char **argv)
812{
813 struct mod_list_t *tail = 0;
814 struct mod_list_t *head = 0;
815 int rc;
816
817 // get dep list for module mod
818 check_dep(mod, &head, &tail);
819
820 if (head && tail) {
821 if (argc) {
822 int i;
823 // append module args
824 for (i = 0; i < argc; i++)
825 head->m_options = append_option(head->m_options, argv[i]);
826 }
827
828 // process tail ---> head
829 if ((rc = mod_process(tail, 1)) != 0) {
830 /*
831 * In case of using udev, multiple instances of modprobe can be
832 * spawned to load the same module (think of two same usb devices,
833 * for example; or cold-plugging at boot time). Thus we shouldn't
834 * fail if the module was loaded, and not by us.
835 */
836 if (already_loaded(mod))
837 rc = 0;
838 }
839 }
840 else
841 rc = 1;
842
843 return rc;
844}
845
846static int mod_remove(char *mod)
847{
848 int rc;
849 static struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL };
850
851 struct mod_list_t *head = 0;
852 struct mod_list_t *tail = 0;
853
854 if (mod)
855 check_dep(mod, &head, &tail);
856 else // autoclean
857 head = tail = &rm_a_dummy;
858
859 if (head && tail)
860 rc = mod_process(head, 0); // process head ---> tail
861 else
862 rc = 1;
863 return rc;
864
865}
866
867int modprobe_main(int argc, char** argv)
868{
869 int rc = EXIT_SUCCESS;
870 char *unused;
871
872 opt_complementary = "?V-:q-v:v-q";
873 main_opts = getopt32(argc, argv, "acdklnqrst:vVC:",
874 &unused, &unused);
875 if (main_opts & (DUMP_CONF_EXIT | LIST_ALL))
876 return EXIT_SUCCESS;
877 if (main_opts & (RESTRICT_DIR | CONFIG_FILE))
878 bb_error_msg_and_die("-t and -C not supported");
879
880 depend = build_dep();
881
882 if (!depend)
883 bb_error_msg_and_die("cannot parse modules.dep");
884
885 if (remove_opt) {
886 do {
887 if (mod_remove(optind < argc ?
888 argv[optind] : NULL)) {
889 bb_error_msg("failed to remove module %s",
890 argv[optind]);
891 rc = EXIT_FAILURE;
892 }
893 } while (++optind < argc);
894 } else {
895 if (optind >= argc)
896 bb_error_msg_and_die("no module or pattern provided");
897
898 if (mod_insert(argv[optind], argc - optind - 1, argv + optind + 1))
899 bb_error_msg_and_die("failed to load module %s", argv[optind]);
900 }
901
902 /* Here would be a good place to free up memory allocated during the dependencies build. */
903
904 return rc;
905}
diff --git a/modutils/rmmod.c b/modutils/rmmod.c
new file mode 100644
index 000000000..22e864d57
--- /dev/null
+++ b/modutils/rmmod.c
@@ -0,0 +1,96 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini rmmod implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
9
10#include "busybox.h"
11#include <sys/syscall.h>
12
13#ifdef CONFIG_FEATURE_2_6_MODULES
14static inline void filename2modname(char *modname, const char *afterslash)
15{
16 unsigned int i;
17 int kr_chk = 1;
18
19 if (ENABLE_FEATURE_2_4_MODULES
20 && get_linux_version_code() <= KERNEL_VERSION(2,6,0))
21 kr_chk = 0;
22
23 /* Convert to underscores, stop at first . */
24 for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
25 if (kr_chk && (afterslash[i] == '-'))
26 modname[i] = '_';
27 else
28 modname[i] = afterslash[i];
29 }
30 modname[i] = '\0';
31}
32#else
33void filename2modname(char *modname, const char *afterslash);
34#endif
35
36// There really should be a header file for this...
37
38int query_module(const char *name, int which, void *buf,
39 size_t bufsize, size_t *ret);
40
41int rmmod_main(int argc, char **argv)
42{
43 int n, ret = EXIT_SUCCESS;
44 unsigned int flags = O_NONBLOCK|O_EXCL;
45
46 /* Parse command line. */
47 n = getopt32(argc, argv, "wfa");
48 if((n & 1)) // --wait
49 flags &= ~O_NONBLOCK;
50 if((n & 2)) // --force
51 flags |= O_TRUNC;
52 if((n & 4)) {
53 /* Unload _all_ unused modules via NULL delete_module() call */
54 /* until the number of modules does not change */
55 size_t nmod = 0; /* number of modules */
56 size_t pnmod = -1; /* previous number of modules */
57
58 while (nmod != pnmod) {
59 if (syscall(__NR_delete_module, NULL, flags) != 0) {
60 if (errno == EFAULT)
61 return ret;
62 bb_perror_msg_and_die("rmmod");
63 }
64 pnmod = nmod;
65 // the 1 here is QM_MODULES.
66 if (ENABLE_FEATURE_QUERY_MODULE_INTERFACE && query_module(NULL,
67 1, bb_common_bufsiz1, sizeof(bb_common_bufsiz1),
68 &nmod))
69 {
70 bb_perror_msg_and_die("QM_MODULES");
71 }
72 }
73 return EXIT_SUCCESS;
74 }
75
76 if (optind == argc)
77 bb_show_usage();
78
79 for (n = optind; n < argc; n++) {
80 if (ENABLE_FEATURE_2_6_MODULES) {
81 const char *afterslash;
82
83 afterslash = strrchr(argv[n], '/');
84 if (!afterslash) afterslash = argv[n];
85 else afterslash++;
86 filename2modname(bb_common_bufsiz1, afterslash);
87 }
88
89 if (syscall(__NR_delete_module, ENABLE_FEATURE_2_6_MODULES ? bb_common_bufsiz1 : argv[n], flags)) {
90 bb_perror_msg("%s", argv[n]);
91 ret = EXIT_FAILURE;
92 }
93 }
94
95 return ret;
96}