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