136f9f06205208af3a36eb700e985e95e31a55c1
[oweals/busybox.git] / insmod.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini insmod implementation for busybox
4  *
5  * Copyright (C) 1999,2000 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>
7  * and Ron Alder <alder@lineo.com>
8  *
9  * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10  * and (theoretically) SH3. Note that there is still no true
11  * multiple architecture support. You just get SH3|SH4|i386, despite
12  * the mention of ARM and m68k--which may or may not work (but
13  * almost certainly do not, due to at least MATCH_MACHINE). I have
14  * only tested SH4 in little endian mode.
15  *
16  * Based almost entirely on the Linux modutils-2.3.11 implementation.
17  *   Copyright 1996, 1997 Linux International.
18  *   New implementation contributed by Richard Henderson <rth@tamu.edu>
19  *   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
20  *   Restructured (and partly rewritten) by:
21  *   Björn Ekwall <bj0rn@blox.se> February 1999
22  *
23  * This program is free software; you can redistribute it and/or modify
24  * it under the terms of the GNU General Public License as published by
25  * the Free Software Foundation; either version 2 of the License, or
26  * (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31  * General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36  *
37  */
38
39 #include "internal.h"
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <stddef.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <dirent.h>
46 #include <ctype.h>
47 #include <assert.h>
48 #include <getopt.h>
49 #include <sys/utsname.h>
50
51 //----------------------------------------------------------------------------
52 //--------modutils module.h, lines 45-242
53 //----------------------------------------------------------------------------
54
55 /* Definitions for the Linux module syscall interface.
56    Copyright 1996, 1997 Linux International.
57
58    Contributed by Richard Henderson <rth@tamu.edu>
59
60    This file is part of the Linux modutils.
61
62    This program is free software; you can redistribute it and/or modify it
63    under the terms of the GNU General Public License as published by the
64    Free Software Foundation; either version 2 of the License, or (at your
65    option) any later version.
66
67    This program is distributed in the hope that it will be useful, but
68    WITHOUT ANY WARRANTY; without even the implied warranty of
69    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
70    General Public License for more details.
71
72    You should have received a copy of the GNU General Public License
73    along with this program; if not, write to the Free Software Foundation,
74    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
75
76
77 #ifndef MODUTILS_MODULE_H
78 #define MODUTILS_MODULE_H 1
79
80 #ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
81
82 /* This file contains the structures used by the 2.0 and 2.1 kernels.
83    We do not use the kernel headers directly because we do not wish
84    to be dependant on a particular kernel version to compile insmod.  */
85
86
87 /*======================================================================*/
88 /* The structures used by Linux 2.0.  */
89
90 /* The symbol format used by get_kernel_syms(2).  */
91 struct old_kernel_sym
92 {
93   unsigned long value;
94   char name[60];
95 };
96
97 struct old_module_ref
98 {
99   unsigned long module;         /* kernel addresses */
100   unsigned long next;
101 };
102
103 struct old_module_symbol
104 {
105   unsigned long addr;
106   unsigned long name;
107 };
108
109 struct old_symbol_table
110 {
111   int size;                     /* total, including string table!!! */
112   int n_symbols;
113   int n_refs;
114   struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */
115   struct old_module_ref ref[0]; /* actual size defined by n_refs */
116 };
117
118 struct old_mod_routines
119 {
120   unsigned long init;
121   unsigned long cleanup;
122 };
123
124 struct old_module
125 {
126   unsigned long next;
127   unsigned long ref;            /* the list of modules that refer to me */
128   unsigned long symtab;
129   unsigned long name;
130   int size;                     /* size of module in pages */
131   unsigned long addr;           /* address of module */
132   int state;
133   unsigned long cleanup;        /* cleanup routine */
134 };
135
136 /* Sent to init_module(2) or'ed into the code size parameter.  */
137 #define OLD_MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */
138
139 int get_kernel_syms(struct old_kernel_sym *);
140 int old_sys_init_module(const char *name, char *code, unsigned codesize,
141                         struct old_mod_routines *, struct old_symbol_table *);
142
143 /*======================================================================*/
144 /* For sizeof() which are related to the module platform and not to the
145    environment isnmod is running in, use sizeof_xx instead of sizeof(xx).  */
146
147 #define tgt_sizeof_char         sizeof(char)
148 #define tgt_sizeof_short        sizeof(short)
149 #define tgt_sizeof_int          sizeof(int)
150 #define tgt_sizeof_long         sizeof(long)
151 #define tgt_sizeof_char_p       sizeof(char *)
152 #define tgt_sizeof_void_p       sizeof(void *)
153 #define tgt_long                long
154
155 #if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
156 #undef tgt_sizeof_long
157 #undef tgt_sizeof_char_p
158 #undef tgt_sizeof_void_p
159 #undef tgt_long
160 #define tgt_sizeof_long         8
161 #define tgt_sizeof_char_p       8
162 #define tgt_sizeof_void_p       8
163 #define tgt_long                long long
164 #endif
165
166 /*======================================================================*/
167 /* The structures used in Linux 2.1.  */
168
169 /* Note: new_module_symbol does not use tgt_long intentionally */
170 struct new_module_symbol
171 {
172   unsigned long value;
173   unsigned long name;
174 };
175
176 struct new_module_persist;
177
178 struct new_module_ref
179 {
180   unsigned tgt_long dep;                /* kernel addresses */
181   unsigned tgt_long ref;
182   unsigned tgt_long next_ref;
183 };
184
185 struct new_module
186 {
187   unsigned tgt_long size_of_struct;     /* == sizeof(module) */
188   unsigned tgt_long next;
189   unsigned tgt_long name;
190   unsigned tgt_long size;
191
192   tgt_long usecount;
193   unsigned tgt_long flags;              /* AUTOCLEAN et al */
194
195   unsigned nsyms;
196   unsigned ndeps;
197
198   unsigned tgt_long syms;
199   unsigned tgt_long deps;
200   unsigned tgt_long refs;
201   unsigned tgt_long init;
202   unsigned tgt_long cleanup;
203   unsigned tgt_long ex_table_start;
204   unsigned tgt_long ex_table_end;
205 #ifdef __alpha__
206   unsigned tgt_long gp;
207 #endif
208   /* Everything after here is extension.  */
209   unsigned tgt_long persist_start;
210   unsigned tgt_long persist_end;
211   unsigned tgt_long can_unload;
212   unsigned tgt_long runsize;
213 };
214
215 struct new_module_info
216 {
217   unsigned long addr;
218   unsigned long size;
219   unsigned long flags;
220            long usecount;
221 };
222
223 /* Bits of module.flags.  */
224 #define NEW_MOD_RUNNING         1
225 #define NEW_MOD_DELETED         2
226 #define NEW_MOD_AUTOCLEAN       4
227 #define NEW_MOD_VISITED         8
228 #define NEW_MOD_USED_ONCE       16
229
230 int new_sys_init_module(const char *name, const struct new_module *);
231 int query_module(const char *name, int which, void *buf, size_t bufsize,
232                  size_t *ret);
233
234 /* Values for query_module's which.  */
235
236 #define QM_MODULES      1
237 #define QM_DEPS         2
238 #define QM_REFS         3
239 #define QM_SYMBOLS      4
240 #define QM_INFO         5
241
242 /*======================================================================*/
243 /* The system calls unchanged between 2.0 and 2.1.  */
244
245 unsigned long create_module(const char *, size_t);
246 int delete_module(const char *);
247
248
249 #endif /* module.h */
250
251 //----------------------------------------------------------------------------
252 //--------end of modutils module.h
253 //----------------------------------------------------------------------------
254
255
256
257 //----------------------------------------------------------------------------
258 //--------modutils obj.h, lines 253-462
259 //----------------------------------------------------------------------------
260
261 /* Elf object file loading and relocation routines.
262    Copyright 1996, 1997 Linux International.
263
264    Contributed by Richard Henderson <rth@tamu.edu>
265
266    This file is part of the Linux modutils.
267
268    This program is free software; you can redistribute it and/or modify it
269    under the terms of the GNU General Public License as published by the
270    Free Software Foundation; either version 2 of the License, or (at your
271    option) any later version.
272
273    This program is distributed in the hope that it will be useful, but
274    WITHOUT ANY WARRANTY; without even the implied warranty of
275    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
276    General Public License for more details.
277
278    You should have received a copy of the GNU General Public License
279    along with this program; if not, write to the Free Software Foundation,
280    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
281
282
283 #ifndef MODUTILS_OBJ_H
284 #define MODUTILS_OBJ_H 1
285
286 #ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
287
288 /* The relocatable object is manipulated using elfin types.  */
289
290 #include <stdio.h>
291 #include <elf.h>
292
293
294 /* Machine-specific elf macros for i386 et al.  */
295
296 /* the SH changes have only been tested on the SH4 in =little endian= mode */
297 /* I'm not sure about big endian, so let's warn: */
298
299 #if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
300 #error insmod.c may require changes for use on big endian SH4/SH3
301 #endif
302
303 /* it may or may not work on the SH1/SH2... So let's error on those
304    also */
305 #if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
306 #error insmod.c may require changes for non-SH3/SH4 use
307 #endif
308
309 #define ELFCLASSM       ELFCLASS32
310 #define ELFDATAM        ELFDATA2LSB
311
312
313
314 #if defined(__sh__)
315
316 #define MATCH_MACHINE(x) (x == EM_SH)
317 #define SHT_RELM        SHT_RELA
318 #define Elf32_RelM      Elf32_Rela
319
320 #else
321
322 /* presumably we can use these for anything but the SH */
323 /* this is the previous behavior, but it does result in
324    insmod.c being broken on anything except i386 */
325
326 #define MATCH_MACHINE(x)  (x == EM_386 || x == EM_486)
327 #define SHT_RELM        SHT_REL
328 #define Elf32_RelM      Elf32_Rel
329
330 #endif
331
332 #ifndef ElfW
333 # if ELFCLASSM == ELFCLASS32
334 #  define ElfW(x)  Elf32_ ## x
335 #  define ELFW(x)  ELF32_ ## x
336 # else
337 #  define ElfW(x)  Elf64_ ## x
338 #  define ELFW(x)  ELF64_ ## x
339 # endif
340 #endif
341
342 /* For some reason this is missing from libc5.  */
343 #ifndef ELF32_ST_INFO
344 # define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
345 #endif
346
347 #ifndef ELF64_ST_INFO
348 # define ELF64_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
349 #endif
350
351 struct obj_string_patch;
352 struct obj_symbol_patch;
353
354 struct obj_section
355 {
356   ElfW(Shdr) header;
357   const char *name;
358   char *contents;
359   struct obj_section *load_next;
360   int idx;
361 };
362
363 struct obj_symbol
364 {
365   struct obj_symbol *next;      /* hash table link */
366   const char *name;
367   unsigned long value;
368   unsigned long size;
369   int secidx;                   /* the defining section index/module */
370   int info;
371   int ksymidx;                  /* for export to the kernel symtab */
372   int referenced;               /* actually used in the link */
373 };
374
375 /* Hardcode the hash table size.  We shouldn't be needing so many
376    symbols that we begin to degrade performance, and we get a big win
377    by giving the compiler a constant divisor.  */
378
379 #define HASH_BUCKETS  521
380
381 struct obj_file
382 {
383   ElfW(Ehdr) header;
384   ElfW(Addr) baseaddr;
385   struct obj_section **sections;
386   struct obj_section *load_order;
387   struct obj_section **load_order_search_start;
388   struct obj_string_patch *string_patches;
389   struct obj_symbol_patch *symbol_patches;
390   int (*symbol_cmp)(const char *, const char *);
391   unsigned long (*symbol_hash)(const char *);
392   unsigned long local_symtab_size;
393   struct obj_symbol **local_symtab;
394   struct obj_symbol *symtab[HASH_BUCKETS];
395 };
396
397 enum obj_reloc
398 {
399   obj_reloc_ok,
400   obj_reloc_overflow,
401   obj_reloc_dangerous,
402   obj_reloc_unhandled
403 };
404
405 struct obj_string_patch
406 {
407   struct obj_string_patch *next;
408   int reloc_secidx;
409   ElfW(Addr) reloc_offset;
410   ElfW(Addr) string_offset;
411 };
412
413 struct obj_symbol_patch
414 {
415   struct obj_symbol_patch *next;
416   int reloc_secidx;
417   ElfW(Addr) reloc_offset;
418   struct obj_symbol *sym;
419 };
420
421
422 /* Generic object manipulation routines.  */
423
424 unsigned long obj_elf_hash(const char *);
425
426 unsigned long obj_elf_hash_n(const char *, unsigned long len);
427
428 struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name,
429                                    unsigned long symidx, int info, int secidx,
430                                    ElfW(Addr) value, unsigned long size);
431
432 struct obj_symbol *obj_find_symbol (struct obj_file *f,
433                                          const char *name);
434
435 ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
436                                   struct obj_symbol *sym);
437
438 void obj_set_symbol_compare(struct obj_file *f,
439                             int (*cmp)(const char *, const char *),
440                             unsigned long (*hash)(const char *));
441
442 struct obj_section *obj_find_section (struct obj_file *f,
443                                            const char *name);
444
445 void obj_insert_section_load_order (struct obj_file *f,
446                                     struct obj_section *sec);
447
448 struct obj_section *obj_create_alloced_section (struct obj_file *f,
449                                                 const char *name,
450                                                 unsigned long align,
451                                                 unsigned long size);
452
453 struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
454                                                       const char *name,
455                                                       unsigned long align,
456                                                       unsigned long size);
457
458 void *obj_extend_section (struct obj_section *sec, unsigned long more);
459
460 int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
461                      const char *string);
462
463 int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
464                      struct obj_symbol *sym);
465
466 int obj_check_undefineds(struct obj_file *f);
467
468 void obj_allocate_commons(struct obj_file *f);
469
470 unsigned long obj_load_size (struct obj_file *f);
471
472 int obj_relocate (struct obj_file *f, ElfW(Addr) base);
473
474 struct obj_file *obj_load(FILE *f);
475
476 int obj_create_image (struct obj_file *f, char *image);
477
478 /* Architecture specific manipulation routines.  */
479
480 struct obj_file *arch_new_file (void);
481
482 struct obj_section *arch_new_section (void);
483
484 struct obj_symbol *arch_new_symbol (void);
485
486 enum obj_reloc arch_apply_relocation (struct obj_file *f,
487                                       struct obj_section *targsec,
488                                       struct obj_section *symsec,
489                                       struct obj_symbol *sym,
490                                       ElfW(RelM) *rel, ElfW(Addr) value);
491
492 int arch_create_got (struct obj_file *f);
493
494 struct new_module;
495 int arch_init_module (struct obj_file *f, struct new_module *);
496
497 #endif /* obj.h */
498 //----------------------------------------------------------------------------
499 //--------end of modutils obj.h
500 //----------------------------------------------------------------------------
501
502
503
504
505
506 #define _PATH_MODULES   "/lib/modules"
507 #define STRVERSIONLEN   32
508
509 #if !defined(BB_FEATURE_INSMOD_NEW_KERNEL) && !defined(BB_FEATURE_INSMOD_OLD_KERNEL)
510 #error "Must have ether BB_FEATURE_INSMOD_NEW_KERNEL or BB_FEATURE_INSMOD_OLD_KERNEL defined"
511 #endif
512
513 /*======================================================================*/
514
515 int flag_force_load = 0;
516 int flag_autoclean = 0;
517 int flag_verbose = 0;
518 int flag_export = 1;
519
520
521 /*======================================================================*/
522
523 /* previously, these were named i386_* but since we could be
524    compiling for the sh, I've renamed them to the more general
525    arch_* These structures are the same between the x86 and SH, 
526    and we can't support anything else right now anyway. In the
527    future maybe they should be #if defined'd */
528
529 struct arch_got_entry {
530         int offset;
531         unsigned offset_done:1;
532         unsigned reloc_done:1;
533 };
534
535 struct arch_file {
536         struct obj_file root;
537         struct obj_section *got;
538 };
539
540 struct arch_symbol {
541         struct obj_symbol root;
542         struct arch_got_entry gotent;
543 };
544
545
546 struct external_module {
547         const char *name;
548         ElfW(Addr) addr;
549         int used;
550         size_t nsyms;
551         struct new_module_symbol *syms;
552 };
553
554 struct new_module_symbol *ksyms;
555 size_t nksyms;
556
557 struct external_module *ext_modules;
558 int n_ext_modules;
559 int n_ext_modules_used;
560
561
562
563 /* Some firendly syscalls to cheer everyone's day...  */
564 #define __NR_new_sys_init_module  __NR_init_module
565 _syscall2(int, new_sys_init_module, const char *, name,
566                   const struct new_module *, info)
567 #define __NR_old_sys_init_module  __NR_init_module
568 _syscall5(int, old_sys_init_module, const char *, name, char *, code,
569                   unsigned, codesize, struct old_mod_routines *, routines,
570                   struct old_symbol_table *, symtab)
571 #ifndef BB_RMMOD
572 _syscall1(int, delete_module, const char *, name)
573 #else
574 extern int delete_module(const char *);
575 #endif
576
577 /* This is kind of troublesome. See, we don't actually support
578    the m68k or the arm the same way we support i386 and (now)
579    sh. In doing my SH patch, I just assumed that whatever works
580    for i386 also works for m68k and arm since currently insmod.c
581    does nothing special for them. If this isn't true, the below
582    line is rather misleading IMHO, and someone should either
583    change it or add more proper architecture-dependent support
584    for these boys.
585
586    -- Bryan Rittmeyer <bryan@ixiacom.com>                    */
587
588 #if defined(__i386__) || defined(__m68k__) || defined(__arm__)
589 /* Jump through hoops to fixup error return codes */
590 #define __NR__create_module  __NR_create_module
591 static inline _syscall2(long, _create_module, const char *, name, size_t,
592                                                 size)
593 unsigned long create_module(const char *name, size_t size)
594 {
595         long ret = _create_module(name, size);
596
597         if (ret == -1 && errno > 125) {
598                 ret = -errno;
599                 errno = 0;
600         }
601         return ret;
602 }
603 #else
604 _syscall2(unsigned long, create_module, const char *, name, size_t, size)
605 #endif
606 static char m_filename[BUFSIZ + 1] = "\0";
607 static char m_fullName[BUFSIZ + 1] = "\0";
608
609 /*======================================================================*/
610
611
612 static int findNamedModule(const char *fileName, struct stat *statbuf,
613                                                    void *userDate)
614 {
615         char *fullName = (char *) userDate;
616
617
618         if (fullName[0] == '\0')
619                 return (FALSE);
620         else {
621                 char *tmp = strrchr(fileName, '/');
622
623                 if (tmp == NULL)
624                         tmp = (char *) fileName;
625                 else
626                         tmp++;
627                 if (check_wildcard_match(tmp, fullName) == TRUE) {
628                         /* Stop searching if we find a match */
629                         memcpy(m_filename, fileName, strlen(fileName)+1);
630                         return (FALSE);
631                 }
632         }
633         return (TRUE);
634 }
635
636
637 /*======================================================================*/
638
639 struct obj_file *arch_new_file(void)
640 {
641         struct arch_file *f;
642         f = xmalloc(sizeof(*f));
643         f->got = NULL;
644         return &f->root;
645 }
646
647 struct obj_section *arch_new_section(void)
648 {
649         return xmalloc(sizeof(struct obj_section));
650 }
651
652 struct obj_symbol *arch_new_symbol(void)
653 {
654         struct arch_symbol *sym;
655         sym = xmalloc(sizeof(*sym));
656         memset(&sym->gotent, 0, sizeof(sym->gotent));
657         return &sym->root;
658 }
659
660 enum obj_reloc
661 arch_apply_relocation(struct obj_file *f,
662                                           struct obj_section *targsec,
663                                           struct obj_section *symsec,
664                                           struct obj_symbol *sym,
665 #if defined(__sh__)
666                                           Elf32_Rela * rel, Elf32_Addr v)
667 #else
668                                           Elf32_Rel * rel, Elf32_Addr v)
669 #endif
670 {
671         struct arch_file *ifile = (struct arch_file *) f;
672         struct arch_symbol *isym = (struct arch_symbol *) sym;
673
674         Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset);
675         Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
676         Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0;
677
678         enum obj_reloc ret = obj_reloc_ok;
679
680         switch (ELF32_R_TYPE(rel->r_info)) {
681
682 /* even though these constants seem to be the same for
683    the i386 and the sh, we "#if define" them for clarity
684    and in case that ever changes */
685 #if defined(__sh__)
686         case R_SH_NONE:
687 #else
688         case R_386_NONE:
689 #endif
690                 break;
691
692 #if defined(__sh__)
693         case R_SH_DIR32:
694 #else
695         case R_386_32:
696 #endif
697                 *loc += v;
698                 break;
699
700 #if defined(__sh__)
701         case R_SH_REL32:
702 #else
703         case R_386_PLT32:
704         case R_386_PC32:
705 #endif
706                 *loc += v - dot;
707                 break;
708
709 #if defined(__sh__)
710         case R_SH_PLT32:
711                 *loc = v - dot;
712                 break;
713 #endif
714
715
716 #if defined(__sh__)
717         case R_SH_GLOB_DAT:
718         case R_SH_JMP_SLOT:
719                 *loc = v;
720                 break;
721 #else
722         case R_386_GLOB_DAT:
723         case R_386_JMP_SLOT:
724                 *loc = v;
725                 break;
726 #endif
727
728 #if defined(__sh__)
729         case R_SH_RELATIVE:
730                 *loc += f->baseaddr + rel->r_addend;
731                 break;
732 #else
733         case R_386_RELATIVE:
734                 *loc += f->baseaddr;
735                 break;
736 #endif
737
738 #if defined(__sh__)
739         case R_SH_GOTPC:
740                 assert(got != 0);
741                 *loc += got - dot + rel->r_addend;;
742                 break;
743 #else
744         case R_386_GOTPC:
745                 assert(got != 0);
746                 *loc += got - dot;
747                 break;
748 #endif
749
750 #if defined(__sh__)
751         case R_SH_GOT32:
752                 assert(isym != NULL);
753                 if (!isym->gotent.reloc_done) {
754                         isym->gotent.reloc_done = 1;
755                         *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
756                                 v;
757                 }
758                 *loc += isym->gotent.offset + rel->r_addend;
759                 break;
760 #else
761         case R_386_GOT32:
762                 assert(isym != NULL);
763                 if (!isym->gotent.reloc_done) {
764                         isym->gotent.reloc_done = 1;
765                         *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
766                                 v;
767                 }
768                 *loc += isym->gotent.offset;
769                 break;
770 #endif
771
772 #if defined(__sh__)
773         case R_SH_GOTOFF:
774 #else
775         case R_386_GOTOFF:
776 #endif
777                 assert(got != 0);
778                 *loc += v - got;
779                 break;
780
781         default:
782                 ret = obj_reloc_unhandled;
783                 break;
784         }
785
786         return ret;
787 }
788
789 int arch_create_got(struct obj_file *f)
790 {
791         struct arch_file *ifile = (struct arch_file *) f;
792         int i, n, offset = 0, gotneeded = 0;
793
794         n = ifile->root.header.e_shnum;
795         for (i = 0; i < n; ++i) {
796                 struct obj_section *relsec, *symsec, *strsec;
797 #if defined(__sh__)
798                 Elf32_Rela *rel, *relend;
799 #else
800                 Elf32_Rel *rel, *relend;
801 #endif
802                 Elf32_Sym *symtab;
803                 const char *strtab;
804
805                 relsec = ifile->root.sections[i];
806                 if (relsec->header.sh_type != SHT_REL)
807                         continue;
808
809                 symsec = ifile->root.sections[relsec->header.sh_link];
810                 strsec = ifile->root.sections[symsec->header.sh_link];
811
812
813 #if defined(__sh__)
814                 rel = (Elf32_Rela *) relsec->contents;
815                 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela));
816 #else
817                 rel = (Elf32_Rel *) relsec->contents;
818                 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
819 #endif
820                 symtab = (Elf32_Sym *) symsec->contents;
821                 strtab = (const char *) strsec->contents;
822
823                 for (; rel < relend; ++rel) {
824                         Elf32_Sym *extsym;
825                         struct arch_symbol *intsym;
826                         const char *name;
827
828                         switch (ELF32_R_TYPE(rel->r_info)) {
829 #if defined(__sh__)
830                         case R_SH_GOTPC:
831                         case R_SH_GOTOFF:
832 #else
833                         case R_386_GOTPC:
834                         case R_386_GOTOFF:
835 #endif
836                                 gotneeded = 1;
837                         default:
838                                 continue;
839
840 #if defined(__sh__)
841                         case R_SH_GOT32:
842 #else
843                         case R_386_GOT32:
844 #endif
845                                 break;
846                         }
847
848                         extsym = &symtab[ELF32_R_SYM(rel->r_info)];
849                         if (extsym->st_name)
850                                 name = strtab + extsym->st_name;
851                         else
852                                 name = f->sections[extsym->st_shndx]->name;
853                         intsym =
854                                 (struct arch_symbol *) obj_find_symbol(&ifile->root, name);
855
856                         if (!intsym->gotent.offset_done) {
857                                 intsym->gotent.offset_done = 1;
858                                 intsym->gotent.offset = offset;
859                                 offset += 4;
860                         }
861                 }
862         }
863
864         if (offset > 0 || gotneeded)
865                 ifile->got =
866                         obj_create_alloced_section(&ifile->root, ".got", 4, offset);
867
868         return 1;
869 }
870
871 int arch_init_module(struct obj_file *f, struct new_module *mod)
872 {
873         return 1;
874 }
875
876
877 /*======================================================================*/
878
879 /* Standard ELF hash function.  */
880 inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
881 {
882         unsigned long h = 0;
883         unsigned long g;
884         unsigned char ch;
885
886         while (n > 0) {
887                 ch = *name++;
888                 h = (h << 4) + ch;
889                 if ((g = (h & 0xf0000000)) != 0) {
890                         h ^= g >> 24;
891                         h &= ~g;
892                 }
893                 n--;
894         }
895         return h;
896 }
897
898 unsigned long obj_elf_hash(const char *name)
899 {
900         return obj_elf_hash_n(name, strlen(name));
901 }
902
903 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
904 /* Get the kernel version in the canonical integer form.  */
905
906 static int get_kernel_version(char str[STRVERSIONLEN])
907 {
908         struct utsname uts_info;
909         char *p, *q;
910         int a, b, c;
911
912         if (uname(&uts_info) < 0)
913                 return -1;
914         strncpy(str, uts_info.release, STRVERSIONLEN);
915         p = uts_info.release;
916
917         a = strtoul(p, &p, 10);
918         if (*p != '.')
919                 return -1;
920         b = strtoul(p + 1, &p, 10);
921         if (*p != '.')
922                 return -1;
923         c = strtoul(p + 1, &q, 10);
924         if (p + 1 == q)
925                 return -1;
926
927         return a << 16 | b << 8 | c;
928 }
929
930 /* String comparison for non-co-versioned kernel and module.  */
931
932 static int ncv_strcmp(const char *a, const char *b)
933 {
934         size_t alen = strlen(a), blen = strlen(b);
935
936         if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
937                 return strncmp(a, b, alen);
938         else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
939                 return strncmp(a, b, blen);
940         else
941                 return strcmp(a, b);
942 }
943
944 /* String hashing for non-co-versioned kernel and module.  Here
945    we are simply forced to drop the crc from the hash.  */
946
947 static unsigned long ncv_symbol_hash(const char *str)
948 {
949         size_t len = strlen(str);
950         if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
951                 len -= 10;
952         return obj_elf_hash_n(str, len);
953 }
954
955 void
956 obj_set_symbol_compare(struct obj_file *f,
957                                            int (*cmp) (const char *, const char *),
958                                            unsigned long (*hash) (const char *))
959 {
960         if (cmp)
961                 f->symbol_cmp = cmp;
962         if (hash) {
963                 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
964                 int i;
965
966                 f->symbol_hash = hash;
967
968                 memcpy(tmptab, f->symtab, sizeof(tmptab));
969                 memset(f->symtab, 0, sizeof(f->symtab));
970
971                 for (i = 0; i < HASH_BUCKETS; ++i)
972                         for (sym = tmptab[i]; sym; sym = next) {
973                                 unsigned long h = hash(sym->name) % HASH_BUCKETS;
974                                 next = sym->next;
975                                 sym->next = f->symtab[h];
976                                 f->symtab[h] = sym;
977                         }
978         }
979 }
980
981 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
982
983
984 struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
985                                                                   unsigned long symidx, int info,
986                                                                   int secidx, ElfW(Addr) value,
987                                                                   unsigned long size)
988 {
989         struct obj_symbol *sym;
990         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
991         int n_type = ELFW(ST_TYPE) (info);
992         int n_binding = ELFW(ST_BIND) (info);
993
994         for (sym = f->symtab[hash]; sym; sym = sym->next)
995                 if (f->symbol_cmp(sym->name, name) == 0) {
996                         int o_secidx = sym->secidx;
997                         int o_info = sym->info;
998                         int o_type = ELFW(ST_TYPE) (o_info);
999                         int o_binding = ELFW(ST_BIND) (o_info);
1000
1001                         /* A redefinition!  Is it legal?  */
1002
1003                         if (secidx == SHN_UNDEF)
1004                                 return sym;
1005                         else if (o_secidx == SHN_UNDEF)
1006                                 goto found;
1007                         else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1008                                 /* Cope with local and global symbols of the same name
1009                                    in the same object file, as might have been created
1010                                    by ld -r.  The only reason locals are now seen at this
1011                                    level at all is so that we can do semi-sensible things
1012                                    with parameters.  */
1013
1014                                 struct obj_symbol *nsym, **p;
1015
1016                                 nsym = arch_new_symbol();
1017                                 nsym->next = sym->next;
1018                                 nsym->ksymidx = -1;
1019
1020                                 /* Excise the old (local) symbol from the hash chain.  */
1021                                 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1022                                         continue;
1023                                 *p = sym = nsym;
1024                                 goto found;
1025                         } else if (n_binding == STB_LOCAL) {
1026                                 /* Another symbol of the same name has already been defined.
1027                                    Just add this to the local table.  */
1028                                 sym = arch_new_symbol();
1029                                 sym->next = NULL;
1030                                 sym->ksymidx = -1;
1031                                 f->local_symtab[symidx] = sym;
1032                                 goto found;
1033                         } else if (n_binding == STB_WEAK)
1034                                 return sym;
1035                         else if (o_binding == STB_WEAK)
1036                                 goto found;
1037                         /* Don't unify COMMON symbols with object types the programmer
1038                            doesn't expect.  */
1039                         else if (secidx == SHN_COMMON
1040                                          && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1041                                 return sym;
1042                         else if (o_secidx == SHN_COMMON
1043                                          && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1044                                 goto found;
1045                         else {
1046                                 /* Don't report an error if the symbol is coming from
1047                                    the kernel or some external module.  */
1048                                 if (secidx <= SHN_HIRESERVE)
1049                                         errorMsg("%s multiply defined\n", name);
1050                                 return sym;
1051                         }
1052                 }
1053
1054         /* Completely new symbol.  */
1055         sym = arch_new_symbol();
1056         sym->next = f->symtab[hash];
1057         f->symtab[hash] = sym;
1058         sym->ksymidx = -1;
1059
1060         if (ELFW(ST_BIND) (info) == STB_LOCAL)
1061                 f->local_symtab[symidx] = sym;
1062
1063   found:
1064         sym->name = name;
1065         sym->value = value;
1066         sym->size = size;
1067         sym->secidx = secidx;
1068         sym->info = info;
1069
1070         return sym;
1071 }
1072
1073 struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
1074 {
1075         struct obj_symbol *sym;
1076         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1077
1078         for (sym = f->symtab[hash]; sym; sym = sym->next)
1079                 if (f->symbol_cmp(sym->name, name) == 0)
1080                         return sym;
1081
1082         return NULL;
1083 }
1084
1085 ElfW(Addr)
1086         obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1087 {
1088         if (sym) {
1089                 if (sym->secidx >= SHN_LORESERVE)
1090                         return sym->value;
1091
1092                 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1093         } else {
1094                 /* As a special case, a NULL sym has value zero.  */
1095                 return 0;
1096         }
1097 }
1098
1099 struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1100 {
1101         int i, n = f->header.e_shnum;
1102
1103         for (i = 0; i < n; ++i)
1104                 if (strcmp(f->sections[i]->name, name) == 0)
1105                         return f->sections[i];
1106
1107         return NULL;
1108 }
1109
1110 static int obj_load_order_prio(struct obj_section *a)
1111 {
1112         unsigned long af, ac;
1113
1114         af = a->header.sh_flags;
1115
1116         ac = 0;
1117         if (a->name[0] != '.' || strlen(a->name) != 10 ||
1118                 strcmp(a->name + 5, ".init"))
1119                 ac |= 32;
1120         if (af & SHF_ALLOC)
1121                 ac |= 16;
1122         if (!(af & SHF_WRITE))
1123                 ac |= 8;
1124         if (af & SHF_EXECINSTR)
1125                 ac |= 4;
1126         if (a->header.sh_type != SHT_NOBITS)
1127                 ac |= 2;
1128
1129         return ac;
1130 }
1131
1132 void
1133 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1134 {
1135         struct obj_section **p;
1136         int prio = obj_load_order_prio(sec);
1137         for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1138                 if (obj_load_order_prio(*p) < prio)
1139                         break;
1140         sec->load_next = *p;
1141         *p = sec;
1142 }
1143
1144 struct obj_section *obj_create_alloced_section(struct obj_file *f,
1145                                                                                            const char *name,
1146                                                                                            unsigned long align,
1147                                                                                            unsigned long size)
1148 {
1149         int newidx = f->header.e_shnum++;
1150         struct obj_section *sec;
1151
1152         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1153         f->sections[newidx] = sec = arch_new_section();
1154
1155         memset(sec, 0, sizeof(*sec));
1156         sec->header.sh_type = SHT_PROGBITS;
1157         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1158         sec->header.sh_size = size;
1159         sec->header.sh_addralign = align;
1160         sec->name = name;
1161         sec->idx = newidx;
1162         if (size)
1163                 sec->contents = xmalloc(size);
1164
1165         obj_insert_section_load_order(f, sec);
1166
1167         return sec;
1168 }
1169
1170 struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1171                                                                                                          const char *name,
1172                                                                                                          unsigned long align,
1173                                                                                                          unsigned long size)
1174 {
1175         int newidx = f->header.e_shnum++;
1176         struct obj_section *sec;
1177
1178         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1179         f->sections[newidx] = sec = arch_new_section();
1180
1181         memset(sec, 0, sizeof(*sec));
1182         sec->header.sh_type = SHT_PROGBITS;
1183         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1184         sec->header.sh_size = size;
1185         sec->header.sh_addralign = align;
1186         sec->name = name;
1187         sec->idx = newidx;
1188         if (size)
1189                 sec->contents = xmalloc(size);
1190
1191         sec->load_next = f->load_order;
1192         f->load_order = sec;
1193         if (f->load_order_search_start == &f->load_order)
1194                 f->load_order_search_start = &sec->load_next;
1195
1196         return sec;
1197 }
1198
1199 void *obj_extend_section(struct obj_section *sec, unsigned long more)
1200 {
1201         unsigned long oldsize = sec->header.sh_size;
1202         sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1203         return sec->contents + oldsize;
1204 }
1205
1206
1207
1208 /* Conditionally add the symbols from the given symbol set to the
1209    new module.  */
1210
1211 static int
1212 add_symbols_from(
1213                                  struct obj_file *f,
1214                                  int idx, struct new_module_symbol *syms, size_t nsyms)
1215 {
1216         struct new_module_symbol *s;
1217         size_t i;
1218         int used = 0;
1219
1220         for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1221
1222                 /* Only add symbols that are already marked external.  If we
1223                    override locals we may cause problems for argument initialization.
1224                    We will also create a false dependency on the module.  */
1225                 struct obj_symbol *sym;
1226
1227                 sym = obj_find_symbol(f, (char *) s->name);
1228                 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1229                         sym = obj_add_symbol(f, (char *) s->name, -1,
1230                                                                  ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1231                                                                  idx, s->value, 0);
1232                         /* Did our symbol just get installed?  If so, mark the
1233                            module as "used".  */
1234                         if (sym->secidx == idx)
1235                                 used = 1;
1236                 }
1237         }
1238
1239         return used;
1240 }
1241
1242 static void add_kernel_symbols(struct obj_file *f)
1243 {
1244         struct external_module *m;
1245         int i, nused = 0;
1246
1247         /* Add module symbols first.  */
1248
1249         for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1250                 if (m->nsyms
1251                         && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1252                                                                 m->nsyms)) m->used = 1, ++nused;
1253
1254         n_ext_modules_used = nused;
1255
1256         /* And finally the symbols from the kernel proper.  */
1257
1258         if (nksyms)
1259                 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1260 }
1261
1262 static char *get_modinfo_value(struct obj_file *f, const char *key)
1263 {
1264         struct obj_section *sec;
1265         char *p, *v, *n, *ep;
1266         size_t klen = strlen(key);
1267
1268         sec = obj_find_section(f, ".modinfo");
1269         if (sec == NULL)
1270                 return NULL;
1271         p = sec->contents;
1272         ep = p + sec->header.sh_size;
1273         while (p < ep) {
1274                 v = strchr(p, '=');
1275                 n = strchr(p, '\0');
1276                 if (v) {
1277                         if (p + klen == v && strncmp(p, key, klen) == 0)
1278                                 return v + 1;
1279                 } else {
1280                         if (p + klen == n && strcmp(p, key) == 0)
1281                                 return n;
1282                 }
1283                 p = n + 1;
1284         }
1285
1286         return NULL;
1287 }
1288
1289
1290 /*======================================================================*/
1291 /* Functions relating to module loading in pre 2.1 kernels.  */
1292
1293 static int
1294 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1295 {
1296         while (argc > 0) {
1297                 char *p, *q;
1298                 struct obj_symbol *sym;
1299                 int *loc;
1300
1301                 p = *argv;
1302                 if ((q = strchr(p, '=')) == NULL) {
1303                         argc--;
1304                         continue;
1305                 }
1306                 *q++ = '\0';
1307
1308                 sym = obj_find_symbol(f, p);
1309
1310                 /* Also check that the parameter was not resolved from the kernel.  */
1311                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1312                         errorMsg("symbol for parameter %s not found\n", p);
1313                         return 0;
1314                 }
1315
1316                 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1317
1318                 /* Do C quoting if we begin with a ".  */
1319                 if (*q == '"') {
1320                         char *r, *str;
1321
1322                         str = alloca(strlen(q));
1323                         for (r = str, q++; *q != '"'; ++q, ++r) {
1324                                 if (*q == '\0') {
1325                                         errorMsg("improperly terminated string argument for %s\n", p);
1326                                         return 0;
1327                                 } else if (*q == '\\')
1328                                         switch (*++q) {
1329                                         case 'a':
1330                                                 *r = '\a';
1331                                                 break;
1332                                         case 'b':
1333                                                 *r = '\b';
1334                                                 break;
1335                                         case 'e':
1336                                                 *r = '\033';
1337                                                 break;
1338                                         case 'f':
1339                                                 *r = '\f';
1340                                                 break;
1341                                         case 'n':
1342                                                 *r = '\n';
1343                                                 break;
1344                                         case 'r':
1345                                                 *r = '\r';
1346                                                 break;
1347                                         case 't':
1348                                                 *r = '\t';
1349                                                 break;
1350
1351                                         case '0':
1352                                         case '1':
1353                                         case '2':
1354                                         case '3':
1355                                         case '4':
1356                                         case '5':
1357                                         case '6':
1358                                         case '7':
1359                                                 {
1360                                                         int c = *q - '0';
1361                                                         if (q[1] >= '0' && q[1] <= '7') {
1362                                                                 c = (c * 8) + *++q - '0';
1363                                                                 if (q[1] >= '0' && q[1] <= '7')
1364                                                                         c = (c * 8) + *++q - '0';
1365                                                         }
1366                                                         *r = c;
1367                                                 }
1368                                                 break;
1369
1370                                         default:
1371                                                 *r = *q;
1372                                                 break;
1373                                 } else
1374                                         *r = *q;
1375                         }
1376                         *r = '\0';
1377                         obj_string_patch(f, sym->secidx, sym->value, str);
1378                 } else if (*q >= '0' && *q <= '9') {
1379                         do
1380                                 *loc++ = strtoul(q, &q, 0);
1381                         while (*q++ == ',');
1382                 } else {
1383                         char *contents = f->sections[sym->secidx]->contents;
1384                         char *loc = contents + sym->value;
1385                         char *r;                        /* To search for commas */
1386
1387                         /* Break the string with comas */
1388                         while ((r = strchr(q, ',')) != (char *) NULL) {
1389                                 *r++ = '\0';
1390                                 obj_string_patch(f, sym->secidx, loc - contents, q);
1391                                 loc += sizeof(char *);
1392                                 q = r;
1393                         }
1394
1395                         /* last part */
1396                         obj_string_patch(f, sym->secidx, loc - contents, q);
1397                 }
1398
1399                 argc--, argv++;
1400         }
1401
1402         return 1;
1403 }
1404
1405 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1406 static int old_is_module_checksummed(struct obj_file *f)
1407 {
1408         return obj_find_symbol(f, "Using_Versions") != NULL;
1409 }
1410 /* Get the module's kernel version in the canonical integer form.  */
1411
1412 static int
1413 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1414 {
1415         struct obj_symbol *sym;
1416         char *p, *q;
1417         int a, b, c;
1418
1419         sym = obj_find_symbol(f, "kernel_version");
1420         if (sym == NULL)
1421                 return -1;
1422
1423         p = f->sections[sym->secidx]->contents + sym->value;
1424         strncpy(str, p, STRVERSIONLEN);
1425
1426         a = strtoul(p, &p, 10);
1427         if (*p != '.')
1428                 return -1;
1429         b = strtoul(p + 1, &p, 10);
1430         if (*p != '.')
1431                 return -1;
1432         c = strtoul(p + 1, &q, 10);
1433         if (p + 1 == q)
1434                 return -1;
1435
1436         return a << 16 | b << 8 | c;
1437 }
1438
1439 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1440
1441 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
1442
1443 /* Fetch all the symbols and divvy them up as appropriate for the modules.  */
1444
1445 static int old_get_kernel_symbols(const char *m_name)
1446 {
1447         struct old_kernel_sym *ks, *k;
1448         struct new_module_symbol *s;
1449         struct external_module *mod;
1450         int nks, nms, nmod, i;
1451
1452         nks = get_kernel_syms(NULL);
1453         if (nks < 0) {
1454                 errorMsg("get_kernel_syms: %s: %s", m_name, strerror(errno));
1455                 return 0;
1456         }
1457
1458         ks = k = xmalloc(nks * sizeof(*ks));
1459
1460         if (get_kernel_syms(ks) != nks) {
1461                 perror("inconsistency with get_kernel_syms -- is someone else "
1462                            "playing with modules?");
1463                 free(ks);
1464                 return 0;
1465         }
1466
1467         /* Collect the module information.  */
1468
1469         mod = NULL;
1470         nmod = -1;
1471
1472         while (k->name[0] == '#' && k->name[1]) {
1473                 struct old_kernel_sym *k2;
1474                 struct new_module_symbol *s;
1475
1476                 /* Find out how many symbols this module has.  */
1477                 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1478                         continue;
1479                 nms = k2 - k - 1;
1480
1481                 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1482                 mod[nmod].name = k->name + 1;
1483                 mod[nmod].addr = k->value;
1484                 mod[nmod].used = 0;
1485                 mod[nmod].nsyms = nms;
1486                 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1487
1488                 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1489                         s->name = (unsigned long) k->name;
1490                         s->value = k->value;
1491                 }
1492
1493                 k = k2;
1494         }
1495
1496         ext_modules = mod;
1497         n_ext_modules = nmod + 1;
1498
1499         /* Now collect the symbols for the kernel proper.  */
1500
1501         if (k->name[0] == '#')
1502                 ++k;
1503
1504         nksyms = nms = nks - (k - ks);
1505         ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1506
1507         for (i = 0; i < nms; ++i, ++s, ++k) {
1508                 s->name = (unsigned long) k->name;
1509                 s->value = k->value;
1510         }
1511
1512         return 1;
1513 }
1514
1515 /* Return the kernel symbol checksum version, or zero if not used.  */
1516
1517 static int old_is_kernel_checksummed(void)
1518 {
1519         /* Using_Versions is the first symbol.  */
1520         if (nksyms > 0
1521                 && strcmp((char *) ksyms[0].name,
1522                                   "Using_Versions") == 0) return ksyms[0].value;
1523         else
1524                 return 0;
1525 }
1526
1527
1528 static int old_create_mod_use_count(struct obj_file *f)
1529 {
1530         struct obj_section *sec;
1531
1532         sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1533                                                                                    sizeof(long));
1534
1535         obj_add_symbol(f, "mod_use_count_", -1,
1536                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1537                                    sizeof(long));
1538
1539         return 1;
1540 }
1541
1542 static int
1543 old_init_module(const char *m_name, struct obj_file *f,
1544                                 unsigned long m_size)
1545 {
1546         char *image;
1547         struct old_mod_routines routines;
1548         struct old_symbol_table *symtab;
1549         int ret;
1550
1551         /* Create the symbol table */
1552         {
1553                 int nsyms = 0, strsize = 0, total;
1554
1555                 /* Size things first... */
1556                 if (flag_export) {
1557                         int i;
1558                         for (i = 0; i < HASH_BUCKETS; ++i) {
1559                                 struct obj_symbol *sym;
1560                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1561                                         if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1562                                                 && sym->secidx <= SHN_HIRESERVE) 
1563                                         {
1564                                                 sym->ksymidx = nsyms++;
1565                                                 strsize += strlen(sym->name) + 1;
1566                                         }
1567                         }
1568                 }
1569
1570                 total = (sizeof(struct old_symbol_table)
1571                                  + nsyms * sizeof(struct old_module_symbol)
1572                                  + n_ext_modules_used * sizeof(struct old_module_ref)
1573                                  + strsize);
1574                 symtab = xmalloc(total);
1575                 symtab->size = total;
1576                 symtab->n_symbols = nsyms;
1577                 symtab->n_refs = n_ext_modules_used;
1578
1579                 if (flag_export && nsyms) {
1580                         struct old_module_symbol *ksym;
1581                         char *str;
1582                         int i;
1583
1584                         ksym = symtab->symbol;
1585                         str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1586                                    + n_ext_modules_used * sizeof(struct old_module_ref));
1587
1588                         for (i = 0; i < HASH_BUCKETS; ++i) {
1589                                 struct obj_symbol *sym;
1590                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1591                                         if (sym->ksymidx >= 0) {
1592                                                 ksym->addr = obj_symbol_final_value(f, sym);
1593                                                 ksym->name =
1594                                                         (unsigned long) str - (unsigned long) symtab;
1595
1596                                                 str = stpcpy(str, sym->name) + 1;
1597                                                 ksym++;
1598                                         }
1599                         }
1600                 }
1601
1602                 if (n_ext_modules_used) {
1603                         struct old_module_ref *ref;
1604                         int i;
1605
1606                         ref = (struct old_module_ref *)
1607                                 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1608
1609                         for (i = 0; i < n_ext_modules; ++i)
1610                                 if (ext_modules[i].used)
1611                                         ref++->module = ext_modules[i].addr;
1612                 }
1613         }
1614
1615         /* Fill in routines.  */
1616
1617         routines.init =
1618                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1619         routines.cleanup =
1620                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1621
1622         /* Whew!  All of the initialization is complete.  Collect the final
1623            module image and give it to the kernel.  */
1624
1625         image = xmalloc(m_size);
1626         obj_create_image(f, image);
1627
1628         /* image holds the complete relocated module, accounting correctly for
1629            mod_use_count.  However the old module kernel support assume that
1630            it is receiving something which does not contain mod_use_count.  */
1631         ret = old_sys_init_module(m_name, image + sizeof(long),
1632                                                           m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1633                                                                                 : 0), &routines, symtab);
1634         if (ret)
1635                 errorMsg("init_module: %s: %s", m_name, strerror(errno));
1636
1637         free(image);
1638         free(symtab);
1639
1640         return ret == 0;
1641 }
1642
1643 #else
1644
1645 #define old_create_mod_use_count(x) TRUE
1646 #define old_init_module(x, y, z) TRUE
1647
1648 #endif                                                  /* BB_FEATURE_INSMOD_OLD_KERNEL */
1649
1650
1651
1652 /*======================================================================*/
1653 /* Functions relating to module loading after 2.1.18.  */
1654
1655 static int
1656 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1657 {
1658         while (argc > 0) {
1659                 char *p, *q, *key;
1660                 struct obj_symbol *sym;
1661                 char *contents, *loc;
1662                 int min, max, n;
1663
1664                 p = *argv;
1665                 if ((q = strchr(p, '=')) == NULL) {
1666                         argc--;
1667                         continue;
1668                 }
1669
1670                 key = alloca(q - p + 6);
1671                 memcpy(key, "parm_", 5);
1672                 memcpy(key + 5, p, q - p);
1673                 key[q - p + 5] = 0;
1674
1675                 p = get_modinfo_value(f, key);
1676                 key += 5;
1677                 if (p == NULL) {
1678                         errorMsg("invalid parameter %s\n", key);
1679                         return 0;
1680                 }
1681
1682                 sym = obj_find_symbol(f, key);
1683
1684                 /* Also check that the parameter was not resolved from the kernel.  */
1685                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1686                         errorMsg("symbol for parameter %s not found\n", key);
1687                         return 0;
1688                 }
1689
1690                 if (isdigit(*p)) {
1691                         min = strtoul(p, &p, 10);
1692                         if (*p == '-')
1693                                 max = strtoul(p + 1, &p, 10);
1694                         else
1695                                 max = min;
1696                 } else
1697                         min = max = 1;
1698
1699                 contents = f->sections[sym->secidx]->contents;
1700                 loc = contents + sym->value;
1701                 n = (*++q != '\0');
1702
1703                 while (1) {
1704                         if ((*p == 's') || (*p == 'c')) {
1705                                 char *str;
1706
1707                                 /* Do C quoting if we begin with a ", else slurp the lot.  */
1708                                 if (*q == '"') {
1709                                         char *r;
1710
1711                                         str = alloca(strlen(q));
1712                                         for (r = str, q++; *q != '"'; ++q, ++r) {
1713                                                 if (*q == '\0') {
1714                                                         errorMsg("improperly terminated string argument for %s\n",
1715                                                                         key);
1716                                                         return 0;
1717                                                 } else if (*q == '\\')
1718                                                         switch (*++q) {
1719                                                         case 'a':
1720                                                                 *r = '\a';
1721                                                                 break;
1722                                                         case 'b':
1723                                                                 *r = '\b';
1724                                                                 break;
1725                                                         case 'e':
1726                                                                 *r = '\033';
1727                                                                 break;
1728                                                         case 'f':
1729                                                                 *r = '\f';
1730                                                                 break;
1731                                                         case 'n':
1732                                                                 *r = '\n';
1733                                                                 break;
1734                                                         case 'r':
1735                                                                 *r = '\r';
1736                                                                 break;
1737                                                         case 't':
1738                                                                 *r = '\t';
1739                                                                 break;
1740
1741                                                         case '0':
1742                                                         case '1':
1743                                                         case '2':
1744                                                         case '3':
1745                                                         case '4':
1746                                                         case '5':
1747                                                         case '6':
1748                                                         case '7':
1749                                                                 {
1750                                                                         int c = *q - '0';
1751                                                                         if (q[1] >= '0' && q[1] <= '7') {
1752                                                                                 c = (c * 8) + *++q - '0';
1753                                                                                 if (q[1] >= '0' && q[1] <= '7')
1754                                                                                         c = (c * 8) + *++q - '0';
1755                                                                         }
1756                                                                         *r = c;
1757                                                                 }
1758                                                                 break;
1759
1760                                                         default:
1761                                                                 *r = *q;
1762                                                                 break;
1763                                                 } else
1764                                                         *r = *q;
1765                                         }
1766                                         *r = '\0';
1767                                         ++q;
1768                                 } else {
1769                                         char *r;
1770
1771                                         /* In this case, the string is not quoted. We will break
1772                                            it using the coma (like for ints). If the user wants to
1773                                            include comas in a string, he just has to quote it */
1774
1775                                         /* Search the next coma */
1776                                         r = strchr(q, ',');
1777
1778                                         /* Found ? */
1779                                         if (r != (char *) NULL) {
1780                                                 /* Recopy the current field */
1781                                                 str = alloca(r - q + 1);
1782                                                 memcpy(str, q, r - q);
1783
1784                                                 /* I don't know if it is usefull, as the previous case
1785                                                    doesn't null terminate the string ??? */
1786                                                 str[r - q] = '\0';
1787
1788                                                 /* Keep next fields */
1789                                                 q = r;
1790                                         } else {
1791                                                 /* last string */
1792                                                 str = q;
1793                                                 q = "";
1794                                         }
1795                                 }
1796
1797                                 if (*p == 's') {
1798                                         /* Normal string */
1799                                         obj_string_patch(f, sym->secidx, loc - contents, str);
1800                                         loc += tgt_sizeof_char_p;
1801                                 } else {
1802                                         /* Array of chars (in fact, matrix !) */
1803                                         unsigned long charssize;        /* size of each member */
1804
1805                                         /* Get the size of each member */
1806                                         /* Probably we should do that outside the loop ? */
1807                                         if (!isdigit(*(p + 1))) {
1808                                                 errorMsg("parameter type 'c' for %s must be followed by"
1809                                                                 " the maximum size\n", key);
1810                                                 return 0;
1811                                         }
1812                                         charssize = strtoul(p + 1, (char **) NULL, 10);
1813
1814                                         /* Check length */
1815                                         if (strlen(str) >= charssize) {
1816                                                 errorMsg("string too long for %s (max %ld)\n", key,
1817                                                                 charssize - 1);
1818                                                 return 0;
1819                                         }
1820
1821                                         /* Copy to location */
1822                                         strcpy((char *) loc, str);
1823                                         loc += charssize;
1824                                 }
1825                         } else {
1826                                 long v = strtoul(q, &q, 0);
1827                                 switch (*p) {
1828                                 case 'b':
1829                                         *loc++ = v;
1830                                         break;
1831                                 case 'h':
1832                                         *(short *) loc = v;
1833                                         loc += tgt_sizeof_short;
1834                                         break;
1835                                 case 'i':
1836                                         *(int *) loc = v;
1837                                         loc += tgt_sizeof_int;
1838                                         break;
1839                                 case 'l':
1840                                         *(long *) loc = v;
1841                                         loc += tgt_sizeof_long;
1842                                         break;
1843
1844                                 default:
1845                                         errorMsg("unknown parameter type '%c' for %s\n", *p, key);
1846                                         return 0;
1847                                 }
1848                         }
1849
1850                   retry_end_of_value:
1851                         switch (*q) {
1852                         case '\0':
1853                                 goto end_of_arg;
1854
1855                         case ' ':
1856                         case '\t':
1857                         case '\n':
1858                         case '\r':
1859                                 ++q;
1860                                 goto retry_end_of_value;
1861
1862                         case ',':
1863                                 if (++n > max) {
1864                                         errorMsg("too many values for %s (max %d)\n", key, max);
1865                                         return 0;
1866                                 }
1867                                 ++q;
1868                                 break;
1869
1870                         default:
1871                                 errorMsg("invalid argument syntax for %s\n", key);
1872                                 return 0;
1873                         }
1874                 }
1875
1876           end_of_arg:
1877                 if (n < min) {
1878                         errorMsg("too few values for %s (min %d)\n", key, min);
1879                         return 0;
1880                 }
1881
1882                 argc--, argv++;
1883         }
1884
1885         return 1;
1886 }
1887
1888 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1889 static int new_is_module_checksummed(struct obj_file *f)
1890 {
1891         const char *p = get_modinfo_value(f, "using_checksums");
1892         if (p)
1893                 return atoi(p);
1894         else
1895                 return 0;
1896 }
1897
1898 /* Get the module's kernel version in the canonical integer form.  */
1899
1900 static int
1901 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1902 {
1903         char *p, *q;
1904         int a, b, c;
1905
1906         p = get_modinfo_value(f, "kernel_version");
1907         if (p == NULL)
1908                 return -1;
1909         strncpy(str, p, STRVERSIONLEN);
1910
1911         a = strtoul(p, &p, 10);
1912         if (*p != '.')
1913                 return -1;
1914         b = strtoul(p + 1, &p, 10);
1915         if (*p != '.')
1916                 return -1;
1917         c = strtoul(p + 1, &q, 10);
1918         if (p + 1 == q)
1919                 return -1;
1920
1921         return a << 16 | b << 8 | c;
1922 }
1923
1924 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1925
1926
1927 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
1928
1929 /* Fetch the loaded modules, and all currently exported symbols.  */
1930
1931 static int new_get_kernel_symbols(void)
1932 {
1933         char *module_names, *mn;
1934         struct external_module *modules, *m;
1935         struct new_module_symbol *syms, *s;
1936         size_t ret, bufsize, nmod, nsyms, i, j;
1937
1938         /* Collect the loaded modules.  */
1939
1940         module_names = xmalloc(bufsize = 256);
1941   retry_modules_load:
1942         if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
1943                 if (errno == ENOSPC) {
1944                         module_names = xrealloc(module_names, bufsize = ret);
1945                         goto retry_modules_load;
1946                 }
1947                 errorMsg("QM_MODULES: %s", strerror(errno));
1948                 return 0;
1949         }
1950
1951         n_ext_modules = nmod = ret;
1952         ext_modules = modules = xmalloc(nmod * sizeof(*modules));
1953         memset(modules, 0, nmod * sizeof(*modules));
1954
1955         /* Collect the modules' symbols.  */
1956
1957         for (i = 0, mn = module_names, m = modules;
1958                  i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
1959                 struct new_module_info info;
1960
1961                 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
1962                         if (errno == ENOENT) {
1963                                 /* The module was removed out from underneath us.  */
1964                                 continue;
1965                         }
1966                         errorMsg("query_module: QM_INFO: %s: %s", mn, strerror(errno));
1967                         return 0;
1968                 }
1969
1970                 syms = xmalloc(bufsize = 1024);
1971           retry_mod_sym_load:
1972                 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
1973                         switch (errno) {
1974                         case ENOSPC:
1975                                 syms = xrealloc(syms, bufsize = ret);
1976                                 goto retry_mod_sym_load;
1977                         case ENOENT:
1978                                 /* The module was removed out from underneath us.  */
1979                                 continue;
1980                         default:
1981                                 errorMsg("query_module: QM_SYMBOLS: %s: %s", mn, strerror(errno));
1982                                 return 0;
1983                         }
1984                 }
1985                 nsyms = ret;
1986
1987                 m->name = mn;
1988                 m->addr = info.addr;
1989                 m->nsyms = nsyms;
1990                 m->syms = syms;
1991
1992                 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
1993                         s->name += (unsigned long) syms;
1994                 }
1995         }
1996
1997         /* Collect the kernel's symbols.  */
1998
1999         syms = xmalloc(bufsize = 16 * 1024);
2000   retry_kern_sym_load:
2001         if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2002                 if (errno == ENOSPC) {
2003                         syms = xrealloc(syms, bufsize = ret);
2004                         goto retry_kern_sym_load;
2005                 }
2006                 errorMsg("kernel: QM_SYMBOLS: %s", strerror(errno));
2007                 return 0;
2008         }
2009         nksyms = nsyms = ret;
2010         ksyms = syms;
2011
2012         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2013                 s->name += (unsigned long) syms;
2014         }
2015         return 1;
2016 }
2017
2018
2019 /* Return the kernel symbol checksum version, or zero if not used.  */
2020
2021 static int new_is_kernel_checksummed(void)
2022 {
2023         struct new_module_symbol *s;
2024         size_t i;
2025
2026         /* Using_Versions is not the first symbol, but it should be in there.  */
2027
2028         for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2029                 if (strcmp((char *) s->name, "Using_Versions") == 0)
2030                         return s->value;
2031
2032         return 0;
2033 }
2034
2035
2036 static int new_create_this_module(struct obj_file *f, const char *m_name)
2037 {
2038         struct obj_section *sec;
2039
2040         sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2041                                                                                    sizeof(struct new_module));
2042         memset(sec->contents, 0, sizeof(struct new_module));
2043
2044         obj_add_symbol(f, "__this_module", -1,
2045                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2046                                    sizeof(struct new_module));
2047
2048         obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2049                                          m_name);
2050
2051         return 1;
2052 }
2053
2054
2055 static int new_create_module_ksymtab(struct obj_file *f)
2056 {
2057         struct obj_section *sec;
2058         int i;
2059
2060         /* We must always add the module references.  */
2061
2062         if (n_ext_modules_used) {
2063                 struct new_module_ref *dep;
2064                 struct obj_symbol *tm;
2065
2066                 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2067                                                                                  (sizeof(struct new_module_ref)
2068                                                                                   * n_ext_modules_used));
2069                 if (!sec)
2070                         return 0;
2071
2072                 tm = obj_find_symbol(f, "__this_module");
2073                 dep = (struct new_module_ref *) sec->contents;
2074                 for (i = 0; i < n_ext_modules; ++i)
2075                         if (ext_modules[i].used) {
2076                                 dep->dep = ext_modules[i].addr;
2077                                 obj_symbol_patch(f, sec->idx,
2078                                                                  (char *) &dep->ref - sec->contents, tm);
2079                                 dep->next_ref = 0;
2080                                 ++dep;
2081                         }
2082         }
2083
2084         if (flag_export && !obj_find_section(f, "__ksymtab")) {
2085                 size_t nsyms;
2086                 int *loaded;
2087
2088                 sec =
2089                         obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2090                                                                            0);
2091
2092                 /* We don't want to export symbols residing in sections that
2093                    aren't loaded.  There are a number of these created so that
2094                    we make sure certain module options don't appear twice.  */
2095
2096                 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2097                 while (--i >= 0)
2098                         loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2099
2100                 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2101                         struct obj_symbol *sym;
2102                         for (sym = f->symtab[i]; sym; sym = sym->next)
2103                                 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2104                                         && sym->secidx <= SHN_HIRESERVE
2105                                         && (sym->secidx >= SHN_LORESERVE
2106                                                 || loaded[sym->secidx])) {
2107                                         ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2108
2109                                         obj_symbol_patch(f, sec->idx, ofs, sym);
2110                                         obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2111                                                                          sym->name);
2112
2113                                         nsyms++;
2114                                 }
2115                 }
2116
2117                 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2118         }
2119
2120         return 1;
2121 }
2122
2123
2124 static int
2125 new_init_module(const char *m_name, struct obj_file *f,
2126                                 unsigned long m_size)
2127 {
2128         struct new_module *module;
2129         struct obj_section *sec;
2130         void *image;
2131         int ret;
2132         tgt_long m_addr;
2133
2134         sec = obj_find_section(f, ".this");
2135         module = (struct new_module *) sec->contents;
2136         m_addr = sec->header.sh_addr;
2137
2138         module->size_of_struct = sizeof(*module);
2139         module->size = m_size;
2140         module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2141
2142         sec = obj_find_section(f, "__ksymtab");
2143         if (sec && sec->header.sh_size) {
2144                 module->syms = sec->header.sh_addr;
2145                 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2146         }
2147
2148         if (n_ext_modules_used) {
2149                 sec = obj_find_section(f, ".kmodtab");
2150                 module->deps = sec->header.sh_addr;
2151                 module->ndeps = n_ext_modules_used;
2152         }
2153
2154         module->init =
2155                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2156         module->cleanup =
2157                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2158
2159         sec = obj_find_section(f, "__ex_table");
2160         if (sec) {
2161                 module->ex_table_start = sec->header.sh_addr;
2162                 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2163         }
2164
2165         sec = obj_find_section(f, ".text.init");
2166         if (sec) {
2167                 module->runsize = sec->header.sh_addr - m_addr;
2168         }
2169         sec = obj_find_section(f, ".data.init");
2170         if (sec) {
2171                 if (!module->runsize ||
2172                         module->runsize > sec->header.sh_addr - m_addr)
2173                                 module->runsize = sec->header.sh_addr - m_addr;
2174         }
2175
2176         if (!arch_init_module(f, module))
2177                 return 0;
2178
2179         /* Whew!  All of the initialization is complete.  Collect the final
2180            module image and give it to the kernel.  */
2181
2182         image = xmalloc(m_size);
2183         obj_create_image(f, image);
2184
2185         ret = new_sys_init_module(m_name, (struct new_module *) image);
2186         if (ret)
2187                 errorMsg("init_module: %s: %s", m_name, strerror(errno));
2188
2189         free(image);
2190
2191         return ret == 0;
2192 }
2193
2194 #else
2195
2196 #define new_init_module(x, y, z) TRUE
2197 #define new_create_this_module(x, y) 0
2198 #define new_create_module_ksymtab(x)
2199
2200 #endif                                                  /* BB_FEATURE_INSMOD_OLD_KERNEL */
2201
2202
2203 /*======================================================================*/
2204
2205 int
2206 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2207                                  const char *string)
2208 {
2209         struct obj_string_patch *p;
2210         struct obj_section *strsec;
2211         size_t len = strlen(string) + 1;
2212         char *loc;
2213
2214         p = xmalloc(sizeof(*p));
2215         p->next = f->string_patches;
2216         p->reloc_secidx = secidx;
2217         p->reloc_offset = offset;
2218         f->string_patches = p;
2219
2220         strsec = obj_find_section(f, ".kstrtab");
2221         if (strsec == NULL) {
2222                 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2223                 p->string_offset = 0;
2224                 loc = strsec->contents;
2225         } else {
2226                 p->string_offset = strsec->header.sh_size;
2227                 loc = obj_extend_section(strsec, len);
2228         }
2229         memcpy(loc, string, len);
2230
2231         return 1;
2232 }
2233
2234 int
2235 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2236                                  struct obj_symbol *sym)
2237 {
2238         struct obj_symbol_patch *p;
2239
2240         p = xmalloc(sizeof(*p));
2241         p->next = f->symbol_patches;
2242         p->reloc_secidx = secidx;
2243         p->reloc_offset = offset;
2244         p->sym = sym;
2245         f->symbol_patches = p;
2246
2247         return 1;
2248 }
2249
2250 int obj_check_undefineds(struct obj_file *f)
2251 {
2252         unsigned long i;
2253         int ret = 1;
2254
2255         for (i = 0; i < HASH_BUCKETS; ++i) {
2256                 struct obj_symbol *sym;
2257                 for (sym = f->symtab[i]; sym; sym = sym->next)
2258                         if (sym->secidx == SHN_UNDEF) {
2259                                 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2260                                         sym->secidx = SHN_ABS;
2261                                         sym->value = 0;
2262                                 } else {
2263                                         errorMsg("unresolved symbol %s\n", sym->name);
2264                                         ret = 0;
2265                                 }
2266                         }
2267         }
2268
2269         return ret;
2270 }
2271
2272 void obj_allocate_commons(struct obj_file *f)
2273 {
2274         struct common_entry {
2275                 struct common_entry *next;
2276                 struct obj_symbol *sym;
2277         } *common_head = NULL;
2278
2279         unsigned long i;
2280
2281         for (i = 0; i < HASH_BUCKETS; ++i) {
2282                 struct obj_symbol *sym;
2283                 for (sym = f->symtab[i]; sym; sym = sym->next)
2284                         if (sym->secidx == SHN_COMMON) {
2285                                 /* Collect all COMMON symbols and sort them by size so as to
2286                                    minimize space wasted by alignment requirements.  */
2287                                 {
2288                                         struct common_entry **p, *n;
2289                                         for (p = &common_head; *p; p = &(*p)->next)
2290                                                 if (sym->size <= (*p)->sym->size)
2291                                                         break;
2292
2293                                         n = alloca(sizeof(*n));
2294                                         n->next = *p;
2295                                         n->sym = sym;
2296                                         *p = n;
2297                                 }
2298                         }
2299         }
2300
2301         for (i = 1; i < f->local_symtab_size; ++i) {
2302                 struct obj_symbol *sym = f->local_symtab[i];
2303                 if (sym && sym->secidx == SHN_COMMON) {
2304                         struct common_entry **p, *n;
2305                         for (p = &common_head; *p; p = &(*p)->next)
2306                                 if (sym == (*p)->sym)
2307                                         break;
2308                                 else if (sym->size < (*p)->sym->size) {
2309                                         n = alloca(sizeof(*n));
2310                                         n->next = *p;
2311                                         n->sym = sym;
2312                                         *p = n;
2313                                         break;
2314                                 }
2315                 }
2316         }
2317
2318         if (common_head) {
2319                 /* Find the bss section.  */
2320                 for (i = 0; i < f->header.e_shnum; ++i)
2321                         if (f->sections[i]->header.sh_type == SHT_NOBITS)
2322                                 break;
2323
2324                 /* If for some reason there hadn't been one, create one.  */
2325                 if (i == f->header.e_shnum) {
2326                         struct obj_section *sec;
2327
2328                         f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2329                         f->sections[i] = sec = arch_new_section();
2330                         f->header.e_shnum = i + 1;
2331
2332                         memset(sec, 0, sizeof(*sec));
2333                         sec->header.sh_type = SHT_PROGBITS;
2334                         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2335                         sec->name = ".bss";
2336                         sec->idx = i;
2337                 }
2338
2339                 /* Allocate the COMMONS.  */
2340                 {
2341                         ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2342                         ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2343                         struct common_entry *c;
2344
2345                         for (c = common_head; c; c = c->next) {
2346                                 ElfW(Addr) align = c->sym->value;
2347
2348                                 if (align > max_align)
2349                                         max_align = align;
2350                                 if (bss_size & (align - 1))
2351                                         bss_size = (bss_size | (align - 1)) + 1;
2352
2353                                 c->sym->secidx = i;
2354                                 c->sym->value = bss_size;
2355
2356                                 bss_size += c->sym->size;
2357                         }
2358
2359                         f->sections[i]->header.sh_size = bss_size;
2360                         f->sections[i]->header.sh_addralign = max_align;
2361                 }
2362         }
2363
2364         /* For the sake of patch relocation and parameter initialization,
2365            allocate zeroed data for NOBITS sections now.  Note that after
2366            this we cannot assume NOBITS are really empty.  */
2367         for (i = 0; i < f->header.e_shnum; ++i) {
2368                 struct obj_section *s = f->sections[i];
2369                 if (s->header.sh_type == SHT_NOBITS) {
2370                         s->contents = memset(xmalloc(s->header.sh_size),
2371                                                                  0, s->header.sh_size);
2372                         s->header.sh_type = SHT_PROGBITS;
2373                 }
2374         }
2375 }
2376
2377 unsigned long obj_load_size(struct obj_file *f)
2378 {
2379         unsigned long dot = 0;
2380         struct obj_section *sec;
2381
2382         /* Finalize the positions of the sections relative to one another.  */
2383
2384         for (sec = f->load_order; sec; sec = sec->load_next) {
2385                 ElfW(Addr) align;
2386
2387                 align = sec->header.sh_addralign;
2388                 if (align && (dot & (align - 1)))
2389                         dot = (dot | (align - 1)) + 1;
2390
2391                 sec->header.sh_addr = dot;
2392                 dot += sec->header.sh_size;
2393         }
2394
2395         return dot;
2396 }
2397
2398 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2399 {
2400         int i, n = f->header.e_shnum;
2401         int ret = 1;
2402
2403         /* Finalize the addresses of the sections.  */
2404
2405         f->baseaddr = base;
2406         for (i = 0; i < n; ++i)
2407                 f->sections[i]->header.sh_addr += base;
2408
2409         /* And iterate over all of the relocations.  */
2410
2411         for (i = 0; i < n; ++i) {
2412                 struct obj_section *relsec, *symsec, *targsec, *strsec;
2413                 ElfW(RelM) * rel, *relend;
2414                 ElfW(Sym) * symtab;
2415                 const char *strtab;
2416
2417                 relsec = f->sections[i];
2418                 if (relsec->header.sh_type != SHT_RELM)
2419                         continue;
2420
2421                 symsec = f->sections[relsec->header.sh_link];
2422                 targsec = f->sections[relsec->header.sh_info];
2423                 strsec = f->sections[symsec->header.sh_link];
2424
2425                 rel = (ElfW(RelM) *) relsec->contents;
2426                 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2427                 symtab = (ElfW(Sym) *) symsec->contents;
2428                 strtab = (const char *) strsec->contents;
2429
2430                 for (; rel < relend; ++rel) {
2431                         ElfW(Addr) value = 0;
2432                         struct obj_symbol *intsym = NULL;
2433                         unsigned long symndx;
2434                         ElfW(Sym) * extsym = 0;
2435                         const char *errmsg;
2436
2437                         /* Attempt to find a value to use for this relocation.  */
2438
2439                         symndx = ELFW(R_SYM) (rel->r_info);
2440                         if (symndx) {
2441                                 /* Note we've already checked for undefined symbols.  */
2442
2443                                 extsym = &symtab[symndx];
2444                                 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2445                                         /* Local symbols we look up in the local table to be sure
2446                                            we get the one that is really intended.  */
2447                                         intsym = f->local_symtab[symndx];
2448                                 } else {
2449                                         /* Others we look up in the hash table.  */
2450                                         const char *name;
2451                                         if (extsym->st_name)
2452                                                 name = strtab + extsym->st_name;
2453                                         else
2454                                                 name = f->sections[extsym->st_shndx]->name;
2455                                         intsym = obj_find_symbol(f, name);
2456                                 }
2457
2458                                 value = obj_symbol_final_value(f, intsym);
2459                                 intsym->referenced = 1;
2460                         }
2461 #if SHT_RELM == SHT_RELA
2462 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2463                         /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9.  */
2464                         if (!extsym || !extsym->st_name ||
2465                                 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2466 #endif
2467                                 value += rel->r_addend;
2468 #endif
2469
2470                         /* Do it! */
2471                         switch (arch_apply_relocation
2472                                         (f, targsec, symsec, intsym, rel, value)) {
2473                         case obj_reloc_ok:
2474                                 break;
2475
2476                         case obj_reloc_overflow:
2477                                 errmsg = "Relocation overflow";
2478                                 goto bad_reloc;
2479                         case obj_reloc_dangerous:
2480                                 errmsg = "Dangerous relocation";
2481                                 goto bad_reloc;
2482                         case obj_reloc_unhandled:
2483                                 errmsg = "Unhandled relocation";
2484                           bad_reloc:
2485                                 if (extsym) {
2486                                         errorMsg("%s of type %ld for %s\n", errmsg,
2487                                                         (long) ELFW(R_TYPE) (rel->r_info),
2488                                                         strtab + extsym->st_name);
2489                                 } else {
2490                                         errorMsg("%s of type %ld\n", errmsg,
2491                                                         (long) ELFW(R_TYPE) (rel->r_info));
2492                                 }
2493                                 ret = 0;
2494                                 break;
2495                         }
2496                 }
2497         }
2498
2499         /* Finally, take care of the patches.  */
2500
2501         if (f->string_patches) {
2502                 struct obj_string_patch *p;
2503                 struct obj_section *strsec;
2504                 ElfW(Addr) strsec_base;
2505                 strsec = obj_find_section(f, ".kstrtab");
2506                 strsec_base = strsec->header.sh_addr;
2507
2508                 for (p = f->string_patches; p; p = p->next) {
2509                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2510                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2511                                 = strsec_base + p->string_offset;
2512                 }
2513         }
2514
2515         if (f->symbol_patches) {
2516                 struct obj_symbol_patch *p;
2517
2518                 for (p = f->symbol_patches; p; p = p->next) {
2519                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2520                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2521                                 = obj_symbol_final_value(f, p->sym);
2522                 }
2523         }
2524
2525         return ret;
2526 }
2527
2528 int obj_create_image(struct obj_file *f, char *image)
2529 {
2530         struct obj_section *sec;
2531         ElfW(Addr) base = f->baseaddr;
2532
2533         for (sec = f->load_order; sec; sec = sec->load_next) {
2534                 char *secimg;
2535
2536                 if (sec->header.sh_size == 0)
2537                         continue;
2538
2539                 secimg = image + (sec->header.sh_addr - base);
2540
2541                 /* Note that we allocated data for NOBITS sections earlier.  */
2542                 memcpy(secimg, sec->contents, sec->header.sh_size);
2543         }
2544
2545         return 1;
2546 }
2547
2548 /*======================================================================*/
2549
2550 struct obj_file *obj_load(FILE * fp)
2551 {
2552         struct obj_file *f;
2553         ElfW(Shdr) * section_headers;
2554         int shnum, i;
2555         char *shstrtab;
2556
2557         /* Read the file header.  */
2558
2559         f = arch_new_file();
2560         memset(f, 0, sizeof(*f));
2561         f->symbol_cmp = strcmp;
2562         f->symbol_hash = obj_elf_hash;
2563         f->load_order_search_start = &f->load_order;
2564
2565         fseek(fp, 0, SEEK_SET);
2566         if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2567                 errorMsg("error reading ELF header: %s", strerror(errno));
2568                 return NULL;
2569         }
2570
2571         if (f->header.e_ident[EI_MAG0] != ELFMAG0
2572                 || f->header.e_ident[EI_MAG1] != ELFMAG1
2573                 || f->header.e_ident[EI_MAG2] != ELFMAG2
2574                 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2575                 errorMsg("not an ELF file\n");
2576                 return NULL;
2577         }
2578         if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2579                 || f->header.e_ident[EI_DATA] != ELFDATAM
2580                 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2581                 || !MATCH_MACHINE(f->header.e_machine)) {
2582                 errorMsg("ELF file not for this architecture\n");
2583                 return NULL;
2584         }
2585         if (f->header.e_type != ET_REL) {
2586                 errorMsg("ELF file not a relocatable object\n");
2587                 return NULL;
2588         }
2589
2590         /* Read the section headers.  */
2591
2592         if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2593                 errorMsg("section header size mismatch: %lu != %lu\n",
2594                                 (unsigned long) f->header.e_shentsize,
2595                                 (unsigned long) sizeof(ElfW(Shdr)));
2596                 return NULL;
2597         }
2598
2599         shnum = f->header.e_shnum;
2600         f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2601         memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2602
2603         section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2604         fseek(fp, f->header.e_shoff, SEEK_SET);
2605         if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2606                 errorMsg("error reading ELF section headers: %s", strerror(errno));
2607                 return NULL;
2608         }
2609
2610         /* Read the section data.  */
2611
2612         for (i = 0; i < shnum; ++i) {
2613                 struct obj_section *sec;
2614
2615                 f->sections[i] = sec = arch_new_section();
2616                 memset(sec, 0, sizeof(*sec));
2617
2618                 sec->header = section_headers[i];
2619                 sec->idx = i;
2620
2621                 switch (sec->header.sh_type) {
2622                 case SHT_NULL:
2623                 case SHT_NOTE:
2624                 case SHT_NOBITS:
2625                         /* ignore */
2626                         break;
2627
2628                 case SHT_PROGBITS:
2629                 case SHT_SYMTAB:
2630                 case SHT_STRTAB:
2631                 case SHT_RELM:
2632                         if (sec->header.sh_size > 0) {
2633                                 sec->contents = xmalloc(sec->header.sh_size);
2634                                 fseek(fp, sec->header.sh_offset, SEEK_SET);
2635                                 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2636                                         errorMsg("error reading ELF section data: %s", strerror(errno));
2637                                         return NULL;
2638                                 }
2639                         } else {
2640                                 sec->contents = NULL;
2641                         }
2642                         break;
2643
2644 #if SHT_RELM == SHT_REL
2645                 case SHT_RELA:
2646                         errorMsg("RELA relocations not supported on this architecture\n");
2647                         return NULL;
2648 #else
2649                 case SHT_REL:
2650                         errorMsg("REL relocations not supported on this architecture\n");
2651                         return NULL;
2652 #endif
2653
2654                 default:
2655                         if (sec->header.sh_type >= SHT_LOPROC) {
2656                                 /* Assume processor specific section types are debug
2657                                    info and can safely be ignored.  If this is ever not
2658                                    the case (Hello MIPS?), don't put ifdefs here but
2659                                    create an arch_load_proc_section().  */
2660                                 break;
2661                         }
2662
2663                         errorMsg("can't handle sections of type %ld\n",
2664                                         (long) sec->header.sh_type);
2665                         return NULL;
2666                 }
2667         }
2668
2669         /* Do what sort of interpretation as needed by each section.  */
2670
2671         shstrtab = f->sections[f->header.e_shstrndx]->contents;
2672
2673         for (i = 0; i < shnum; ++i) {
2674                 struct obj_section *sec = f->sections[i];
2675                 sec->name = shstrtab + sec->header.sh_name;
2676         }
2677
2678         for (i = 0; i < shnum; ++i) {
2679                 struct obj_section *sec = f->sections[i];
2680
2681                 if (sec->header.sh_flags & SHF_ALLOC)
2682                         obj_insert_section_load_order(f, sec);
2683
2684                 switch (sec->header.sh_type) {
2685                 case SHT_SYMTAB:
2686                         {
2687                                 unsigned long nsym, j;
2688                                 char *strtab;
2689                                 ElfW(Sym) * sym;
2690
2691                                 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
2692                                         errorMsg("symbol size mismatch: %lu != %lu\n",
2693                                                         (unsigned long) sec->header.sh_entsize,
2694                                                         (unsigned long) sizeof(ElfW(Sym)));
2695                                         return NULL;
2696                                 }
2697
2698                                 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
2699                                 strtab = f->sections[sec->header.sh_link]->contents;
2700                                 sym = (ElfW(Sym) *) sec->contents;
2701
2702                                 /* Allocate space for a table of local symbols.  */
2703                                 j = f->local_symtab_size = sec->header.sh_info;
2704                                 f->local_symtab = xmalloc(j *=
2705                                                                                   sizeof(struct obj_symbol *));
2706                                 memset(f->local_symtab, 0, j);
2707
2708                                 /* Insert all symbols into the hash table.  */
2709                                 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
2710                                         const char *name;
2711                                         if (sym->st_name)
2712                                                 name = strtab + sym->st_name;
2713                 else
2714                                                 name = f->sections[sym->st_shndx]->name;
2715
2716                                         obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
2717                                                                    sym->st_value, sym->st_size);
2718                 }
2719         }
2720                         break;
2721
2722                 case SHT_RELM:
2723                         if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
2724                                 errorMsg("relocation entry size mismatch: %lu != %lu\n",
2725                                                 (unsigned long) sec->header.sh_entsize,
2726                                                 (unsigned long) sizeof(ElfW(RelM)));
2727                                 return NULL;
2728                         }
2729                         break;
2730                 }
2731         }
2732
2733         return f;
2734 }
2735
2736 static void hide_special_symbols(struct obj_file *f)
2737 {
2738         static const char *const specials[] = {
2739                 "cleanup_module",
2740                 "init_module",
2741                 "kernel_version",
2742                 NULL
2743         };
2744
2745         struct obj_symbol *sym;
2746         const char *const *p;
2747
2748         for (p = specials; *p; ++p)
2749                 if ((sym = obj_find_symbol(f, *p)) != NULL)
2750                         sym->info =
2751                                 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
2752 }
2753
2754
2755
2756 extern int insmod_main( int argc, char **argv)
2757 {
2758         int k_crcs;
2759         int k_new_syscalls;
2760         int len;
2761         char *tmp;
2762         unsigned long m_size;
2763         ElfW(Addr) m_addr;
2764         FILE *fp;
2765         struct obj_file *f;
2766         char m_name[BUFSIZ + 1] = "\0";
2767         int exit_status = FALSE;
2768         int m_has_modinfo;
2769 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2770         int k_version;
2771         char k_strversion[STRVERSIONLEN];
2772         char m_strversion[STRVERSIONLEN];
2773         int m_version;
2774         int m_crcs;
2775 #endif
2776
2777
2778         if (argc <= 1) {
2779                 usage(insmod_usage);
2780         }
2781
2782         /* Parse any options */
2783         while (--argc > 0 && **(++argv) == '-') {
2784                 while (*(++(*argv))) {
2785                         switch (**argv) {
2786                         case 'f':                       /* force loading */
2787                                 flag_force_load = 1;
2788                                 break;
2789                         case 'k':                       /* module loaded by kerneld, auto-cleanable */
2790                                 flag_autoclean = 1;
2791                                 break;
2792                         case 'v':                       /* verbose output */
2793                                 flag_verbose = 1;
2794                                 break;
2795                         case 'x':                       /* do not export externs */
2796                                 flag_export = 0;
2797                                 break;
2798                         default:
2799                                 usage(insmod_usage);
2800                         }
2801                 }
2802         }
2803
2804         if (argc <= 0) {
2805                 usage(insmod_usage);
2806         }
2807         /* Grab the module name */
2808         if ((tmp = strrchr(*argv, '/')) != NULL) {
2809                 tmp++;
2810         } else {
2811                 tmp = *argv;
2812         }
2813         len = strlen(tmp);
2814
2815         if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
2816                 len -= 2;
2817         memcpy(m_name, tmp, len);
2818         strcpy(m_fullName, m_name);
2819         strcat(m_fullName, ".o");
2820
2821         /* Get a filedesc for the module */
2822         if ((fp = fopen(*argv, "r")) == NULL) {
2823                 /* Hmpf.  Could not open it. Search through _PATH_MODULES to find a module named m_name */
2824                 if (recursiveAction(_PATH_MODULES, TRUE, FALSE, FALSE,
2825                                                         findNamedModule, 0, m_fullName) == FALSE) 
2826                 {
2827                         if (m_filename[0] == '\0'
2828                                 || ((fp = fopen(m_filename, "r")) == NULL)) 
2829                         {
2830                                 errorMsg("No module named '%s' found in '%s'\n", m_fullName, _PATH_MODULES);
2831                                 exit(FALSE);
2832                         }
2833                 } else
2834                         fatalError("No module named '%s' found in '%s'\n", m_fullName, _PATH_MODULES);
2835         } else
2836                 memcpy(m_filename, *argv, strlen(*argv));
2837
2838
2839         if ((f = obj_load(fp)) == NULL) {
2840                 perror("Could not load the module\n");
2841                 exit(FALSE);
2842         }
2843
2844         if (get_modinfo_value(f, "kernel_version") == NULL)
2845                 m_has_modinfo = 0;
2846         else
2847                 m_has_modinfo = 1;
2848
2849 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2850         /* Version correspondence?  */
2851
2852         k_version = get_kernel_version(k_strversion);
2853         if (m_has_modinfo) {
2854                 m_version = new_get_module_version(f, m_strversion);
2855         } else {
2856                 m_version = old_get_module_version(f, m_strversion);
2857                 if (m_version == -1) {
2858                         errorMsg("couldn't find the kernel version the module was "
2859                                         "compiled for\n");
2860                         goto out;
2861                 }
2862         }
2863
2864         if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
2865                 if (flag_force_load) {
2866                         errorMsg("Warning: kernel-module version mismatch\n"
2867                                         "\t%s was compiled for kernel version %s\n"
2868                                         "\twhile this kernel is version %s\n",
2869                                         m_filename, m_strversion, k_strversion);
2870                 } else {
2871                         errorMsg("kernel-module version mismatch\n"
2872                                         "\t%s was compiled for kernel version %s\n"
2873                                         "\twhile this kernel is version %s.\n",
2874                                         m_filename, m_strversion, k_strversion);
2875                         goto out;
2876                 }
2877         }
2878         k_crcs = 0;
2879 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2880
2881         k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
2882
2883         if (k_new_syscalls) {
2884 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
2885                 if (!new_get_kernel_symbols())
2886                         goto out;
2887                 k_crcs = new_is_kernel_checksummed();
2888 #else
2889                 errorMsg("Not configured to support new kernels\n");
2890                 goto out;
2891 #endif
2892         } else {
2893 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
2894                 if (!old_get_kernel_symbols(m_name))
2895                         goto out;
2896                 k_crcs = old_is_kernel_checksummed();
2897 #else
2898                 errorMsg("Not configured to support old kernels\n");
2899                 goto out;
2900 #endif
2901         }
2902
2903 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2904         if (m_has_modinfo)
2905                 m_crcs = new_is_module_checksummed(f);
2906         else
2907                 m_crcs = old_is_module_checksummed(f);
2908
2909         if (m_crcs != k_crcs)
2910                 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
2911 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2912
2913         /* Let the module know about the kernel symbols.  */
2914         add_kernel_symbols(f);
2915
2916         /* Allocate common symbols, symbol tables, and string tables.  */
2917
2918         if (k_new_syscalls 
2919                 ? !new_create_this_module(f, m_name)
2920                 : !old_create_mod_use_count(f)) 
2921         {
2922                 goto out;
2923         }
2924
2925         if (!obj_check_undefineds(f)) {
2926                 goto out;
2927         }
2928         obj_allocate_commons(f);
2929
2930         if (optind < argc) {
2931                 if (m_has_modinfo
2932                         ? !new_process_module_arguments(f, argc - optind, argv + optind) 
2933                         : !old_process_module_arguments(f, argc - optind, argv + optind)) 
2934                 {
2935                         goto out;
2936                 }
2937         }
2938
2939         arch_create_got(f);
2940         hide_special_symbols(f);
2941
2942         if (k_new_syscalls)
2943                 new_create_module_ksymtab(f);
2944
2945         /* Find current size of the module */
2946         m_size = obj_load_size(f);
2947
2948
2949         errno = 0;
2950         m_addr = create_module(m_name, m_size);
2951         switch (errno) {
2952         case 0:
2953                 break;
2954         case EEXIST:
2955                 errorMsg("A module named %s already exists\n", m_name);
2956                 goto out;
2957         case ENOMEM:
2958                 errorMsg("Can't allocate kernel memory for module; needed %lu bytes\n",
2959                                 m_size);
2960                 goto out;
2961         default:
2962                 errorMsg("create_module: %s: %s", m_name, strerror(errno));
2963                 goto out;
2964         }
2965
2966         if (!obj_relocate(f, m_addr)) {
2967                 delete_module(m_name);
2968                 goto out;
2969         }
2970
2971         if (k_new_syscalls 
2972                 ? !new_init_module(m_name, f, m_size)
2973                 : !old_init_module(m_name, f, m_size)) 
2974         {
2975                 delete_module(m_name);
2976                 goto out;
2977         }
2978
2979         exit_status = TRUE;
2980
2981 out:
2982         fclose(fp);
2983         return(exit_status);
2984 }