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