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