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