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