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