source: trunk/mindi-busybox/modutils/insmod.c @ 956

Last change on this file since 956 was 821, checked in by bruno, 13 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

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