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