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