source: MondoRescue/branches/stable/mindi-busybox/modutils/insmod.c @ 1770

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 12 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod? silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian? keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René? Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

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