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