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