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