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