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