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