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