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