Applied patch from Gennady Feldman to use single-thread instead of forking.
[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.50 2001/02/24 20:01:53 andersen 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.50 2001/02/24 20:01:53 andersen 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         ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2310         memset(modules, 0, nmod * sizeof(*modules));
2311
2312         /* Collect the modules' symbols.  */
2313
2314         for (i = 0, mn = module_names, m = modules;
2315                  i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2316                 struct new_module_info info;
2317
2318                 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2319                         if (errno == ENOENT) {
2320                                 /* The module was removed out from underneath us.  */
2321                                 continue;
2322                         }
2323                         perror_msg("query_module: QM_INFO: %s", mn);
2324                         return 0;
2325                 }
2326
2327                 syms = xmalloc(bufsize = 1024);
2328           retry_mod_sym_load:
2329                 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2330                         switch (errno) {
2331                         case ENOSPC:
2332                                 syms = xrealloc(syms, bufsize = ret);
2333                                 goto retry_mod_sym_load;
2334                         case ENOENT:
2335                                 /* The module was removed out from underneath us.  */
2336                                 continue;
2337                         default:
2338                                 perror_msg("query_module: QM_SYMBOLS: %s", mn);
2339                                 return 0;
2340                         }
2341                 }
2342                 nsyms = ret;
2343
2344                 m->name = mn;
2345                 m->addr = info.addr;
2346                 m->nsyms = nsyms;
2347                 m->syms = syms;
2348
2349                 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2350                         s->name += (unsigned long) syms;
2351                 }
2352         }
2353
2354         /* Collect the kernel's symbols.  */
2355
2356         syms = xmalloc(bufsize = 16 * 1024);
2357   retry_kern_sym_load:
2358         if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2359                 if (errno == ENOSPC) {
2360                         syms = xrealloc(syms, bufsize = ret);
2361                         goto retry_kern_sym_load;
2362                 }
2363                 perror_msg("kernel: QM_SYMBOLS");
2364                 return 0;
2365         }
2366         nksyms = nsyms = ret;
2367         ksyms = syms;
2368
2369         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2370                 s->name += (unsigned long) syms;
2371         }
2372         return 1;
2373 }
2374
2375
2376 /* Return the kernel symbol checksum version, or zero if not used.  */
2377
2378 static int new_is_kernel_checksummed(void)
2379 {
2380         struct new_module_symbol *s;
2381         size_t i;
2382
2383         /* Using_Versions is not the first symbol, but it should be in there.  */
2384
2385         for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2386                 if (strcmp((char *) s->name, "Using_Versions") == 0)
2387                         return s->value;
2388
2389         return 0;
2390 }
2391
2392
2393 static int new_create_this_module(struct obj_file *f, const char *m_name)
2394 {
2395         struct obj_section *sec;
2396
2397         sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2398                                                                                    sizeof(struct new_module));
2399         memset(sec->contents, 0, sizeof(struct new_module));
2400
2401         obj_add_symbol(f, "__this_module", -1,
2402                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2403                                    sizeof(struct new_module));
2404
2405         obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2406                                          m_name);
2407
2408         return 1;
2409 }
2410
2411
2412 static int new_create_module_ksymtab(struct obj_file *f)
2413 {
2414         struct obj_section *sec;
2415         int i;
2416
2417         /* We must always add the module references.  */
2418
2419         if (n_ext_modules_used) {
2420                 struct new_module_ref *dep;
2421                 struct obj_symbol *tm;
2422
2423                 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2424                                                                                  (sizeof(struct new_module_ref)
2425                                                                                   * n_ext_modules_used));
2426                 if (!sec)
2427                         return 0;
2428
2429                 tm = obj_find_symbol(f, "__this_module");
2430                 dep = (struct new_module_ref *) sec->contents;
2431                 for (i = 0; i < n_ext_modules; ++i)
2432                         if (ext_modules[i].used) {
2433                                 dep->dep = ext_modules[i].addr;
2434                                 obj_symbol_patch(f, sec->idx,
2435                                                                  (char *) &dep->ref - sec->contents, tm);
2436                                 dep->next_ref = 0;
2437                                 ++dep;
2438                         }
2439         }
2440
2441         if (flag_export && !obj_find_section(f, "__ksymtab")) {
2442                 size_t nsyms;
2443                 int *loaded;
2444
2445                 sec =
2446                         obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2447                                                                            0);
2448
2449                 /* We don't want to export symbols residing in sections that
2450                    aren't loaded.  There are a number of these created so that
2451                    we make sure certain module options don't appear twice.  */
2452
2453                 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2454                 while (--i >= 0)
2455                         loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2456
2457                 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2458                         struct obj_symbol *sym;
2459                         for (sym = f->symtab[i]; sym; sym = sym->next)
2460                                 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2461                                         && sym->secidx <= SHN_HIRESERVE
2462                                         && (sym->secidx >= SHN_LORESERVE
2463                                                 || loaded[sym->secidx])) {
2464                                         ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2465
2466                                         obj_symbol_patch(f, sec->idx, ofs, sym);
2467                                         obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2468                                                                          sym->name);
2469
2470                                         nsyms++;
2471                                 }
2472                 }
2473
2474                 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2475         }
2476
2477         return 1;
2478 }
2479
2480
2481 static int
2482 new_init_module(const char *m_name, struct obj_file *f,
2483                                 unsigned long m_size)
2484 {
2485         struct new_module *module;
2486         struct obj_section *sec;
2487         void *image;
2488         int ret;
2489         tgt_long m_addr;
2490
2491         sec = obj_find_section(f, ".this");
2492         module = (struct new_module *) sec->contents;
2493         m_addr = sec->header.sh_addr;
2494
2495         module->size_of_struct = sizeof(*module);
2496         module->size = m_size;
2497         module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2498
2499         sec = obj_find_section(f, "__ksymtab");
2500         if (sec && sec->header.sh_size) {
2501                 module->syms = sec->header.sh_addr;
2502                 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2503         }
2504
2505         if (n_ext_modules_used) {
2506                 sec = obj_find_section(f, ".kmodtab");
2507                 module->deps = sec->header.sh_addr;
2508                 module->ndeps = n_ext_modules_used;
2509         }
2510
2511         module->init =
2512                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2513         module->cleanup =
2514                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2515
2516         sec = obj_find_section(f, "__ex_table");
2517         if (sec) {
2518                 module->ex_table_start = sec->header.sh_addr;
2519                 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2520         }
2521
2522         sec = obj_find_section(f, ".text.init");
2523         if (sec) {
2524                 module->runsize = sec->header.sh_addr - m_addr;
2525         }
2526         sec = obj_find_section(f, ".data.init");
2527         if (sec) {
2528                 if (!module->runsize ||
2529                         module->runsize > sec->header.sh_addr - m_addr)
2530                                 module->runsize = sec->header.sh_addr - m_addr;
2531         }
2532
2533         if (!arch_init_module(f, module))
2534                 return 0;
2535
2536         /* Whew!  All of the initialization is complete.  Collect the final
2537            module image and give it to the kernel.  */
2538
2539         image = xmalloc(m_size);
2540         obj_create_image(f, image);
2541
2542         ret = new_sys_init_module(m_name, (struct new_module *) image);
2543         if (ret)
2544                 perror_msg("init_module: %s", m_name);
2545
2546         free(image);
2547
2548         return ret == 0;
2549 }
2550
2551 #else
2552
2553 #define new_init_module(x, y, z) TRUE
2554 #define new_create_this_module(x, y) 0
2555 #define new_create_module_ksymtab(x)
2556 #define query_module(v, w, x, y, z) -1
2557
2558 #endif                                                  /* BB_FEATURE_NEW_MODULE_INTERFACE */
2559
2560
2561 /*======================================================================*/
2562
2563 int
2564 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2565                                  const char *string)
2566 {
2567         struct obj_string_patch *p;
2568         struct obj_section *strsec;
2569         size_t len = strlen(string) + 1;
2570         char *loc;
2571
2572         p = xmalloc(sizeof(*p));
2573         p->next = f->string_patches;
2574         p->reloc_secidx = secidx;
2575         p->reloc_offset = offset;
2576         f->string_patches = p;
2577
2578         strsec = obj_find_section(f, ".kstrtab");
2579         if (strsec == NULL) {
2580                 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2581                 p->string_offset = 0;
2582                 loc = strsec->contents;
2583         } else {
2584                 p->string_offset = strsec->header.sh_size;
2585                 loc = obj_extend_section(strsec, len);
2586         }
2587         memcpy(loc, string, len);
2588
2589         return 1;
2590 }
2591
2592 int
2593 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2594                                  struct obj_symbol *sym)
2595 {
2596         struct obj_symbol_patch *p;
2597
2598         p = xmalloc(sizeof(*p));
2599         p->next = f->symbol_patches;
2600         p->reloc_secidx = secidx;
2601         p->reloc_offset = offset;
2602         p->sym = sym;
2603         f->symbol_patches = p;
2604
2605         return 1;
2606 }
2607
2608 int obj_check_undefineds(struct obj_file *f)
2609 {
2610         unsigned long i;
2611         int ret = 1;
2612
2613         for (i = 0; i < HASH_BUCKETS; ++i) {
2614                 struct obj_symbol *sym;
2615                 for (sym = f->symtab[i]; sym; sym = sym->next)
2616                         if (sym->secidx == SHN_UNDEF) {
2617                                 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2618                                         sym->secidx = SHN_ABS;
2619                                         sym->value = 0;
2620                                 } else {
2621                                         error_msg("unresolved symbol %s", sym->name);
2622                                         ret = 0;
2623                                 }
2624                         }
2625         }
2626
2627         return ret;
2628 }
2629
2630 void obj_allocate_commons(struct obj_file *f)
2631 {
2632         struct common_entry {
2633                 struct common_entry *next;
2634                 struct obj_symbol *sym;
2635         } *common_head = NULL;
2636
2637         unsigned long i;
2638
2639         for (i = 0; i < HASH_BUCKETS; ++i) {
2640                 struct obj_symbol *sym;
2641                 for (sym = f->symtab[i]; sym; sym = sym->next)
2642                         if (sym->secidx == SHN_COMMON) {
2643                                 /* Collect all COMMON symbols and sort them by size so as to
2644                                    minimize space wasted by alignment requirements.  */
2645                                 {
2646                                         struct common_entry **p, *n;
2647                                         for (p = &common_head; *p; p = &(*p)->next)
2648                                                 if (sym->size <= (*p)->sym->size)
2649                                                         break;
2650
2651                                         n = alloca(sizeof(*n));
2652                                         n->next = *p;
2653                                         n->sym = sym;
2654                                         *p = n;
2655                                 }
2656                         }
2657         }
2658
2659         for (i = 1; i < f->local_symtab_size; ++i) {
2660                 struct obj_symbol *sym = f->local_symtab[i];
2661                 if (sym && sym->secidx == SHN_COMMON) {
2662                         struct common_entry **p, *n;
2663                         for (p = &common_head; *p; p = &(*p)->next)
2664                                 if (sym == (*p)->sym)
2665                                         break;
2666                                 else if (sym->size < (*p)->sym->size) {
2667                                         n = alloca(sizeof(*n));
2668                                         n->next = *p;
2669                                         n->sym = sym;
2670                                         *p = n;
2671                                         break;
2672                                 }
2673                 }
2674         }
2675
2676         if (common_head) {
2677                 /* Find the bss section.  */
2678                 for (i = 0; i < f->header.e_shnum; ++i)
2679                         if (f->sections[i]->header.sh_type == SHT_NOBITS)
2680                                 break;
2681
2682                 /* If for some reason there hadn't been one, create one.  */
2683                 if (i == f->header.e_shnum) {
2684                         struct obj_section *sec;
2685
2686                         f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2687                         f->sections[i] = sec = arch_new_section();
2688                         f->header.e_shnum = i + 1;
2689
2690                         memset(sec, 0, sizeof(*sec));
2691                         sec->header.sh_type = SHT_PROGBITS;
2692                         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2693                         sec->name = ".bss";
2694                         sec->idx = i;
2695                 }
2696
2697                 /* Allocate the COMMONS.  */
2698                 {
2699                         ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2700                         ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2701                         struct common_entry *c;
2702
2703                         for (c = common_head; c; c = c->next) {
2704                                 ElfW(Addr) align = c->sym->value;
2705
2706                                 if (align > max_align)
2707                                         max_align = align;
2708                                 if (bss_size & (align - 1))
2709                                         bss_size = (bss_size | (align - 1)) + 1;
2710
2711                                 c->sym->secidx = i;
2712                                 c->sym->value = bss_size;
2713
2714                                 bss_size += c->sym->size;
2715                         }
2716
2717                         f->sections[i]->header.sh_size = bss_size;
2718                         f->sections[i]->header.sh_addralign = max_align;
2719                 }
2720         }
2721
2722         /* For the sake of patch relocation and parameter initialization,
2723            allocate zeroed data for NOBITS sections now.  Note that after
2724            this we cannot assume NOBITS are really empty.  */
2725         for (i = 0; i < f->header.e_shnum; ++i) {
2726                 struct obj_section *s = f->sections[i];
2727                 if (s->header.sh_type == SHT_NOBITS) {
2728                         if (s->header.sh_size != 0)
2729                         s->contents = memset(xmalloc(s->header.sh_size),
2730                                                                  0, s->header.sh_size);
2731                         else
2732                                 s->contents = NULL;
2733
2734                         s->header.sh_type = SHT_PROGBITS;
2735                 }
2736         }
2737 }
2738
2739 unsigned long obj_load_size(struct obj_file *f)
2740 {
2741         unsigned long dot = 0;
2742         struct obj_section *sec;
2743
2744         /* Finalize the positions of the sections relative to one another.  */
2745
2746         for (sec = f->load_order; sec; sec = sec->load_next) {
2747                 ElfW(Addr) align;
2748
2749                 align = sec->header.sh_addralign;
2750                 if (align && (dot & (align - 1)))
2751                         dot = (dot | (align - 1)) + 1;
2752
2753                 sec->header.sh_addr = dot;
2754                 dot += sec->header.sh_size;
2755         }
2756
2757         return dot;
2758 }
2759
2760 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2761 {
2762         int i, n = f->header.e_shnum;
2763         int ret = 1;
2764
2765         /* Finalize the addresses of the sections.  */
2766
2767         f->baseaddr = base;
2768         for (i = 0; i < n; ++i)
2769                 f->sections[i]->header.sh_addr += base;
2770
2771         /* And iterate over all of the relocations.  */
2772
2773         for (i = 0; i < n; ++i) {
2774                 struct obj_section *relsec, *symsec, *targsec, *strsec;
2775                 ElfW(RelM) * rel, *relend;
2776                 ElfW(Sym) * symtab;
2777                 const char *strtab;
2778
2779                 relsec = f->sections[i];
2780                 if (relsec->header.sh_type != SHT_RELM)
2781                         continue;
2782
2783                 symsec = f->sections[relsec->header.sh_link];
2784                 targsec = f->sections[relsec->header.sh_info];
2785                 strsec = f->sections[symsec->header.sh_link];
2786
2787                 rel = (ElfW(RelM) *) relsec->contents;
2788                 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2789                 symtab = (ElfW(Sym) *) symsec->contents;
2790                 strtab = (const char *) strsec->contents;
2791
2792                 for (; rel < relend; ++rel) {
2793                         ElfW(Addr) value = 0;
2794                         struct obj_symbol *intsym = NULL;
2795                         unsigned long symndx;
2796                         ElfW(Sym) * extsym = 0;
2797                         const char *errmsg;
2798
2799                         /* Attempt to find a value to use for this relocation.  */
2800
2801                         symndx = ELFW(R_SYM) (rel->r_info);
2802                         if (symndx) {
2803                                 /* Note we've already checked for undefined symbols.  */
2804
2805                                 extsym = &symtab[symndx];
2806                                 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2807                                         /* Local symbols we look up in the local table to be sure
2808                                            we get the one that is really intended.  */
2809                                         intsym = f->local_symtab[symndx];
2810                                 } else {
2811                                         /* Others we look up in the hash table.  */
2812                                         const char *name;
2813                                         if (extsym->st_name)
2814                                                 name = strtab + extsym->st_name;
2815                                         else
2816                                                 name = f->sections[extsym->st_shndx]->name;
2817                                         intsym = obj_find_symbol(f, name);
2818                                 }
2819
2820                                 value = obj_symbol_final_value(f, intsym);
2821                                 intsym->referenced = 1;
2822                         }
2823 #if SHT_RELM == SHT_RELA
2824 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2825                         /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9.  */
2826                         if (!extsym || !extsym->st_name ||
2827                                 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2828 #endif
2829                                 value += rel->r_addend;
2830 #endif
2831
2832                         /* Do it! */
2833                         switch (arch_apply_relocation
2834                                         (f, targsec, symsec, intsym, rel, value)) {
2835                         case obj_reloc_ok:
2836                                 break;
2837
2838                         case obj_reloc_overflow:
2839                                 errmsg = "Relocation overflow";
2840                                 goto bad_reloc;
2841                         case obj_reloc_dangerous:
2842                                 errmsg = "Dangerous relocation";
2843                                 goto bad_reloc;
2844                         case obj_reloc_unhandled:
2845                                 errmsg = "Unhandled relocation";
2846                           bad_reloc:
2847                                 if (extsym) {
2848                                         error_msg("%s of type %ld for %s", errmsg,
2849                                                         (long) ELFW(R_TYPE) (rel->r_info),
2850                                                         strtab + extsym->st_name);
2851                                 } else {
2852                                         error_msg("%s of type %ld", errmsg,
2853                                                         (long) ELFW(R_TYPE) (rel->r_info));
2854                                 }
2855                                 ret = 0;
2856                                 break;
2857                         }
2858                 }
2859         }
2860
2861         /* Finally, take care of the patches.  */
2862
2863         if (f->string_patches) {
2864                 struct obj_string_patch *p;
2865                 struct obj_section *strsec;
2866                 ElfW(Addr) strsec_base;
2867                 strsec = obj_find_section(f, ".kstrtab");
2868                 strsec_base = strsec->header.sh_addr;
2869
2870                 for (p = f->string_patches; p; p = p->next) {
2871                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2872                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2873                                 = strsec_base + p->string_offset;
2874                 }
2875         }
2876
2877         if (f->symbol_patches) {
2878                 struct obj_symbol_patch *p;
2879
2880                 for (p = f->symbol_patches; p; p = p->next) {
2881                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2882                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2883                                 = obj_symbol_final_value(f, p->sym);
2884                 }
2885         }
2886
2887         return ret;
2888 }
2889
2890 int obj_create_image(struct obj_file *f, char *image)
2891 {
2892         struct obj_section *sec;
2893         ElfW(Addr) base = f->baseaddr;
2894
2895         for (sec = f->load_order; sec; sec = sec->load_next) {
2896                 char *secimg;
2897
2898                 if (sec->contents == 0 || sec->header.sh_size == 0)
2899                         continue;
2900
2901                 secimg = image + (sec->header.sh_addr - base);
2902
2903                 /* Note that we allocated data for NOBITS sections earlier.  */
2904                 memcpy(secimg, sec->contents, sec->header.sh_size);
2905         }
2906
2907         return 1;
2908 }
2909
2910 /*======================================================================*/
2911
2912 struct obj_file *obj_load(FILE * fp)
2913 {
2914         struct obj_file *f;
2915         ElfW(Shdr) * section_headers;
2916         int shnum, i;
2917         char *shstrtab;
2918
2919         /* Read the file header.  */
2920
2921         f = arch_new_file();
2922         memset(f, 0, sizeof(*f));
2923         f->symbol_cmp = strcmp;
2924         f->symbol_hash = obj_elf_hash;
2925         f->load_order_search_start = &f->load_order;
2926
2927         fseek(fp, 0, SEEK_SET);
2928         if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2929                 perror_msg("error reading ELF header");
2930                 return NULL;
2931         }
2932
2933         if (f->header.e_ident[EI_MAG0] != ELFMAG0
2934                 || f->header.e_ident[EI_MAG1] != ELFMAG1
2935                 || f->header.e_ident[EI_MAG2] != ELFMAG2
2936                 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2937                 error_msg("not an ELF file");
2938                 return NULL;
2939         }
2940         if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2941                 || f->header.e_ident[EI_DATA] != ELFDATAM
2942                 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2943                 || !MATCH_MACHINE(f->header.e_machine)) {
2944                 error_msg("ELF file not for this architecture");
2945                 return NULL;
2946         }
2947         if (f->header.e_type != ET_REL) {
2948                 error_msg("ELF file not a relocatable object");
2949                 return NULL;
2950         }
2951
2952         /* Read the section headers.  */
2953
2954         if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2955                 error_msg("section header size mismatch: %lu != %lu",
2956                                 (unsigned long) f->header.e_shentsize,
2957                                 (unsigned long) sizeof(ElfW(Shdr)));
2958                 return NULL;
2959         }
2960
2961         shnum = f->header.e_shnum;
2962         f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2963         memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2964
2965         section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2966         fseek(fp, f->header.e_shoff, SEEK_SET);
2967         if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2968                 perror_msg("error reading ELF section headers");
2969                 return NULL;
2970         }
2971
2972         /* Read the section data.  */
2973
2974         for (i = 0; i < shnum; ++i) {
2975                 struct obj_section *sec;
2976
2977                 f->sections[i] = sec = arch_new_section();
2978                 memset(sec, 0, sizeof(*sec));
2979
2980                 sec->header = section_headers[i];
2981                 sec->idx = i;
2982
2983                 if(sec->header.sh_size) switch (sec->header.sh_type) {
2984                 case SHT_NULL:
2985                 case SHT_NOTE:
2986                 case SHT_NOBITS:
2987                         /* ignore */
2988                         break;
2989
2990                 case SHT_PROGBITS:
2991                 case SHT_SYMTAB:
2992                 case SHT_STRTAB:
2993                 case SHT_RELM:
2994                         if (sec->header.sh_size > 0) {
2995                                 sec->contents = xmalloc(sec->header.sh_size);
2996                                 fseek(fp, sec->header.sh_offset, SEEK_SET);
2997                                 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2998                                         perror_msg("error reading ELF section data");
2999                                         return NULL;
3000                                 }
3001                         } else {
3002                                 sec->contents = NULL;
3003                         }
3004                         break;
3005
3006 #if SHT_RELM == SHT_REL
3007                 case SHT_RELA:
3008                         error_msg("RELA relocations not supported on this architecture");
3009                         return NULL;
3010 #else
3011                 case SHT_REL:
3012                         error_msg("REL relocations not supported on this architecture");
3013                         return NULL;
3014 #endif
3015
3016                 default:
3017                         if (sec->header.sh_type >= SHT_LOPROC) {
3018                                 /* Assume processor specific section types are debug
3019                                    info and can safely be ignored.  If this is ever not
3020                                    the case (Hello MIPS?), don't put ifdefs here but
3021                                    create an arch_load_proc_section().  */
3022                                 break;
3023                         }
3024
3025                         error_msg("can't handle sections of type %ld",
3026                                         (long) sec->header.sh_type);
3027                         return NULL;
3028                 }
3029         }
3030
3031         /* Do what sort of interpretation as needed by each section.  */
3032
3033         shstrtab = f->sections[f->header.e_shstrndx]->contents;
3034
3035         for (i = 0; i < shnum; ++i) {
3036                 struct obj_section *sec = f->sections[i];
3037                 sec->name = shstrtab + sec->header.sh_name;
3038         }
3039
3040         for (i = 0; i < shnum; ++i) {
3041                 struct obj_section *sec = f->sections[i];
3042
3043                 if (sec->header.sh_flags & SHF_ALLOC)
3044                         obj_insert_section_load_order(f, sec);
3045
3046                 switch (sec->header.sh_type) {
3047                 case SHT_SYMTAB:
3048                         {
3049                                 unsigned long nsym, j;
3050                                 char *strtab;
3051                                 ElfW(Sym) * sym;
3052
3053                                 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3054                                         error_msg("symbol size mismatch: %lu != %lu",
3055                                                         (unsigned long) sec->header.sh_entsize,
3056                                                         (unsigned long) sizeof(ElfW(Sym)));
3057                                         return NULL;
3058                                 }
3059
3060                                 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3061                                 strtab = f->sections[sec->header.sh_link]->contents;
3062                                 sym = (ElfW(Sym) *) sec->contents;
3063
3064                                 /* Allocate space for a table of local symbols.  */
3065                                 j = f->local_symtab_size = sec->header.sh_info;
3066                                 f->local_symtab = xmalloc(j *=
3067                                                                                   sizeof(struct obj_symbol *));
3068                                 memset(f->local_symtab, 0, j);
3069
3070                                 /* Insert all symbols into the hash table.  */
3071                                 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3072                                         const char *name;
3073                                         if (sym->st_name)
3074                                                 name = strtab + sym->st_name;
3075                 else
3076                                                 name = f->sections[sym->st_shndx]->name;
3077
3078                                         obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3079                                                                    sym->st_value, sym->st_size);
3080                 }
3081         }
3082                         break;
3083
3084                 case SHT_RELM:
3085                         if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3086                                 error_msg("relocation entry size mismatch: %lu != %lu",
3087                                                 (unsigned long) sec->header.sh_entsize,
3088                                                 (unsigned long) sizeof(ElfW(RelM)));
3089                                 return NULL;
3090                         }
3091                         break;
3092                 }
3093         }
3094
3095         return f;
3096 }
3097
3098 static void hide_special_symbols(struct obj_file *f)
3099 {
3100         static const char *const specials[] = {
3101                 "cleanup_module",
3102                 "init_module",
3103                 "kernel_version",
3104                 NULL
3105         };
3106
3107         struct obj_symbol *sym;
3108         const char *const *p;
3109
3110         for (p = specials; *p; ++p)
3111                 if ((sym = obj_find_symbol(f, *p)) != NULL)
3112                         sym->info =
3113                                 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3114 }
3115
3116
3117
3118 extern int insmod_main( int argc, char **argv)
3119 {
3120         int opt;
3121         int k_crcs;
3122         int k_new_syscalls;
3123         int len;
3124         char *tmp;
3125         unsigned long m_size;
3126         ElfW(Addr) m_addr;
3127         FILE *fp;
3128         struct obj_file *f;
3129         struct stat st;
3130         char m_name[BUFSIZ + 1] = "\0";
3131         int exit_status = EXIT_FAILURE;
3132         int m_has_modinfo;
3133 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3134         int k_version;
3135         char k_strversion[STRVERSIONLEN];
3136         char m_strversion[STRVERSIONLEN];
3137         int m_version;
3138         int m_crcs;
3139 #endif
3140
3141         /* Parse any options */
3142         while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
3143                 switch (opt) {
3144                         case 'f':                       /* force loading */
3145                                 flag_force_load = 1;
3146                                 break;
3147                         case 'k':                       /* module loaded by kerneld, auto-cleanable */
3148                                 flag_autoclean = 1;
3149                                 break;
3150                         case 'v':                       /* verbose output */
3151                                 flag_verbose = 1;
3152                                 break;
3153                         case 'x':                       /* do not export externs */
3154                                 flag_export = 0;
3155                                 break;
3156                         case 'o':                       /* name the output module */
3157                                 strncpy(m_name, optarg, BUFSIZ);
3158                                 break;
3159                         case 'L':                       /* Stub warning */
3160                                 /* This is needed for compatibility with modprobe.
3161                                  * In theory, this does locking, but we don't do
3162                                  * that.  So be careful and plan your life around not
3163                                  * loading the same module 50 times concurrently. */
3164                                 break;
3165                         default:
3166                                 show_usage();
3167                 }
3168         }
3169         
3170         if (argv[optind] == NULL) {
3171                 show_usage();
3172         }
3173
3174         /* Grab the module name */
3175         if ((tmp = strrchr(argv[optind], '/')) != NULL) {
3176                 tmp++;
3177         } else {
3178                 tmp = argv[optind];
3179         }
3180         len = strlen(tmp);
3181
3182         if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3183                 len -= 2;
3184         strncpy(m_fullName, tmp, len);
3185         if (*m_name == '\0') {
3186                 strcpy(m_name, m_fullName);
3187         }
3188         strcat(m_fullName, ".o");
3189
3190         /* Get a filedesc for the module */
3191         if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3192                         (fp = fopen(argv[optind], "r")) == NULL) {
3193                 /* Hmpf.  Could not open it. Search through _PATH_MODULES to find a module named m_name */
3194                 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
3195                                                         findNamedModule, 0, m_fullName) == FALSE) 
3196                 {
3197                         if (m_filename[0] == '\0'
3198                                 || ((fp = fopen(m_filename, "r")) == NULL)) 
3199                         {
3200                                 error_msg("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3201                                 return EXIT_FAILURE;
3202                         }
3203                 } else
3204                         error_msg_and_die("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3205         } else
3206                 memcpy(m_filename, argv[optind], strlen(argv[optind]));
3207
3208
3209         if ((f = obj_load(fp)) == NULL)
3210                 perror_msg_and_die("Could not load the module");
3211
3212         if (get_modinfo_value(f, "kernel_version") == NULL)
3213                 m_has_modinfo = 0;
3214         else
3215                 m_has_modinfo = 1;
3216
3217 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3218         /* Version correspondence?  */
3219
3220         k_version = get_kernel_version(k_strversion);
3221         if (m_has_modinfo) {
3222                 m_version = new_get_module_version(f, m_strversion);
3223         } else {
3224                 m_version = old_get_module_version(f, m_strversion);
3225                 if (m_version == -1) {
3226                         error_msg("couldn't find the kernel version the module was "
3227                                         "compiled for");
3228                         goto out;
3229                 }
3230         }
3231
3232         if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3233                 if (flag_force_load) {
3234                         error_msg("Warning: kernel-module version mismatch\n"
3235                                         "\t%s was compiled for kernel version %s\n"
3236                                         "\twhile this kernel is version %s",
3237                                         m_filename, m_strversion, k_strversion);
3238                 } else {
3239                         error_msg("kernel-module version mismatch\n"
3240                                         "\t%s was compiled for kernel version %s\n"
3241                                         "\twhile this kernel is version %s.",
3242                                         m_filename, m_strversion, k_strversion);
3243                         goto out;
3244                 }
3245         }
3246         k_crcs = 0;
3247 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3248
3249         k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3250
3251         if (k_new_syscalls) {
3252 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
3253                 if (!new_get_kernel_symbols())
3254                         goto out;
3255                 k_crcs = new_is_kernel_checksummed();
3256 #else
3257                 error_msg("Not configured to support new kernels");
3258                 goto out;
3259 #endif
3260         } else {
3261 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
3262                 if (!old_get_kernel_symbols(m_name))
3263                         goto out;
3264                 k_crcs = old_is_kernel_checksummed();
3265 #else
3266                 error_msg("Not configured to support old kernels");
3267                 goto out;
3268 #endif
3269         }
3270
3271 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3272         if (m_has_modinfo)
3273                 m_crcs = new_is_module_checksummed(f);
3274         else
3275                 m_crcs = old_is_module_checksummed(f);
3276
3277         if (m_crcs != k_crcs)
3278                 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3279 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3280
3281         /* Let the module know about the kernel symbols.  */
3282         add_kernel_symbols(f);
3283
3284         /* Allocate common symbols, symbol tables, and string tables.  */
3285
3286         if (k_new_syscalls 
3287                 ? !new_create_this_module(f, m_name)
3288                 : !old_create_mod_use_count(f)) 
3289         {
3290                 goto out;
3291         }
3292
3293         if (!obj_check_undefineds(f)) {
3294                 goto out;
3295         }
3296         obj_allocate_commons(f);
3297
3298         /* done with the module name, on to the optional var=value arguments */
3299         ++optind;
3300
3301         if (optind < argc) {
3302                 if (m_has_modinfo
3303                         ? !new_process_module_arguments(f, argc - optind, argv + optind) 
3304                         : !old_process_module_arguments(f, argc - optind, argv + optind)) 
3305                 {
3306                         goto out;
3307                 }
3308         }
3309
3310         arch_create_got(f);
3311         hide_special_symbols(f);
3312
3313         if (k_new_syscalls)
3314                 new_create_module_ksymtab(f);
3315
3316         /* Find current size of the module */
3317         m_size = obj_load_size(f);
3318
3319
3320         m_addr = create_module(m_name, m_size);
3321         if (m_addr==-1) switch (errno) {
3322         case EEXIST:
3323                 error_msg("A module named %s already exists", m_name);
3324                 goto out;
3325         case ENOMEM:
3326                 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3327                                 m_size);
3328                 goto out;
3329         default:
3330                 perror_msg("create_module: %s", m_name);
3331                 goto out;
3332         }
3333
3334         if (!obj_relocate(f, m_addr)) {
3335                 delete_module(m_name);
3336                 goto out;
3337         }
3338
3339         if (k_new_syscalls 
3340                 ? !new_init_module(m_name, f, m_size)
3341                 : !old_init_module(m_name, f, m_size)) 
3342         {
3343                 delete_module(m_name);
3344                 goto out;
3345         }
3346
3347         exit_status = EXIT_SUCCESS;
3348
3349 out:
3350         fclose(fp);
3351         return(exit_status);
3352 }