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