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