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