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