Small size optimization from Aaron Lehmann
[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.71 2001/08/06 14:18:08 kraai 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.71 2001/08/06 14:18:08 kraai 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 /* String comparison for non-co-versioned kernel and module.  */
1308
1309 static int ncv_strcmp(const char *a, const char *b)
1310 {
1311         size_t alen = strlen(a), blen = strlen(b);
1312
1313         if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1314                 return strncmp(a, b, alen);
1315         else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1316                 return strncmp(a, b, blen);
1317         else
1318                 return strcmp(a, b);
1319 }
1320
1321 /* String hashing for non-co-versioned kernel and module.  Here
1322    we are simply forced to drop the crc from the hash.  */
1323
1324 static unsigned long ncv_symbol_hash(const char *str)
1325 {
1326         size_t len = strlen(str);
1327         if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1328                 len -= 10;
1329         return obj_elf_hash_n(str, len);
1330 }
1331
1332 static void
1333 obj_set_symbol_compare(struct obj_file *f,
1334                                            int (*cmp) (const char *, const char *),
1335                                            unsigned long (*hash) (const char *))
1336 {
1337         if (cmp)
1338                 f->symbol_cmp = cmp;
1339         if (hash) {
1340                 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1341                 int i;
1342
1343                 f->symbol_hash = hash;
1344
1345                 memcpy(tmptab, f->symtab, sizeof(tmptab));
1346                 memset(f->symtab, 0, sizeof(f->symtab));
1347
1348                 for (i = 0; i < HASH_BUCKETS; ++i)
1349                         for (sym = tmptab[i]; sym; sym = next) {
1350                                 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1351                                 next = sym->next;
1352                                 sym->next = f->symtab[h];
1353                                 f->symtab[h] = sym;
1354                         }
1355         }
1356 }
1357
1358 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1359
1360 static struct obj_symbol *
1361 obj_add_symbol(struct obj_file *f, const char *name,
1362                                                                   unsigned long symidx, int info,
1363                                                                   int secidx, ElfW(Addr) value,
1364                                                                   unsigned long size)
1365 {
1366         struct obj_symbol *sym;
1367         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1368         int n_type = ELFW(ST_TYPE) (info);
1369         int n_binding = ELFW(ST_BIND) (info);
1370
1371         for (sym = f->symtab[hash]; sym; sym = sym->next)
1372                 if (f->symbol_cmp(sym->name, name) == 0) {
1373                         int o_secidx = sym->secidx;
1374                         int o_info = sym->info;
1375                         int o_type = ELFW(ST_TYPE) (o_info);
1376                         int o_binding = ELFW(ST_BIND) (o_info);
1377
1378                         /* A redefinition!  Is it legal?  */
1379
1380                         if (secidx == SHN_UNDEF)
1381                                 return sym;
1382                         else if (o_secidx == SHN_UNDEF)
1383                                 goto found;
1384                         else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1385                                 /* Cope with local and global symbols of the same name
1386                                    in the same object file, as might have been created
1387                                    by ld -r.  The only reason locals are now seen at this
1388                                    level at all is so that we can do semi-sensible things
1389                                    with parameters.  */
1390
1391                                 struct obj_symbol *nsym, **p;
1392
1393                                 nsym = arch_new_symbol();
1394                                 nsym->next = sym->next;
1395                                 nsym->ksymidx = -1;
1396
1397                                 /* Excise the old (local) symbol from the hash chain.  */
1398                                 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1399                                         continue;
1400                                 *p = sym = nsym;
1401                                 goto found;
1402                         } else if (n_binding == STB_LOCAL) {
1403                                 /* Another symbol of the same name has already been defined.
1404                                    Just add this to the local table.  */
1405                                 sym = arch_new_symbol();
1406                                 sym->next = NULL;
1407                                 sym->ksymidx = -1;
1408                                 f->local_symtab[symidx] = sym;
1409                                 goto found;
1410                         } else if (n_binding == STB_WEAK)
1411                                 return sym;
1412                         else if (o_binding == STB_WEAK)
1413                                 goto found;
1414                         /* Don't unify COMMON symbols with object types the programmer
1415                            doesn't expect.  */
1416                         else if (secidx == SHN_COMMON
1417                                          && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1418                                 return sym;
1419                         else if (o_secidx == SHN_COMMON
1420                                          && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1421                                 goto found;
1422                         else {
1423                                 /* Don't report an error if the symbol is coming from
1424                                    the kernel or some external module.  */
1425                                 if (secidx <= SHN_HIRESERVE)
1426                                         error_msg("%s multiply defined", name);
1427                                 return sym;
1428                         }
1429                 }
1430
1431         /* Completely new symbol.  */
1432         sym = arch_new_symbol();
1433         sym->next = f->symtab[hash];
1434         f->symtab[hash] = sym;
1435         sym->ksymidx = -1;
1436
1437         if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) {
1438                 if (symidx >= f->local_symtab_size)
1439                         error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
1440                                         name, (long) symidx, (long) f->local_symtab_size);
1441                 else
1442                         f->local_symtab[symidx] = sym;
1443         }
1444
1445   found:
1446         sym->name = name;
1447         sym->value = value;
1448         sym->size = size;
1449         sym->secidx = secidx;
1450         sym->info = info;
1451
1452         return sym;
1453 }
1454
1455 static struct obj_symbol *
1456 obj_find_symbol(struct obj_file *f, const char *name)
1457 {
1458         struct obj_symbol *sym;
1459         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1460
1461         for (sym = f->symtab[hash]; sym; sym = sym->next)
1462                 if (f->symbol_cmp(sym->name, name) == 0)
1463                         return sym;
1464
1465         return NULL;
1466 }
1467
1468 static ElfW(Addr)
1469         obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1470 {
1471         if (sym) {
1472                 if (sym->secidx >= SHN_LORESERVE)
1473                         return sym->value;
1474
1475                 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1476         } else {
1477                 /* As a special case, a NULL sym has value zero.  */
1478                 return 0;
1479         }
1480 }
1481
1482 static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1483 {
1484         int i, n = f->header.e_shnum;
1485
1486         for (i = 0; i < n; ++i)
1487                 if (strcmp(f->sections[i]->name, name) == 0)
1488                         return f->sections[i];
1489
1490         return NULL;
1491 }
1492
1493 static int obj_load_order_prio(struct obj_section *a)
1494 {
1495         unsigned long af, ac;
1496
1497         af = a->header.sh_flags;
1498
1499         ac = 0;
1500         if (a->name[0] != '.' || strlen(a->name) != 10 ||
1501                 strcmp(a->name + 5, ".init"))
1502                 ac |= 32;
1503         if (af & SHF_ALLOC)
1504                 ac |= 16;
1505         if (!(af & SHF_WRITE))
1506                 ac |= 8;
1507         if (af & SHF_EXECINSTR)
1508                 ac |= 4;
1509         if (a->header.sh_type != SHT_NOBITS)
1510                 ac |= 2;
1511
1512         return ac;
1513 }
1514
1515 static void
1516 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1517 {
1518         struct obj_section **p;
1519         int prio = obj_load_order_prio(sec);
1520         for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1521                 if (obj_load_order_prio(*p) < prio)
1522                         break;
1523         sec->load_next = *p;
1524         *p = sec;
1525 }
1526
1527 static struct obj_section *obj_create_alloced_section(struct obj_file *f,
1528                                                                                            const char *name,
1529                                                                                            unsigned long align,
1530                                                                                            unsigned long size)
1531 {
1532         int newidx = f->header.e_shnum++;
1533         struct obj_section *sec;
1534
1535         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1536         f->sections[newidx] = sec = arch_new_section();
1537
1538         memset(sec, 0, sizeof(*sec));
1539         sec->header.sh_type = SHT_PROGBITS;
1540         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1541         sec->header.sh_size = size;
1542         sec->header.sh_addralign = align;
1543         sec->name = name;
1544         sec->idx = newidx;
1545         if (size)
1546                 sec->contents = xmalloc(size);
1547
1548         obj_insert_section_load_order(f, sec);
1549
1550         return sec;
1551 }
1552
1553 static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1554                                                                                                          const char *name,
1555                                                                                                          unsigned long align,
1556                                                                                                          unsigned long size)
1557 {
1558         int newidx = f->header.e_shnum++;
1559         struct obj_section *sec;
1560
1561         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1562         f->sections[newidx] = sec = arch_new_section();
1563
1564         memset(sec, 0, sizeof(*sec));
1565         sec->header.sh_type = SHT_PROGBITS;
1566         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1567         sec->header.sh_size = size;
1568         sec->header.sh_addralign = align;
1569         sec->name = name;
1570         sec->idx = newidx;
1571         if (size)
1572                 sec->contents = xmalloc(size);
1573
1574         sec->load_next = f->load_order;
1575         f->load_order = sec;
1576         if (f->load_order_search_start == &f->load_order)
1577                 f->load_order_search_start = &sec->load_next;
1578
1579         return sec;
1580 }
1581
1582 static void *obj_extend_section(struct obj_section *sec, unsigned long more)
1583 {
1584         unsigned long oldsize = sec->header.sh_size;
1585         if (more) { 
1586                 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1587         }
1588         return sec->contents + oldsize;
1589 }
1590
1591
1592 /* Conditionally add the symbols from the given symbol set to the
1593    new module.  */
1594
1595 static int
1596 add_symbols_from(
1597                                  struct obj_file *f,
1598                                  int idx, struct new_module_symbol *syms, size_t nsyms)
1599 {
1600         struct new_module_symbol *s;
1601         size_t i;
1602         int used = 0;
1603
1604         for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1605
1606                 /* Only add symbols that are already marked external.  If we
1607                    override locals we may cause problems for argument initialization.
1608                    We will also create a false dependency on the module.  */
1609                 struct obj_symbol *sym;
1610
1611                 sym = obj_find_symbol(f, (char *) s->name);
1612                 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1613                         sym = obj_add_symbol(f, (char *) s->name, -1,
1614                                                                  ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1615                                                                  idx, s->value, 0);
1616                         /* Did our symbol just get installed?  If so, mark the
1617                            module as "used".  */
1618                         if (sym->secidx == idx)
1619                                 used = 1;
1620                 }
1621         }
1622
1623         return used;
1624 }
1625
1626 static void add_kernel_symbols(struct obj_file *f)
1627 {
1628         struct external_module *m;
1629         int i, nused = 0;
1630
1631         /* Add module symbols first.  */
1632
1633         for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1634                 if (m->nsyms
1635                         && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1636                                                                 m->nsyms)) m->used = 1, ++nused;
1637
1638         n_ext_modules_used = nused;
1639
1640         /* And finally the symbols from the kernel proper.  */
1641
1642         if (nksyms)
1643                 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1644 }
1645
1646 static char *get_modinfo_value(struct obj_file *f, const char *key)
1647 {
1648         struct obj_section *sec;
1649         char *p, *v, *n, *ep;
1650         size_t klen = strlen(key);
1651
1652         sec = obj_find_section(f, ".modinfo");
1653         if (sec == NULL)
1654                 return NULL;
1655         p = sec->contents;
1656         ep = p + sec->header.sh_size;
1657         while (p < ep) {
1658                 v = strchr(p, '=');
1659                 n = strchr(p, '\0');
1660                 if (v) {
1661                         if (p + klen == v && strncmp(p, key, klen) == 0)
1662                                 return v + 1;
1663                 } else {
1664                         if (p + klen == n && strcmp(p, key) == 0)
1665                                 return n;
1666                 }
1667                 p = n + 1;
1668         }
1669
1670         return NULL;
1671 }
1672
1673
1674 /*======================================================================*/
1675 /* Functions relating to module loading in pre 2.1 kernels.  */
1676
1677 static int
1678 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1679 {
1680         while (argc > 0) {
1681                 char *p, *q;
1682                 struct obj_symbol *sym;
1683                 int *loc;
1684
1685                 p = *argv;
1686                 if ((q = strchr(p, '=')) == NULL) {
1687                         argc--;
1688                         continue;
1689                 }
1690                 *q++ = '\0';
1691
1692                 sym = obj_find_symbol(f, p);
1693
1694                 /* Also check that the parameter was not resolved from the kernel.  */
1695                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1696                         error_msg("symbol for parameter %s not found", p);
1697                         return 0;
1698                 }
1699
1700                 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1701
1702                 /* Do C quoting if we begin with a ".  */
1703                 if (*q == '"') {
1704                         char *r, *str;
1705
1706                         str = alloca(strlen(q));
1707                         for (r = str, q++; *q != '"'; ++q, ++r) {
1708                                 if (*q == '\0') {
1709                                         error_msg("improperly terminated string argument for %s", p);
1710                                         return 0;
1711                                 } else if (*q == '\\')
1712                                         switch (*++q) {
1713                                         case 'a':
1714                                                 *r = '\a';
1715                                                 break;
1716                                         case 'b':
1717                                                 *r = '\b';
1718                                                 break;
1719                                         case 'e':
1720                                                 *r = '\033';
1721                                                 break;
1722                                         case 'f':
1723                                                 *r = '\f';
1724                                                 break;
1725                                         case 'n':
1726                                                 *r = '\n';
1727                                                 break;
1728                                         case 'r':
1729                                                 *r = '\r';
1730                                                 break;
1731                                         case 't':
1732                                                 *r = '\t';
1733                                                 break;
1734
1735                                         case '0':
1736                                         case '1':
1737                                         case '2':
1738                                         case '3':
1739                                         case '4':
1740                                         case '5':
1741                                         case '6':
1742                                         case '7':
1743                                                 {
1744                                                         int c = *q - '0';
1745                                                         if (q[1] >= '0' && q[1] <= '7') {
1746                                                                 c = (c * 8) + *++q - '0';
1747                                                                 if (q[1] >= '0' && q[1] <= '7')
1748                                                                         c = (c * 8) + *++q - '0';
1749                                                         }
1750                                                         *r = c;
1751                                                 }
1752                                                 break;
1753
1754                                         default:
1755                                                 *r = *q;
1756                                                 break;
1757                                 } else
1758                                         *r = *q;
1759                         }
1760                         *r = '\0';
1761                         obj_string_patch(f, sym->secidx, sym->value, str);
1762                 } else if (*q >= '0' && *q <= '9') {
1763                         do
1764                                 *loc++ = strtoul(q, &q, 0);
1765                         while (*q++ == ',');
1766                 } else {
1767                         char *contents = f->sections[sym->secidx]->contents;
1768                         char *myloc = contents + sym->value;
1769                         char *r;                        /* To search for commas */
1770
1771                         /* Break the string with comas */
1772                         while ((r = strchr(q, ',')) != (char *) NULL) {
1773                                 *r++ = '\0';
1774                                 obj_string_patch(f, sym->secidx, myloc - contents, q);
1775                                 myloc += sizeof(char *);
1776                                 q = r;
1777                         }
1778
1779                         /* last part */
1780                         obj_string_patch(f, sym->secidx, myloc - contents, q);
1781                 }
1782
1783                 argc--, argv++;
1784         }
1785
1786         return 1;
1787 }
1788
1789 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1790 static int old_is_module_checksummed(struct obj_file *f)
1791 {
1792         return obj_find_symbol(f, "Using_Versions") != NULL;
1793 }
1794 /* Get the module's kernel version in the canonical integer form.  */
1795
1796 static int
1797 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1798 {
1799         struct obj_symbol *sym;
1800         char *p, *q;
1801         int a, b, c;
1802
1803         sym = obj_find_symbol(f, "kernel_version");
1804         if (sym == NULL)
1805                 return -1;
1806
1807         p = f->sections[sym->secidx]->contents + sym->value;
1808         strncpy(str, p, STRVERSIONLEN);
1809
1810         a = strtoul(p, &p, 10);
1811         if (*p != '.')
1812                 return -1;
1813         b = strtoul(p + 1, &p, 10);
1814         if (*p != '.')
1815                 return -1;
1816         c = strtoul(p + 1, &q, 10);
1817         if (p + 1 == q)
1818                 return -1;
1819
1820         return a << 16 | b << 8 | c;
1821 }
1822
1823 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1824
1825 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
1826
1827 /* Fetch all the symbols and divvy them up as appropriate for the modules.  */
1828
1829 static int old_get_kernel_symbols(const char *m_name)
1830 {
1831         struct old_kernel_sym *ks, *k;
1832         struct new_module_symbol *s;
1833         struct external_module *mod;
1834         int nks, nms, nmod, i;
1835
1836         nks = get_kernel_syms(NULL);
1837         if (nks <= 0) {
1838                 if (nks)
1839                         perror_msg("get_kernel_syms: %s", m_name);
1840                 else
1841                         error_msg("No kernel symbols");
1842                 return 0;
1843         }
1844
1845         ks = k = xmalloc(nks * sizeof(*ks));
1846
1847         if (get_kernel_syms(ks) != nks) {
1848                 perror("inconsistency with get_kernel_syms -- is someone else "
1849                            "playing with modules?");
1850                 free(ks);
1851                 return 0;
1852         }
1853
1854         /* Collect the module information.  */
1855
1856         mod = NULL;
1857         nmod = -1;
1858
1859         while (k->name[0] == '#' && k->name[1]) {
1860                 struct old_kernel_sym *k2;
1861
1862                 /* Find out how many symbols this module has.  */
1863                 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1864                         continue;
1865                 nms = k2 - k - 1;
1866
1867                 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1868                 mod[nmod].name = k->name + 1;
1869                 mod[nmod].addr = k->value;
1870                 mod[nmod].used = 0;
1871                 mod[nmod].nsyms = nms;
1872                 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1873
1874                 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1875                         s->name = (unsigned long) k->name;
1876                         s->value = k->value;
1877                 }
1878
1879                 k = k2;
1880         }
1881
1882         ext_modules = mod;
1883         n_ext_modules = nmod + 1;
1884
1885         /* Now collect the symbols for the kernel proper.  */
1886
1887         if (k->name[0] == '#')
1888                 ++k;
1889
1890         nksyms = nms = nks - (k - ks);
1891         ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1892
1893         for (i = 0; i < nms; ++i, ++s, ++k) {
1894                 s->name = (unsigned long) k->name;
1895                 s->value = k->value;
1896         }
1897
1898         return 1;
1899 }
1900
1901 /* Return the kernel symbol checksum version, or zero if not used.  */
1902
1903 static int old_is_kernel_checksummed(void)
1904 {
1905         /* Using_Versions is the first symbol.  */
1906         if (nksyms > 0
1907                 && strcmp((char *) ksyms[0].name,
1908                                   "Using_Versions") == 0) return ksyms[0].value;
1909         else
1910                 return 0;
1911 }
1912
1913
1914 static int old_create_mod_use_count(struct obj_file *f)
1915 {
1916         struct obj_section *sec;
1917
1918         sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1919                                                                                    sizeof(long));
1920
1921         obj_add_symbol(f, "mod_use_count_", -1,
1922                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1923                                    sizeof(long));
1924
1925         return 1;
1926 }
1927
1928 static int
1929 old_init_module(const char *m_name, struct obj_file *f,
1930                                 unsigned long m_size)
1931 {
1932         char *image;
1933         struct old_mod_routines routines;
1934         struct old_symbol_table *symtab;
1935         int ret;
1936
1937         /* Create the symbol table */
1938         {
1939                 int nsyms = 0, strsize = 0, total;
1940
1941                 /* Size things first... */
1942                 if (flag_export) {
1943                         int i;
1944                         for (i = 0; i < HASH_BUCKETS; ++i) {
1945                                 struct obj_symbol *sym;
1946                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1947                                         if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1948                                                 && sym->secidx <= SHN_HIRESERVE) 
1949                                         {
1950                                                 sym->ksymidx = nsyms++;
1951                                                 strsize += strlen(sym->name) + 1;
1952                                         }
1953                         }
1954                 }
1955
1956                 total = (sizeof(struct old_symbol_table)
1957                                  + nsyms * sizeof(struct old_module_symbol)
1958                                  + n_ext_modules_used * sizeof(struct old_module_ref)
1959                                  + strsize);
1960                 symtab = xmalloc(total);
1961                 symtab->size = total;
1962                 symtab->n_symbols = nsyms;
1963                 symtab->n_refs = n_ext_modules_used;
1964
1965                 if (flag_export && nsyms) {
1966                         struct old_module_symbol *ksym;
1967                         char *str;
1968                         int i;
1969
1970                         ksym = symtab->symbol;
1971                         str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1972                                    + n_ext_modules_used * sizeof(struct old_module_ref));
1973
1974                         for (i = 0; i < HASH_BUCKETS; ++i) {
1975                                 struct obj_symbol *sym;
1976                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1977                                         if (sym->ksymidx >= 0) {
1978                                                 ksym->addr = obj_symbol_final_value(f, sym);
1979                                                 ksym->name =
1980                                                         (unsigned long) str - (unsigned long) symtab;
1981
1982                                                 strcpy(str, sym->name);
1983                                                 str += strlen(sym->name) + 1;
1984                                                 ksym++;
1985                                         }
1986                         }
1987                 }
1988
1989                 if (n_ext_modules_used) {
1990                         struct old_module_ref *ref;
1991                         int i;
1992
1993                         ref = (struct old_module_ref *)
1994                                 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1995
1996                         for (i = 0; i < n_ext_modules; ++i)
1997                                 if (ext_modules[i].used)
1998                                         ref++->module = ext_modules[i].addr;
1999                 }
2000         }
2001
2002         /* Fill in routines.  */
2003
2004         routines.init =
2005                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2006         routines.cleanup =
2007                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2008
2009         /* Whew!  All of the initialization is complete.  Collect the final
2010            module image and give it to the kernel.  */
2011
2012         image = xmalloc(m_size);
2013         obj_create_image(f, image);
2014
2015         /* image holds the complete relocated module, accounting correctly for
2016            mod_use_count.  However the old module kernel support assume that
2017            it is receiving something which does not contain mod_use_count.  */
2018         ret = old_sys_init_module(m_name, image + sizeof(long),
2019                                                           m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
2020                                                                                 : 0), &routines, symtab);
2021         if (ret)
2022                 perror_msg("init_module: %s", m_name);
2023
2024         free(image);
2025         free(symtab);
2026
2027         return ret == 0;
2028 }
2029
2030 #else
2031
2032 #define old_create_mod_use_count(x) TRUE
2033 #define old_init_module(x, y, z) TRUE
2034
2035 #endif                                                  /* BB_FEATURE_OLD_MODULE_INTERFACE */
2036
2037
2038
2039 /*======================================================================*/
2040 /* Functions relating to module loading after 2.1.18.  */
2041
2042 static int
2043 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2044 {
2045         while (argc > 0) {
2046                 char *p, *q, *key;
2047                 struct obj_symbol *sym;
2048                 char *contents, *loc;
2049                 int min, max, n;
2050
2051                 p = *argv;
2052                 if ((q = strchr(p, '=')) == NULL) {
2053                         argc--;
2054                         continue;
2055                 }
2056
2057                 key = alloca(q - p + 6);
2058                 memcpy(key, "parm_", 5);
2059                 memcpy(key + 5, p, q - p);
2060                 key[q - p + 5] = 0;
2061
2062                 p = get_modinfo_value(f, key);
2063                 key += 5;
2064                 if (p == NULL) {
2065                         error_msg("invalid parameter %s", key);
2066                         return 0;
2067                 }
2068
2069                 sym = obj_find_symbol(f, key);
2070
2071                 /* Also check that the parameter was not resolved from the kernel.  */
2072                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
2073                         error_msg("symbol for parameter %s not found", key);
2074                         return 0;
2075                 }
2076
2077                 if (isdigit(*p)) {
2078                         min = strtoul(p, &p, 10);
2079                         if (*p == '-')
2080                                 max = strtoul(p + 1, &p, 10);
2081                         else
2082                                 max = min;
2083                 } else
2084                         min = max = 1;
2085
2086                 contents = f->sections[sym->secidx]->contents;
2087                 loc = contents + sym->value;
2088                 n = (*++q != '\0');
2089
2090                 while (1) {
2091                         if ((*p == 's') || (*p == 'c')) {
2092                                 char *str;
2093
2094                                 /* Do C quoting if we begin with a ", else slurp the lot.  */
2095                                 if (*q == '"') {
2096                                         char *r;
2097
2098                                         str = alloca(strlen(q));
2099                                         for (r = str, q++; *q != '"'; ++q, ++r) {
2100                                                 if (*q == '\0') {
2101                                                         error_msg("improperly terminated string argument for %s",
2102                                                                         key);
2103                                                         return 0;
2104                                                 } else if (*q == '\\')
2105                                                         switch (*++q) {
2106                                                         case 'a':
2107                                                                 *r = '\a';
2108                                                                 break;
2109                                                         case 'b':
2110                                                                 *r = '\b';
2111                                                                 break;
2112                                                         case 'e':
2113                                                                 *r = '\033';
2114                                                                 break;
2115                                                         case 'f':
2116                                                                 *r = '\f';
2117                                                                 break;
2118                                                         case 'n':
2119                                                                 *r = '\n';
2120                                                                 break;
2121                                                         case 'r':
2122                                                                 *r = '\r';
2123                                                                 break;
2124                                                         case 't':
2125                                                                 *r = '\t';
2126                                                                 break;
2127
2128                                                         case '0':
2129                                                         case '1':
2130                                                         case '2':
2131                                                         case '3':
2132                                                         case '4':
2133                                                         case '5':
2134                                                         case '6':
2135                                                         case '7':
2136                                                                 {
2137                                                                         int c = *q - '0';
2138                                                                         if (q[1] >= '0' && q[1] <= '7') {
2139                                                                                 c = (c * 8) + *++q - '0';
2140                                                                                 if (q[1] >= '0' && q[1] <= '7')
2141                                                                                         c = (c * 8) + *++q - '0';
2142                                                                         }
2143                                                                         *r = c;
2144                                                                 }
2145                                                                 break;
2146
2147                                                         default:
2148                                                                 *r = *q;
2149                                                                 break;
2150                                                 } else
2151                                                         *r = *q;
2152                                         }
2153                                         *r = '\0';
2154                                         ++q;
2155                                 } else {
2156                                         char *r;
2157
2158                                         /* In this case, the string is not quoted. We will break
2159                                            it using the coma (like for ints). If the user wants to
2160                                            include comas in a string, he just has to quote it */
2161
2162                                         /* Search the next coma */
2163                                         r = strchr(q, ',');
2164
2165                                         /* Found ? */
2166                                         if (r != (char *) NULL) {
2167                                                 /* Recopy the current field */
2168                                                 str = alloca(r - q + 1);
2169                                                 memcpy(str, q, r - q);
2170
2171                                                 /* I don't know if it is usefull, as the previous case
2172                                                    doesn't null terminate the string ??? */
2173                                                 str[r - q] = '\0';
2174
2175                                                 /* Keep next fields */
2176                                                 q = r;
2177                                         } else {
2178                                                 /* last string */
2179                                                 str = q;
2180                                                 q = "";
2181                                         }
2182                                 }
2183
2184                                 if (*p == 's') {
2185                                         /* Normal string */
2186                                         obj_string_patch(f, sym->secidx, loc - contents, str);
2187                                         loc += tgt_sizeof_char_p;
2188                                 } else {
2189                                         /* Array of chars (in fact, matrix !) */
2190                                         unsigned long charssize;        /* size of each member */
2191
2192                                         /* Get the size of each member */
2193                                         /* Probably we should do that outside the loop ? */
2194                                         if (!isdigit(*(p + 1))) {
2195                                                 error_msg("parameter type 'c' for %s must be followed by"
2196                                                                 " the maximum size", key);
2197                                                 return 0;
2198                                         }
2199                                         charssize = strtoul(p + 1, (char **) NULL, 10);
2200
2201                                         /* Check length */
2202                                         if (strlen(str) >= charssize) {
2203                                                 error_msg("string too long for %s (max %ld)", key,
2204                                                                 charssize - 1);
2205                                                 return 0;
2206                                         }
2207
2208                                         /* Copy to location */
2209                                         strcpy((char *) loc, str);
2210                                         loc += charssize;
2211                                 }
2212                         } else {
2213                                 long v = strtoul(q, &q, 0);
2214                                 switch (*p) {
2215                                 case 'b':
2216                                         *loc++ = v;
2217                                         break;
2218                                 case 'h':
2219                                         *(short *) loc = v;
2220                                         loc += tgt_sizeof_short;
2221                                         break;
2222                                 case 'i':
2223                                         *(int *) loc = v;
2224                                         loc += tgt_sizeof_int;
2225                                         break;
2226                                 case 'l':
2227                                         *(long *) loc = v;
2228                                         loc += tgt_sizeof_long;
2229                                         break;
2230
2231                                 default:
2232                                         error_msg("unknown parameter type '%c' for %s", *p, key);
2233                                         return 0;
2234                                 }
2235                         }
2236
2237                   retry_end_of_value:
2238                         switch (*q) {
2239                         case '\0':
2240                                 goto end_of_arg;
2241
2242                         case ' ':
2243                         case '\t':
2244                         case '\n':
2245                         case '\r':
2246                                 ++q;
2247                                 goto retry_end_of_value;
2248
2249                         case ',':
2250                                 if (++n > max) {
2251                                         error_msg("too many values for %s (max %d)", key, max);
2252                                         return 0;
2253                                 }
2254                                 ++q;
2255                                 break;
2256
2257                         default:
2258                                 error_msg("invalid argument syntax for %s", key);
2259                                 return 0;
2260                         }
2261                 }
2262
2263           end_of_arg:
2264                 if (n < min) {
2265                         error_msg("too few values for %s (min %d)", key, min);
2266                         return 0;
2267                 }
2268
2269                 argc--, argv++;
2270         }
2271
2272         return 1;
2273 }
2274
2275 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2276 static int new_is_module_checksummed(struct obj_file *f)
2277 {
2278         const char *p = get_modinfo_value(f, "using_checksums");
2279         if (p)
2280                 return atoi(p);
2281         else
2282                 return 0;
2283 }
2284
2285 /* Get the module's kernel version in the canonical integer form.  */
2286
2287 static int
2288 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2289 {
2290         char *p, *q;
2291         int a, b, c;
2292
2293         p = get_modinfo_value(f, "kernel_version");
2294         if (p == NULL)
2295                 return -1;
2296         strncpy(str, p, STRVERSIONLEN);
2297
2298         a = strtoul(p, &p, 10);
2299         if (*p != '.')
2300                 return -1;
2301         b = strtoul(p + 1, &p, 10);
2302         if (*p != '.')
2303                 return -1;
2304         c = strtoul(p + 1, &q, 10);
2305         if (p + 1 == q)
2306                 return -1;
2307
2308         return a << 16 | b << 8 | c;
2309 }
2310
2311 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2312
2313
2314 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
2315
2316 /* Fetch the loaded modules, and all currently exported symbols.  */
2317
2318 static int new_get_kernel_symbols(void)
2319 {
2320         char *module_names, *mn;
2321         struct external_module *modules, *m;
2322         struct new_module_symbol *syms, *s;
2323         size_t ret, bufsize, nmod, nsyms, i, j;
2324
2325         /* Collect the loaded modules.  */
2326
2327         module_names = xmalloc(bufsize = 256);
2328   retry_modules_load:
2329         if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2330                 if (errno == ENOSPC && bufsize < ret) {
2331                         module_names = xrealloc(module_names, bufsize = ret);
2332                         goto retry_modules_load;
2333                 }
2334                 perror_msg("QM_MODULES");
2335                 return 0;
2336         }
2337
2338         n_ext_modules = nmod = ret;
2339
2340         /* Collect the modules' symbols.  */
2341
2342         if (nmod){
2343                 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2344                 memset(modules, 0, nmod * sizeof(*modules));
2345                 for (i = 0, mn = module_names, m = modules;
2346                          i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2347                         struct new_module_info info;
2348         
2349                         if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2350                                 if (errno == ENOENT) {
2351                                         /* The module was removed out from underneath us.  */
2352                                         continue;
2353                                 }
2354                                 perror_msg("query_module: QM_INFO: %s", mn);
2355                                 return 0;
2356                         }
2357         
2358                         syms = xmalloc(bufsize = 1024);
2359                   retry_mod_sym_load:
2360                         if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2361                                 switch (errno) {
2362                                 case ENOSPC:
2363                                         syms = xrealloc(syms, bufsize = ret);
2364                                         goto retry_mod_sym_load;
2365                                 case ENOENT:
2366                                         /* The module was removed out from underneath us.  */
2367                                         continue;
2368                                 default:
2369                                         perror_msg("query_module: QM_SYMBOLS: %s", mn);
2370                                         return 0;
2371                                 }
2372                         }
2373                         nsyms = ret;
2374         
2375                         m->name = mn;
2376                         m->addr = info.addr;
2377                         m->nsyms = nsyms;
2378                         m->syms = syms;
2379         
2380                         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2381                                 s->name += (unsigned long) syms;
2382                         }
2383                 }
2384         }
2385
2386         /* Collect the kernel's symbols.  */
2387
2388         syms = xmalloc(bufsize = 16 * 1024);
2389   retry_kern_sym_load:
2390         if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2391                 if (errno == ENOSPC && bufsize < ret) {
2392                         syms = xrealloc(syms, bufsize = ret);
2393                         goto retry_kern_sym_load;
2394                 }
2395                 perror_msg("kernel: QM_SYMBOLS");
2396                 return 0;
2397         }
2398         nksyms = nsyms = ret;
2399         ksyms = syms;
2400
2401         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2402                 s->name += (unsigned long) syms;
2403         }
2404         return 1;
2405 }
2406
2407
2408 /* Return the kernel symbol checksum version, or zero if not used.  */
2409
2410 static int new_is_kernel_checksummed(void)
2411 {
2412         struct new_module_symbol *s;
2413         size_t i;
2414
2415         /* Using_Versions is not the first symbol, but it should be in there.  */
2416
2417         for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2418                 if (strcmp((char *) s->name, "Using_Versions") == 0)
2419                         return s->value;
2420
2421         return 0;
2422 }
2423
2424
2425 static int new_create_this_module(struct obj_file *f, const char *m_name)
2426 {
2427         struct obj_section *sec;
2428
2429         sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2430                                                                                    sizeof(struct new_module));
2431         memset(sec->contents, 0, sizeof(struct new_module));
2432
2433         obj_add_symbol(f, "__this_module", -1,
2434                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2435                                    sizeof(struct new_module));
2436
2437         obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2438                                          m_name);
2439
2440         return 1;
2441 }
2442
2443
2444 static int new_create_module_ksymtab(struct obj_file *f)
2445 {
2446         struct obj_section *sec;
2447         int i;
2448
2449         /* We must always add the module references.  */
2450
2451         if (n_ext_modules_used) {
2452                 struct new_module_ref *dep;
2453                 struct obj_symbol *tm;
2454
2455                 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2456                                                                                  (sizeof(struct new_module_ref)
2457                                                                                   * n_ext_modules_used));
2458                 if (!sec)
2459                         return 0;
2460
2461                 tm = obj_find_symbol(f, "__this_module");
2462                 dep = (struct new_module_ref *) sec->contents;
2463                 for (i = 0; i < n_ext_modules; ++i)
2464                         if (ext_modules[i].used) {
2465                                 dep->dep = ext_modules[i].addr;
2466                                 obj_symbol_patch(f, sec->idx,
2467                                                                  (char *) &dep->ref - sec->contents, tm);
2468                                 dep->next_ref = 0;
2469                                 ++dep;
2470                         }
2471         }
2472
2473         if (flag_export && !obj_find_section(f, "__ksymtab")) {
2474                 size_t nsyms;
2475                 int *loaded;
2476
2477                 sec =
2478                         obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2479                                                                            0);
2480
2481                 /* We don't want to export symbols residing in sections that
2482                    aren't loaded.  There are a number of these created so that
2483                    we make sure certain module options don't appear twice.  */
2484
2485                 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2486                 while (--i >= 0)
2487                         loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2488
2489                 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2490                         struct obj_symbol *sym;
2491                         for (sym = f->symtab[i]; sym; sym = sym->next)
2492                                 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2493                                         && sym->secidx <= SHN_HIRESERVE
2494                                         && (sym->secidx >= SHN_LORESERVE
2495                                                 || loaded[sym->secidx])) {
2496                                         ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2497
2498                                         obj_symbol_patch(f, sec->idx, ofs, sym);
2499                                         obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2500                                                                          sym->name);
2501
2502                                         nsyms++;
2503                                 }
2504                 }
2505
2506                 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2507         }
2508
2509         return 1;
2510 }
2511
2512
2513 static int
2514 new_init_module(const char *m_name, struct obj_file *f,
2515                                 unsigned long m_size)
2516 {
2517         struct new_module *module;
2518         struct obj_section *sec;
2519         void *image;
2520         int ret;
2521         tgt_long m_addr;
2522
2523         sec = obj_find_section(f, ".this");
2524         if (!sec || !sec->contents) { 
2525                 perror_msg_and_die("corrupt module %s?",m_name);
2526         }
2527         module = (struct new_module *) sec->contents;
2528         m_addr = sec->header.sh_addr;
2529
2530         module->size_of_struct = sizeof(*module);
2531         module->size = m_size;
2532         module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2533
2534         sec = obj_find_section(f, "__ksymtab");
2535         if (sec && sec->header.sh_size) {
2536                 module->syms = sec->header.sh_addr;
2537                 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2538         }
2539
2540         if (n_ext_modules_used) {
2541                 sec = obj_find_section(f, ".kmodtab");
2542                 module->deps = sec->header.sh_addr;
2543                 module->ndeps = n_ext_modules_used;
2544         }
2545
2546         module->init =
2547                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2548         module->cleanup =
2549                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2550
2551         sec = obj_find_section(f, "__ex_table");
2552         if (sec) {
2553                 module->ex_table_start = sec->header.sh_addr;
2554                 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2555         }
2556
2557         sec = obj_find_section(f, ".text.init");
2558         if (sec) {
2559                 module->runsize = sec->header.sh_addr - m_addr;
2560         }
2561         sec = obj_find_section(f, ".data.init");
2562         if (sec) {
2563                 if (!module->runsize ||
2564                         module->runsize > sec->header.sh_addr - m_addr)
2565                                 module->runsize = sec->header.sh_addr - m_addr;
2566         }
2567         sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2568         if (sec && sec->header.sh_size) {
2569                 module->archdata_start = (void*)sec->header.sh_addr;
2570                 module->archdata_end = module->archdata_start + sec->header.sh_size;
2571         }
2572         sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2573         if (sec && sec->header.sh_size) {
2574                 module->kallsyms_start = (void*)sec->header.sh_addr;
2575                 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2576         }
2577
2578         if (!arch_init_module(f, module))
2579                 return 0;
2580
2581         /* Whew!  All of the initialization is complete.  Collect the final
2582            module image and give it to the kernel.  */
2583
2584         image = xmalloc(m_size);
2585         obj_create_image(f, image);
2586
2587         ret = new_sys_init_module(m_name, (struct new_module *) image);
2588         if (ret)
2589                 perror_msg("init_module: %s", m_name);
2590
2591         free(image);
2592
2593         return ret == 0;
2594 }
2595
2596 #else
2597
2598 #define new_init_module(x, y, z) TRUE
2599 #define new_create_this_module(x, y) 0
2600 #define new_create_module_ksymtab(x)
2601 #define query_module(v, w, x, y, z) -1
2602
2603 #endif                                                  /* BB_FEATURE_NEW_MODULE_INTERFACE */
2604
2605
2606 /*======================================================================*/
2607
2608 static int
2609 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2610                                  const char *string)
2611 {
2612         struct obj_string_patch *p;
2613         struct obj_section *strsec;
2614         size_t len = strlen(string) + 1;
2615         char *loc;
2616
2617         p = xmalloc(sizeof(*p));
2618         p->next = f->string_patches;
2619         p->reloc_secidx = secidx;
2620         p->reloc_offset = offset;
2621         f->string_patches = p;
2622
2623         strsec = obj_find_section(f, ".kstrtab");
2624         if (strsec == NULL) {
2625                 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2626                 p->string_offset = 0;
2627                 loc = strsec->contents;
2628         } else {
2629                 p->string_offset = strsec->header.sh_size;
2630                 loc = obj_extend_section(strsec, len);
2631         }
2632         memcpy(loc, string, len);
2633
2634         return 1;
2635 }
2636
2637 static int
2638 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2639                                  struct obj_symbol *sym)
2640 {
2641         struct obj_symbol_patch *p;
2642
2643         p = xmalloc(sizeof(*p));
2644         p->next = f->symbol_patches;
2645         p->reloc_secidx = secidx;
2646         p->reloc_offset = offset;
2647         p->sym = sym;
2648         f->symbol_patches = p;
2649
2650         return 1;
2651 }
2652
2653 static int obj_check_undefineds(struct obj_file *f)
2654 {
2655         unsigned long i;
2656         int ret = 1;
2657
2658         for (i = 0; i < HASH_BUCKETS; ++i) {
2659                 struct obj_symbol *sym;
2660                 for (sym = f->symtab[i]; sym; sym = sym->next)
2661                         if (sym->secidx == SHN_UNDEF) {
2662                                 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2663                                         sym->secidx = SHN_ABS;
2664                                         sym->value = 0;
2665                                 } else {
2666                                         error_msg("unresolved symbol %s", sym->name);
2667                                         ret = 0;
2668                                 }
2669                         }
2670         }
2671
2672         return ret;
2673 }
2674
2675 static void obj_allocate_commons(struct obj_file *f)
2676 {
2677         struct common_entry {
2678                 struct common_entry *next;
2679                 struct obj_symbol *sym;
2680         } *common_head = NULL;
2681
2682         unsigned long i;
2683
2684         for (i = 0; i < HASH_BUCKETS; ++i) {
2685                 struct obj_symbol *sym;
2686                 for (sym = f->symtab[i]; sym; sym = sym->next)
2687                         if (sym->secidx == SHN_COMMON) {
2688                                 /* Collect all COMMON symbols and sort them by size so as to
2689                                    minimize space wasted by alignment requirements.  */
2690                                 {
2691                                         struct common_entry **p, *n;
2692                                         for (p = &common_head; *p; p = &(*p)->next)
2693                                                 if (sym->size <= (*p)->sym->size)
2694                                                         break;
2695
2696                                         n = alloca(sizeof(*n));
2697                                         n->next = *p;
2698                                         n->sym = sym;
2699                                         *p = n;
2700                                 }
2701                         }
2702         }
2703
2704         for (i = 1; i < f->local_symtab_size; ++i) {
2705                 struct obj_symbol *sym = f->local_symtab[i];
2706                 if (sym && sym->secidx == SHN_COMMON) {
2707                         struct common_entry **p, *n;
2708                         for (p = &common_head; *p; p = &(*p)->next)
2709                                 if (sym == (*p)->sym)
2710                                         break;
2711                                 else if (sym->size < (*p)->sym->size) {
2712                                         n = alloca(sizeof(*n));
2713                                         n->next = *p;
2714                                         n->sym = sym;
2715                                         *p = n;
2716                                         break;
2717                                 }
2718                 }
2719         }
2720
2721         if (common_head) {
2722                 /* Find the bss section.  */
2723                 for (i = 0; i < f->header.e_shnum; ++i)
2724                         if (f->sections[i]->header.sh_type == SHT_NOBITS)
2725                                 break;
2726
2727                 /* If for some reason there hadn't been one, create one.  */
2728                 if (i == f->header.e_shnum) {
2729                         struct obj_section *sec;
2730
2731                         f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2732                         f->sections[i] = sec = arch_new_section();
2733                         f->header.e_shnum = i + 1;
2734
2735                         memset(sec, 0, sizeof(*sec));
2736                         sec->header.sh_type = SHT_PROGBITS;
2737                         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2738                         sec->name = ".bss";
2739                         sec->idx = i;
2740                 }
2741
2742                 /* Allocate the COMMONS.  */
2743                 {
2744                         ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2745                         ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2746                         struct common_entry *c;
2747
2748                         for (c = common_head; c; c = c->next) {
2749                                 ElfW(Addr) align = c->sym->value;
2750
2751                                 if (align > max_align)
2752                                         max_align = align;
2753                                 if (bss_size & (align - 1))
2754                                         bss_size = (bss_size | (align - 1)) + 1;
2755
2756                                 c->sym->secidx = i;
2757                                 c->sym->value = bss_size;
2758
2759                                 bss_size += c->sym->size;
2760                         }
2761
2762                         f->sections[i]->header.sh_size = bss_size;
2763                         f->sections[i]->header.sh_addralign = max_align;
2764                 }
2765         }
2766
2767         /* For the sake of patch relocation and parameter initialization,
2768            allocate zeroed data for NOBITS sections now.  Note that after
2769            this we cannot assume NOBITS are really empty.  */
2770         for (i = 0; i < f->header.e_shnum; ++i) {
2771                 struct obj_section *s = f->sections[i];
2772                 if (s->header.sh_type == SHT_NOBITS) {
2773                         if (s->header.sh_size != 0)
2774                         s->contents = memset(xmalloc(s->header.sh_size),
2775                                                                  0, s->header.sh_size);
2776                         else
2777                                 s->contents = NULL;
2778
2779                         s->header.sh_type = SHT_PROGBITS;
2780                 }
2781         }
2782 }
2783
2784 static unsigned long obj_load_size(struct obj_file *f)
2785 {
2786         unsigned long dot = 0;
2787         struct obj_section *sec;
2788
2789         /* Finalize the positions of the sections relative to one another.  */
2790
2791         for (sec = f->load_order; sec; sec = sec->load_next) {
2792                 ElfW(Addr) align;
2793
2794                 align = sec->header.sh_addralign;
2795                 if (align && (dot & (align - 1)))
2796                         dot = (dot | (align - 1)) + 1;
2797
2798                 sec->header.sh_addr = dot;
2799                 dot += sec->header.sh_size;
2800         }
2801
2802         return dot;
2803 }
2804
2805 static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2806 {
2807         int i, n = f->header.e_shnum;
2808         int ret = 1;
2809
2810         /* Finalize the addresses of the sections.  */
2811
2812         f->baseaddr = base;
2813         for (i = 0; i < n; ++i)
2814                 f->sections[i]->header.sh_addr += base;
2815
2816         /* And iterate over all of the relocations.  */
2817
2818         for (i = 0; i < n; ++i) {
2819                 struct obj_section *relsec, *symsec, *targsec, *strsec;
2820                 ElfW(RelM) * rel, *relend;
2821                 ElfW(Sym) * symtab;
2822                 const char *strtab;
2823
2824                 relsec = f->sections[i];
2825                 if (relsec->header.sh_type != SHT_RELM)
2826                         continue;
2827
2828                 symsec = f->sections[relsec->header.sh_link];
2829                 targsec = f->sections[relsec->header.sh_info];
2830                 strsec = f->sections[symsec->header.sh_link];
2831
2832                 rel = (ElfW(RelM) *) relsec->contents;
2833                 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2834                 symtab = (ElfW(Sym) *) symsec->contents;
2835                 strtab = (const char *) strsec->contents;
2836
2837                 for (; rel < relend; ++rel) {
2838                         ElfW(Addr) value = 0;
2839                         struct obj_symbol *intsym = NULL;
2840                         unsigned long symndx;
2841                         ElfW(Sym) * extsym = 0;
2842                         const char *errmsg;
2843
2844                         /* Attempt to find a value to use for this relocation.  */
2845
2846                         symndx = ELFW(R_SYM) (rel->r_info);
2847                         if (symndx) {
2848                                 /* Note we've already checked for undefined symbols.  */
2849
2850                                 extsym = &symtab[symndx];
2851                                 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2852                                         /* Local symbols we look up in the local table to be sure
2853                                            we get the one that is really intended.  */
2854                                         intsym = f->local_symtab[symndx];
2855                                 } else {
2856                                         /* Others we look up in the hash table.  */
2857                                         const char *name;
2858                                         if (extsym->st_name)
2859                                                 name = strtab + extsym->st_name;
2860                                         else
2861                                                 name = f->sections[extsym->st_shndx]->name;
2862                                         intsym = obj_find_symbol(f, name);
2863                                 }
2864
2865                                 value = obj_symbol_final_value(f, intsym);
2866                                 intsym->referenced = 1;
2867                         }
2868 #if SHT_RELM == SHT_RELA
2869 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2870                         /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9.  */
2871                         if (!extsym || !extsym->st_name ||
2872                                 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2873 #endif
2874                                 value += rel->r_addend;
2875 #endif
2876
2877                         /* Do it! */
2878                         switch (arch_apply_relocation
2879                                         (f, targsec, symsec, intsym, rel, value)) {
2880                         case obj_reloc_ok:
2881                                 break;
2882
2883                         case obj_reloc_overflow:
2884                                 errmsg = "Relocation overflow";
2885                                 goto bad_reloc;
2886                         case obj_reloc_dangerous:
2887                                 errmsg = "Dangerous relocation";
2888                                 goto bad_reloc;
2889                         case obj_reloc_unhandled:
2890                                 errmsg = "Unhandled relocation";
2891                           bad_reloc:
2892                                 if (extsym) {
2893                                         error_msg("%s of type %ld for %s", errmsg,
2894                                                         (long) ELFW(R_TYPE) (rel->r_info),
2895                                                         strtab + extsym->st_name);
2896                                 } else {
2897                                         error_msg("%s of type %ld", errmsg,
2898                                                         (long) ELFW(R_TYPE) (rel->r_info));
2899                                 }
2900                                 ret = 0;
2901                                 break;
2902                         }
2903                 }
2904         }
2905
2906         /* Finally, take care of the patches.  */
2907
2908         if (f->string_patches) {
2909                 struct obj_string_patch *p;
2910                 struct obj_section *strsec;
2911                 ElfW(Addr) strsec_base;
2912                 strsec = obj_find_section(f, ".kstrtab");
2913                 strsec_base = strsec->header.sh_addr;
2914
2915                 for (p = f->string_patches; p; p = p->next) {
2916                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2917                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2918                                 = strsec_base + p->string_offset;
2919                 }
2920         }
2921
2922         if (f->symbol_patches) {
2923                 struct obj_symbol_patch *p;
2924
2925                 for (p = f->symbol_patches; p; p = p->next) {
2926                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2927                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2928                                 = obj_symbol_final_value(f, p->sym);
2929                 }
2930         }
2931
2932         return ret;
2933 }
2934
2935 static int obj_create_image(struct obj_file *f, char *image)
2936 {
2937         struct obj_section *sec;
2938         ElfW(Addr) base = f->baseaddr;
2939
2940         for (sec = f->load_order; sec; sec = sec->load_next) {
2941                 char *secimg;
2942
2943                 if (sec->contents == 0 || sec->header.sh_size == 0)
2944                         continue;
2945
2946                 secimg = image + (sec->header.sh_addr - base);
2947
2948                 /* Note that we allocated data for NOBITS sections earlier.  */
2949                 memcpy(secimg, sec->contents, sec->header.sh_size);
2950         }
2951
2952         return 1;
2953 }
2954
2955 /*======================================================================*/
2956
2957 static struct obj_file *obj_load(FILE * fp, int loadprogbits)
2958 {
2959         struct obj_file *f;
2960         ElfW(Shdr) * section_headers;
2961         int shnum, i;
2962         char *shstrtab;
2963
2964         /* Read the file header.  */
2965
2966         f = arch_new_file();
2967         memset(f, 0, sizeof(*f));
2968         f->symbol_cmp = strcmp;
2969         f->symbol_hash = obj_elf_hash;
2970         f->load_order_search_start = &f->load_order;
2971
2972         fseek(fp, 0, SEEK_SET);
2973         if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2974                 perror_msg("error reading ELF header");
2975                 return NULL;
2976         }
2977
2978         if (f->header.e_ident[EI_MAG0] != ELFMAG0
2979                 || f->header.e_ident[EI_MAG1] != ELFMAG1
2980                 || f->header.e_ident[EI_MAG2] != ELFMAG2
2981                 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2982                 error_msg("not an ELF file");
2983                 return NULL;
2984         }
2985         if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2986                 || f->header.e_ident[EI_DATA] != ELFDATAM
2987                 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2988                 || !MATCH_MACHINE(f->header.e_machine)) {
2989                 error_msg("ELF file not for this architecture");
2990                 return NULL;
2991         }
2992         if (f->header.e_type != ET_REL) {
2993                 error_msg("ELF file not a relocatable object");
2994                 return NULL;
2995         }
2996
2997         /* Read the section headers.  */
2998
2999         if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3000                 error_msg("section header size mismatch: %lu != %lu",
3001                                 (unsigned long) f->header.e_shentsize,
3002                                 (unsigned long) sizeof(ElfW(Shdr)));
3003                 return NULL;
3004         }
3005
3006         shnum = f->header.e_shnum;
3007         f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3008         memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3009
3010         section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3011         fseek(fp, f->header.e_shoff, SEEK_SET);
3012         if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
3013                 perror_msg("error reading ELF section headers");
3014                 return NULL;
3015         }
3016
3017         /* Read the section data.  */
3018
3019         for (i = 0; i < shnum; ++i) {
3020                 struct obj_section *sec;
3021
3022                 f->sections[i] = sec = arch_new_section();
3023                 memset(sec, 0, sizeof(*sec));
3024
3025                 sec->header = section_headers[i];
3026                 sec->idx = i;
3027
3028                 if(sec->header.sh_size) switch (sec->header.sh_type) {
3029                 case SHT_NULL:
3030                 case SHT_NOTE:
3031                 case SHT_NOBITS:
3032                         /* ignore */
3033                         break;
3034
3035                 case SHT_PROGBITS:
3036 #if LOADBITS
3037                         if (!loadprogbits) {
3038                                 sec->contents = NULL;
3039                                 break;
3040                         }
3041 #endif                  
3042                 case SHT_SYMTAB:
3043                 case SHT_STRTAB:
3044                 case SHT_RELM:
3045                         if (sec->header.sh_size > 0) {
3046                                 sec->contents = xmalloc(sec->header.sh_size);
3047                                 fseek(fp, sec->header.sh_offset, SEEK_SET);
3048                                 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3049                                         perror_msg("error reading ELF section data");
3050                                         return NULL;
3051                                 }
3052                         } else {
3053                                 sec->contents = NULL;
3054                         }
3055                         break;
3056
3057 #if SHT_RELM == SHT_REL
3058                 case SHT_RELA:
3059                         error_msg("RELA relocations not supported on this architecture");
3060                         return NULL;
3061 #else
3062                 case SHT_REL:
3063                         error_msg("REL relocations not supported on this architecture");
3064                         return NULL;
3065 #endif
3066
3067                 default:
3068                         if (sec->header.sh_type >= SHT_LOPROC) {
3069                                 /* Assume processor specific section types are debug
3070                                    info and can safely be ignored.  If this is ever not
3071                                    the case (Hello MIPS?), don't put ifdefs here but
3072                                    create an arch_load_proc_section().  */
3073                                 break;
3074                         }
3075
3076                         error_msg("can't handle sections of type %ld",
3077                                         (long) sec->header.sh_type);
3078                         return NULL;
3079                 }
3080         }
3081
3082         /* Do what sort of interpretation as needed by each section.  */
3083
3084         shstrtab = f->sections[f->header.e_shstrndx]->contents;
3085
3086         for (i = 0; i < shnum; ++i) {
3087                 struct obj_section *sec = f->sections[i];
3088                 sec->name = shstrtab + sec->header.sh_name;
3089         }
3090
3091         for (i = 0; i < shnum; ++i) {
3092                 struct obj_section *sec = f->sections[i];
3093
3094                 /* .modinfo should be contents only but gcc has no attribute for that.
3095                  * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3096                  */
3097                 if (strcmp(sec->name, ".modinfo") == 0)
3098                         sec->header.sh_flags &= ~SHF_ALLOC;
3099
3100                 if (sec->header.sh_flags & SHF_ALLOC)
3101                         obj_insert_section_load_order(f, sec);
3102
3103                 switch (sec->header.sh_type) {
3104                 case SHT_SYMTAB:
3105                         {
3106                                 unsigned long nsym, j;
3107                                 char *strtab;
3108                                 ElfW(Sym) * sym;
3109
3110                                 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3111                                         error_msg("symbol size mismatch: %lu != %lu",
3112                                                         (unsigned long) sec->header.sh_entsize,
3113                                                         (unsigned long) sizeof(ElfW(Sym)));
3114                                         return NULL;
3115                                 }
3116
3117                                 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3118                                 strtab = f->sections[sec->header.sh_link]->contents;
3119                                 sym = (ElfW(Sym) *) sec->contents;
3120
3121                                 /* Allocate space for a table of local symbols.  */
3122                                 j = f->local_symtab_size = sec->header.sh_info;
3123                                 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
3124
3125                                 /* Insert all symbols into the hash table.  */
3126                                 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3127                                         const char *name;
3128                                         if (sym->st_name)
3129                                                 name = strtab + sym->st_name;
3130                                         else
3131                                                 name = f->sections[sym->st_shndx]->name;
3132
3133                                         obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3134                                                                    sym->st_value, sym->st_size);
3135                                 }
3136                         }
3137                         break;
3138
3139                 case SHT_RELM:
3140                         if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3141                                 error_msg("relocation entry size mismatch: %lu != %lu",
3142                                                 (unsigned long) sec->header.sh_entsize,
3143                                                 (unsigned long) sizeof(ElfW(RelM)));
3144                                 return NULL;
3145                         }
3146                         break;
3147                         /* XXX  Relocation code from modutils-2.3.19 is not here.
3148                          * Why?  That's about 20 lines of code from obj/obj_load.c,
3149                          * which gets done in a second pass through the sections.
3150                          * This BusyBox insmod does similar work in obj_relocate(). */
3151                 }
3152         }
3153
3154         return f;
3155 }
3156
3157 #ifdef BB_FEATURE_INSMOD_LOADINKMEM
3158 /*
3159  * load the unloaded sections directly into the memory allocated by
3160  * kernel for the module
3161  */
3162
3163 static int obj_load_progbits(FILE * fp, struct obj_file* f)
3164 {
3165         char* imagebase = (char*) f->imagebase;
3166         ElfW(Addr) base = f->baseaddr;
3167         struct obj_section* sec;
3168         
3169         for (sec = f->load_order; sec; sec = sec->load_next) {
3170
3171                 /* section already loaded? */
3172                 if (sec->contents != NULL)
3173                         continue;
3174                 
3175                 if (sec->header.sh_size == 0)
3176                         continue;
3177
3178                 sec->contents = imagebase + (sec->header.sh_addr - base);
3179                 fseek(fp, sec->header.sh_offset, SEEK_SET);
3180                 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3181                         errorMsg("error reading ELF section data: %s\n", strerror(errno));
3182                         return 0;
3183                 }
3184
3185         }
3186         return 1;
3187 }
3188 #endif
3189
3190 static void hide_special_symbols(struct obj_file *f)
3191 {
3192         static const char *const specials[] = {
3193                 "cleanup_module",
3194                 "init_module",
3195                 "kernel_version",
3196                 NULL
3197         };
3198
3199         struct obj_symbol *sym;
3200         const char *const *p;
3201
3202         for (p = specials; *p; ++p)
3203                 if ((sym = obj_find_symbol(f, *p)) != NULL)
3204                         sym->info =
3205                                 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3206 }
3207
3208
3209
3210 extern int insmod_main( int argc, char **argv)
3211 {
3212         int opt;
3213         int k_crcs;
3214         int k_new_syscalls;
3215         int len;
3216         char *tmp;
3217         unsigned long m_size;
3218         ElfW(Addr) m_addr;
3219         FILE *fp;
3220         struct obj_file *f;
3221         struct stat st;
3222         char m_name[FILENAME_MAX + 1] = "\0";
3223         int exit_status = EXIT_FAILURE;
3224         int m_has_modinfo;
3225 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3226         struct utsname uts_info;
3227         char m_strversion[STRVERSIONLEN];
3228         int m_version;
3229         int m_crcs;
3230 #endif
3231
3232         /* Parse any options */
3233         while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
3234                 switch (opt) {
3235                         case 'f':                       /* force loading */
3236                                 flag_force_load = 1;
3237                                 break;
3238                         case 'k':                       /* module loaded by kerneld, auto-cleanable */
3239                                 flag_autoclean = 1;
3240                                 break;
3241                         case 'v':                       /* verbose output */
3242                                 flag_verbose = 1;
3243                                 break;
3244                         case 'x':                       /* do not export externs */
3245                                 flag_export = 0;
3246                                 break;
3247                         case 'o':                       /* name the output module */
3248                                 strncpy(m_name, optarg, FILENAME_MAX);
3249                                 break;
3250                         case 'L':                       /* Stub warning */
3251                                 /* This is needed for compatibility with modprobe.
3252                                  * In theory, this does locking, but we don't do
3253                                  * that.  So be careful and plan your life around not
3254                                  * loading the same module 50 times concurrently. */
3255                                 break;
3256                         default:
3257                                 show_usage();
3258                 }
3259         }
3260         
3261         if (argv[optind] == NULL) {
3262                 show_usage();
3263         }
3264
3265         /* Grab the module name */
3266         if ((tmp = strrchr(argv[optind], '/')) != NULL) {
3267                 tmp++;
3268         } else {
3269                 tmp = argv[optind];
3270         }
3271         len = strlen(tmp);
3272
3273         if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3274                 len -= 2;
3275         memcpy(m_fullName, tmp, len);
3276         m_fullName[len]='\0';
3277         if (*m_name == '\0') {
3278                 strcpy(m_name, m_fullName);
3279         }
3280         strcat(m_fullName, ".o");
3281
3282         /* Get a filedesc for the module.  Check we we have a complete path */
3283         if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3284                         (fp = fopen(argv[optind], "r")) == NULL) {
3285                 struct utsname myuname;
3286
3287                 /* Hmm.  Could not open it.  First search under /lib/modules/`uname -r`,
3288                  * but do not error out yet if we fail to find it... */
3289                 if (uname(&myuname) == 0) {
3290                         char module_dir[FILENAME_MAX];
3291                         char real_module_dir[FILENAME_MAX];
3292                         snprintf (module_dir, sizeof(module_dir), "%s/%s", 
3293                                         _PATH_MODULES, myuname.release);
3294                         /* Jump through hoops in case /lib/modules/`uname -r`
3295                          * is a symlink.  We do not want recursive_action to
3296                          * follow symlinks, but we do want to follow the
3297                          * /lib/modules/`uname -r` dir, So resolve it ourselves
3298                          * if it is a link... */
3299                         if (realpath (module_dir, real_module_dir) == NULL)
3300                                 strcpy(real_module_dir, module_dir);
3301                         recursive_action(real_module_dir, TRUE, FALSE, FALSE,
3302                                         check_module_name_match, 0, m_fullName);
3303                 }
3304
3305                 /* Check if we have found anything yet */
3306                 if (m_filename[0] == '\0' || ((fp = fopen(m_filename, "r")) == NULL)) 
3307                 {
3308                         char module_dir[FILENAME_MAX];
3309                         if (realpath (_PATH_MODULES, module_dir) == NULL)
3310                                 strcpy(module_dir, _PATH_MODULES);
3311                         /* No module found under /lib/modules/`uname -r`, this
3312                          * time cast the net a bit wider.  Search /lib/modules/ */
3313                         if (recursive_action(module_dir, TRUE, FALSE, FALSE,
3314                                                 check_module_name_match, 0, m_fullName) == FALSE) 
3315                         {
3316                                 if (m_filename[0] == '\0'
3317                                                 || ((fp = fopen(m_filename, "r")) == NULL)) 
3318                                 {
3319                                         error_msg("%s: no module by that name found", m_fullName);
3320                                         return EXIT_FAILURE;
3321                                 }
3322                         } else
3323                                 error_msg_and_die("%s: no module by that name found", m_fullName);
3324                 }
3325         } else 
3326                 safe_strncpy(m_filename, argv[optind], sizeof(m_filename));
3327
3328         printf("Using %s\n", m_filename);
3329
3330         if ((f = obj_load(fp, LOADBITS)) == NULL)
3331                 perror_msg_and_die("Could not load the module");
3332
3333         if (get_modinfo_value(f, "kernel_version") == NULL)
3334                 m_has_modinfo = 0;
3335         else
3336                 m_has_modinfo = 1;
3337
3338 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3339         /* Version correspondence?  */
3340
3341         if (uname(&uts_info) < 0)
3342                 uts_info.release[0] = '\0';
3343         if (m_has_modinfo) {
3344                 m_version = new_get_module_version(f, m_strversion);
3345         } else {
3346                 m_version = old_get_module_version(f, m_strversion);
3347                 if (m_version == -1) {
3348                         error_msg("couldn't find the kernel version the module was "
3349                                         "compiled for");
3350                         goto out;
3351                 }
3352         }
3353
3354         if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
3355                 if (flag_force_load) {
3356                         error_msg("Warning: kernel-module version mismatch\n"
3357                                         "\t%s was compiled for kernel version %s\n"
3358                                         "\twhile this kernel is version %s",
3359                                         m_filename, m_strversion, uts_info.release);
3360                 } else {
3361                         error_msg("kernel-module version mismatch\n"
3362                                         "\t%s was compiled for kernel version %s\n"
3363                                         "\twhile this kernel is version %s.",
3364                                         m_filename, m_strversion, uts_info.release);
3365                         goto out;
3366                 }
3367         }
3368         k_crcs = 0;
3369 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3370
3371         k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3372
3373         if (k_new_syscalls) {
3374 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
3375                 if (!new_get_kernel_symbols())
3376                         goto out;
3377                 k_crcs = new_is_kernel_checksummed();
3378 #else
3379                 error_msg("Not configured to support new kernels");
3380                 goto out;
3381 #endif
3382         } else {
3383 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
3384                 if (!old_get_kernel_symbols(m_name))
3385                         goto out;
3386                 k_crcs = old_is_kernel_checksummed();
3387 #else
3388                 error_msg("Not configured to support old kernels");
3389                 goto out;
3390 #endif
3391         }
3392
3393 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3394         if (m_has_modinfo)
3395                 m_crcs = new_is_module_checksummed(f);
3396         else
3397                 m_crcs = old_is_module_checksummed(f);
3398
3399         if (m_crcs != k_crcs)
3400                 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3401 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3402
3403         /* Let the module know about the kernel symbols.  */
3404         add_kernel_symbols(f);
3405
3406         /* Allocate common symbols, symbol tables, and string tables.  */
3407
3408         if (k_new_syscalls 
3409                 ? !new_create_this_module(f, m_name)
3410                 : !old_create_mod_use_count(f)) 
3411         {
3412                 goto out;
3413         }
3414
3415         if (!obj_check_undefineds(f)) {
3416                 goto out;
3417         }
3418         obj_allocate_commons(f);
3419
3420         /* done with the module name, on to the optional var=value arguments */
3421         ++optind;
3422
3423         if (optind < argc) {
3424                 if (m_has_modinfo
3425                         ? !new_process_module_arguments(f, argc - optind, argv + optind) 
3426                         : !old_process_module_arguments(f, argc - optind, argv + optind)) 
3427                 {
3428                         goto out;
3429                 }
3430         }
3431
3432         arch_create_got(f);
3433         hide_special_symbols(f);
3434
3435         if (k_new_syscalls)
3436                 new_create_module_ksymtab(f);
3437
3438         /* Find current size of the module */
3439         m_size = obj_load_size(f);
3440
3441
3442         m_addr = create_module(m_name, m_size);
3443         if (m_addr==-1) switch (errno) {
3444         case EEXIST:
3445                 error_msg("A module named %s already exists", m_name);
3446                 goto out;
3447         case ENOMEM:
3448                 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3449                                 m_size);
3450                 goto out;
3451         default:
3452                 perror_msg("create_module: %s", m_name);
3453                 goto out;
3454         }
3455
3456 #if  !LOADBITS
3457         /*
3458          * the PROGBITS section was not loaded by the obj_load
3459          * now we can load them directly into the kernel memory
3460          */
3461         //      f->imagebase = (char*) m_addr;
3462         f->imagebase = (ElfW(Addr)) m_addr;
3463         if (!obj_load_progbits(fp, f)) {
3464                 delete_module(m_name);
3465                 goto out;
3466         }
3467 #endif  
3468
3469         if (!obj_relocate(f, m_addr)) {
3470                 delete_module(m_name);
3471                 goto out;
3472         }
3473
3474         if (k_new_syscalls 
3475                 ? !new_init_module(m_name, f, m_size)
3476                 : !old_init_module(m_name, f, m_size)) 
3477         {
3478                 delete_module(m_name);
3479                 goto out;
3480         }
3481
3482         exit_status = EXIT_SUCCESS;
3483
3484 out:
3485         fclose(fp);
3486         return(exit_status);
3487 }