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