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