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