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