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