1 /* vi: set sw=4 ts=4: */
3 * Mini insmod implementation for busybox
5 * Copyright (C) 1999,2000,2001 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>
7 * and Ron Alder <alder@lineo.com>
9 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
12 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
13 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
14 * very minor changes required to also work with StrongArm and presumably
15 * all ARM based systems.
17 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
18 * PowerPC specific code stolen from modutils-2.3.16,
19 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
20 * I've only tested the code on mpc8xx platforms in big-endian mode.
21 * Did some cleanup and added BB_USE_xxx_ENTRIES...
23 * Based almost entirely on the Linux modutils-2.3.11 implementation.
24 * Copyright 1996, 1997 Linux International.
25 * New implementation contributed by Richard Henderson <rth@tamu.edu>
26 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
27 * Restructured (and partly rewritten) by:
28 * Björn Ekwall <bj0rn@blox.se> February 1999
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 * General Public License for more details.
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
56 #include <sys/utsname.h>
57 #include <sys/syscall.h>
58 #include <linux/unistd.h>
61 #if defined(__powerpc__)
62 #define BB_USE_PLT_ENTRIES
63 #define BB_PLT_ENTRY_SIZE 16
67 #define BB_USE_PLT_ENTRIES
68 #define BB_PLT_ENTRY_SIZE 8
69 #define BB_USE_GOT_ENTRIES
70 #define BB_GOT_ENTRY_SIZE 8
74 #define BB_USE_GOT_ENTRIES
75 #define BB_GOT_ENTRY_SIZE 4
79 #define BB_USE_GOT_ENTRIES
80 #define BB_GOT_ENTRY_SIZE 4
83 //----------------------------------------------------------------------------
84 //--------modutils module.h, lines 45-242
85 //----------------------------------------------------------------------------
87 /* Definitions for the Linux module syscall interface.
88 Copyright 1996, 1997 Linux International.
90 Contributed by Richard Henderson <rth@tamu.edu>
92 This file is part of the Linux modutils.
94 This program is free software; you can redistribute it and/or modify it
95 under the terms of the GNU General Public License as published by the
96 Free Software Foundation; either version 2 of the License, or (at your
97 option) any later version.
99 This program is distributed in the hope that it will be useful, but
100 WITHOUT ANY WARRANTY; without even the implied warranty of
101 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
102 General Public License for more details.
104 You should have received a copy of the GNU General Public License
105 along with this program; if not, write to the Free Software Foundation,
106 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
109 #ifndef MODUTILS_MODULE_H
110 static const int MODUTILS_MODULE_H = 1;
112 #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $"
114 /* This file contains the structures used by the 2.0 and 2.1 kernels.
115 We do not use the kernel headers directly because we do not wish
116 to be dependant on a particular kernel version to compile insmod. */
119 /*======================================================================*/
120 /* The structures used by Linux 2.0. */
122 /* The symbol format used by get_kernel_syms(2). */
123 struct old_kernel_sym
129 struct old_module_ref
131 unsigned long module; /* kernel addresses */
135 struct old_module_symbol
141 struct old_symbol_table
143 int size; /* total, including string table!!! */
146 struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */
147 struct old_module_ref ref[0]; /* actual size defined by n_refs */
150 struct old_mod_routines
153 unsigned long cleanup;
159 unsigned long ref; /* the list of modules that refer to me */
160 unsigned long symtab;
162 int size; /* size of module in pages */
163 unsigned long addr; /* address of module */
165 unsigned long cleanup; /* cleanup routine */
168 /* Sent to init_module(2) or'ed into the code size parameter. */
169 static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */
171 int get_kernel_syms(struct old_kernel_sym *);
172 int old_sys_init_module(const char *name, char *code, unsigned codesize,
173 struct old_mod_routines *, struct old_symbol_table *);
175 /*======================================================================*/
176 /* For sizeof() which are related to the module platform and not to the
177 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
179 #define tgt_sizeof_char sizeof(char)
180 #define tgt_sizeof_short sizeof(short)
181 #define tgt_sizeof_int sizeof(int)
182 #define tgt_sizeof_long sizeof(long)
183 #define tgt_sizeof_char_p sizeof(char *)
184 #define tgt_sizeof_void_p sizeof(void *)
185 #define tgt_long long
187 #if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
188 #undef tgt_sizeof_long
189 #undef tgt_sizeof_char_p
190 #undef tgt_sizeof_void_p
192 static const int tgt_sizeof_long = 8;
193 static const int tgt_sizeof_char_p = 8;
194 static const int tgt_sizeof_void_p = 8;
195 #define tgt_long long long
198 /*======================================================================*/
199 /* The structures used in Linux 2.1. */
201 /* Note: new_module_symbol does not use tgt_long intentionally */
202 struct new_module_symbol
208 struct new_module_persist;
210 struct new_module_ref
212 unsigned tgt_long dep; /* kernel addresses */
213 unsigned tgt_long ref;
214 unsigned tgt_long next_ref;
219 unsigned tgt_long size_of_struct; /* == sizeof(module) */
220 unsigned tgt_long next;
221 unsigned tgt_long name;
222 unsigned tgt_long size;
225 unsigned tgt_long flags; /* AUTOCLEAN et al */
230 unsigned tgt_long syms;
231 unsigned tgt_long deps;
232 unsigned tgt_long refs;
233 unsigned tgt_long init;
234 unsigned tgt_long cleanup;
235 unsigned tgt_long ex_table_start;
236 unsigned tgt_long ex_table_end;
238 unsigned tgt_long gp;
240 /* Everything after here is extension. */
241 unsigned tgt_long persist_start;
242 unsigned tgt_long persist_end;
243 unsigned tgt_long can_unload;
244 unsigned tgt_long runsize;
247 struct new_module_info
255 /* Bits of module.flags. */
256 static const int NEW_MOD_RUNNING = 1;
257 static const int NEW_MOD_DELETED = 2;
258 static const int NEW_MOD_AUTOCLEAN = 4;
259 static const int NEW_MOD_VISITED = 8;
260 static const int NEW_MOD_USED_ONCE = 16;
262 int new_sys_init_module(const char *name, const struct new_module *);
263 int query_module(const char *name, int which, void *buf, size_t bufsize,
266 /* Values for query_module's which. */
268 static const int QM_MODULES = 1;
269 static const int QM_DEPS = 2;
270 static const int QM_REFS = 3;
271 static const int QM_SYMBOLS = 4;
272 static const int QM_INFO = 5;
274 /*======================================================================*/
275 /* The system calls unchanged between 2.0 and 2.1. */
277 unsigned long create_module(const char *, size_t);
278 int delete_module(const char *);
281 #endif /* module.h */
283 //----------------------------------------------------------------------------
284 //--------end of modutils module.h
285 //----------------------------------------------------------------------------
289 //----------------------------------------------------------------------------
290 //--------modutils obj.h, lines 253-462
291 //----------------------------------------------------------------------------
293 /* Elf object file loading and relocation routines.
294 Copyright 1996, 1997 Linux International.
296 Contributed by Richard Henderson <rth@tamu.edu>
298 This file is part of the Linux modutils.
300 This program is free software; you can redistribute it and/or modify it
301 under the terms of the GNU General Public License as published by the
302 Free Software Foundation; either version 2 of the License, or (at your
303 option) any later version.
305 This program is distributed in the hope that it will be useful, but
306 WITHOUT ANY WARRANTY; without even the implied warranty of
307 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
308 General Public License for more details.
310 You should have received a copy of the GNU General Public License
311 along with this program; if not, write to the Free Software Foundation,
312 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
315 #ifndef MODUTILS_OBJ_H
316 static const int MODUTILS_OBJ_H = 1;
318 #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $"
320 /* The relocatable object is manipulated using elfin types. */
326 /* Machine-specific elf macros for i386 et al. */
328 /* the SH changes have only been tested on the SH4 in =little endian= mode */
329 /* I'm not sure about big endian, so let's warn: */
331 #if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
332 #error insmod.c may require changes for use on big endian SH4/SH3
335 /* it may or may not work on the SH1/SH2... So let's error on those
337 #if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
338 #error insmod.c may require changes for non-SH3/SH4 use
341 #define ELFCLASSM ELFCLASS32
345 #define MATCH_MACHINE(x) (x == EM_SH)
346 #define SHT_RELM SHT_RELA
347 #define Elf32_RelM Elf32_Rela
348 #define ELFDATAM ELFDATA2LSB
350 #elif defined(__arm__)
352 #define MATCH_MACHINE(x) (x == EM_ARM)
353 #define SHT_RELM SHT_REL
354 #define Elf32_RelM Elf32_Rel
355 #define ELFDATAM ELFDATA2LSB
357 #elif defined(__powerpc__)
359 #define MATCH_MACHINE(x) (x == EM_PPC)
360 #define SHT_RELM SHT_RELA
361 #define Elf32_RelM Elf32_Rela
362 #define ELFDATAM ELFDATA2MSB
364 #elif defined(__i386__)
366 /* presumably we can use these for anything but the SH and ARM*/
367 /* this is the previous behavior, but it does result in
368 insmod.c being broken on anything except i386 */
370 #define MATCH_MACHINE(x) (x == EM_386)
372 #define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
375 #define SHT_RELM SHT_REL
376 #define Elf32_RelM Elf32_Rel
377 #define ELFDATAM ELFDATA2LSB
380 #error Sorry, but insmod.c does not yet support this architecture...
384 # if ELFCLASSM == ELFCLASS32
385 # define ElfW(x) Elf32_ ## x
386 # define ELFW(x) ELF32_ ## x
388 # define ElfW(x) Elf64_ ## x
389 # define ELFW(x) ELF64_ ## x
393 /* For some reason this is missing from libc5. */
394 #ifndef ELF32_ST_INFO
395 # define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
398 #ifndef ELF64_ST_INFO
399 # define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
402 struct obj_string_patch;
403 struct obj_symbol_patch;
410 struct obj_section *load_next;
416 struct obj_symbol *next; /* hash table link */
420 int secidx; /* the defining section index/module */
422 int ksymidx; /* for export to the kernel symtab */
423 int referenced; /* actually used in the link */
426 /* Hardcode the hash table size. We shouldn't be needing so many
427 symbols that we begin to degrade performance, and we get a big win
428 by giving the compiler a constant divisor. */
430 #define HASH_BUCKETS 521
436 struct obj_section **sections;
437 struct obj_section *load_order;
438 struct obj_section **load_order_search_start;
439 struct obj_string_patch *string_patches;
440 struct obj_symbol_patch *symbol_patches;
441 int (*symbol_cmp)(const char *, const char *);
442 unsigned long (*symbol_hash)(const char *);
443 unsigned long local_symtab_size;
444 struct obj_symbol **local_symtab;
445 struct obj_symbol *symtab[HASH_BUCKETS];
456 struct obj_string_patch
458 struct obj_string_patch *next;
460 ElfW(Addr) reloc_offset;
461 ElfW(Addr) string_offset;
464 struct obj_symbol_patch
466 struct obj_symbol_patch *next;
468 ElfW(Addr) reloc_offset;
469 struct obj_symbol *sym;
473 /* Generic object manipulation routines. */
475 unsigned long obj_elf_hash(const char *);
477 unsigned long obj_elf_hash_n(const char *, unsigned long len);
479 struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name,
480 unsigned long symidx, int info, int secidx,
481 ElfW(Addr) value, unsigned long size);
483 struct obj_symbol *obj_find_symbol (struct obj_file *f,
486 ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
487 struct obj_symbol *sym);
489 void obj_set_symbol_compare(struct obj_file *f,
490 int (*cmp)(const char *, const char *),
491 unsigned long (*hash)(const char *));
493 struct obj_section *obj_find_section (struct obj_file *f,
496 void obj_insert_section_load_order (struct obj_file *f,
497 struct obj_section *sec);
499 struct obj_section *obj_create_alloced_section (struct obj_file *f,
504 struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
509 void *obj_extend_section (struct obj_section *sec, unsigned long more);
511 int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
514 int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
515 struct obj_symbol *sym);
517 int obj_check_undefineds(struct obj_file *f);
519 void obj_allocate_commons(struct obj_file *f);
521 unsigned long obj_load_size (struct obj_file *f);
523 int obj_relocate (struct obj_file *f, ElfW(Addr) base);
525 struct obj_file *obj_load(FILE *f);
527 int obj_create_image (struct obj_file *f, char *image);
529 /* Architecture specific manipulation routines. */
531 struct obj_file *arch_new_file (void);
533 struct obj_section *arch_new_section (void);
535 struct obj_symbol *arch_new_symbol (void);
537 enum obj_reloc arch_apply_relocation (struct obj_file *f,
538 struct obj_section *targsec,
539 struct obj_section *symsec,
540 struct obj_symbol *sym,
541 ElfW(RelM) *rel, ElfW(Addr) value);
543 int arch_create_got (struct obj_file *f);
546 int arch_init_module (struct obj_file *f, struct new_module *);
549 //----------------------------------------------------------------------------
550 //--------end of modutils obj.h
551 //----------------------------------------------------------------------------
557 #define _PATH_MODULES "/lib/modules"
558 static const int STRVERSIONLEN = 32;
560 /*======================================================================*/
562 int flag_force_load = 0;
563 int flag_autoclean = 0;
564 int flag_verbose = 0;
568 /*======================================================================*/
570 /* previously, these were named i386_* but since we could be
571 compiling for the sh, I've renamed them to the more general
572 arch_* These structures are the same between the x86 and SH,
573 and we can't support anything else right now anyway. In the
574 future maybe they should be #if defined'd */
580 #if defined(BB_USE_PLT_ENTRIES)
581 struct arch_plt_entry
585 int inited:1; /* has been set up */
589 #if defined(BB_USE_GOT_ENTRIES)
590 struct arch_got_entry {
592 unsigned offset_done:1;
593 unsigned reloc_done:1;
598 struct obj_file root;
599 #if defined(BB_USE_PLT_ENTRIES)
600 struct obj_section *plt;
602 #if defined(BB_USE_GOT_ENTRIES)
603 struct obj_section *got;
608 struct obj_symbol root;
609 #if defined(BB_USE_PLT_ENTRIES)
610 struct arch_plt_entry pltent;
612 #if defined(BB_USE_GOT_ENTRIES)
613 struct arch_got_entry gotent;
618 struct external_module {
623 struct new_module_symbol *syms;
626 struct new_module_symbol *ksyms;
629 struct external_module *ext_modules;
631 int n_ext_modules_used;
635 /* Some firendly syscalls to cheer everyone's day... */
636 #define __NR_new_sys_init_module __NR_init_module
637 _syscall2(int, new_sys_init_module, const char *, name,
638 const struct new_module *, info)
639 #define __NR_old_sys_init_module __NR_init_module
640 _syscall5(int, old_sys_init_module, const char *, name, char *, code,
641 unsigned, codesize, struct old_mod_routines *, routines,
642 struct old_symbol_table *, symtab)
644 _syscall1(int, delete_module, const char *, name)
646 extern int delete_module(const char *);
649 /* This is kind of troublesome. See, we don't actually support
650 the m68k or the arm the same way we support i386 and (now)
651 sh. In doing my SH patch, I just assumed that whatever works
652 for i386 also works for m68k and arm since currently insmod.c
653 does nothing special for them. If this isn't true, the below
654 line is rather misleading IMHO, and someone should either
655 change it or add more proper architecture-dependent support
658 -- Bryan Rittmeyer <bryan@ixiacom.com> */
660 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
661 _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks)
664 #if defined(__i386__) || defined(__m68k__) || defined(__arm__) \
665 || defined(__powerpc__)
666 /* Jump through hoops to fixup error return codes */
667 #define __NR__create_module __NR_create_module
668 static inline _syscall2(long, _create_module, const char *, name, size_t,
670 unsigned long create_module(const char *name, size_t size)
672 long ret = _create_module(name, size);
674 if (ret == -1 && errno > 125) {
681 _syscall2(unsigned long, create_module, const char *, name, size_t, size)
683 static char m_filename[BUFSIZ + 1] = "\0";
684 static char m_fullName[BUFSIZ + 1] = "\0";
686 /*======================================================================*/
689 static int findNamedModule(const char *fileName, struct stat *statbuf,
692 char *fullName = (char *) userDate;
695 if (fullName[0] == '\0')
698 char *tmp = strrchr((char *) fileName, '/');
701 tmp = (char *) fileName;
704 if (check_wildcard_match(tmp, fullName) == TRUE) {
705 /* Stop searching if we find a match */
706 memcpy(m_filename, fileName, strlen(fileName)+1);
714 /*======================================================================*/
716 struct obj_file *arch_new_file(void)
719 f = xmalloc(sizeof(*f));
721 #if defined(BB_USE_PLT_ENTRIES)
724 #if defined(BB_USE_GOT_ENTRIES)
731 struct obj_section *arch_new_section(void)
733 return xmalloc(sizeof(struct obj_section));
736 struct obj_symbol *arch_new_symbol(void)
738 struct arch_symbol *sym;
739 sym = xmalloc(sizeof(*sym));
741 #if defined(BB_USE_PLT_ENTRIES)
742 memset(&sym->pltent, 0, sizeof(sym->pltent));
744 #if defined(BB_USE_GOT_ENTRIES)
745 memset(&sym->gotent, 0, sizeof(sym->gotent));
752 arch_apply_relocation(struct obj_file *f,
753 struct obj_section *targsec,
754 struct obj_section *symsec,
755 struct obj_symbol *sym,
756 ElfW(RelM) *rel, ElfW(Addr) v)
758 struct arch_file *ifile = (struct arch_file *) f;
759 struct arch_symbol *isym = (struct arch_symbol *) sym;
761 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
762 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
763 #if defined(BB_USE_GOT_ENTRIES)
764 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
766 #if defined(BB_USE_PLT_ENTRIES)
767 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
768 struct arch_plt_entry *pe;
771 enum obj_reloc ret = obj_reloc_ok;
773 switch (ELF32_R_TYPE(rel->r_info)) {
775 /* even though these constants seem to be the same for
776 the i386 and the sh, we "#if define" them for clarity
777 and in case that ever changes */
780 #elif defined(__arm__)
782 #elif defined(__i386__)
784 #elif defined(__powerpc__)
791 #elif defined(__arm__)
793 #elif defined(__i386__)
795 #elif defined(__powerpc__)
801 #if defined(__powerpc__)
802 case R_PPC_ADDR16_HA:
803 *(unsigned short *)loc = (v + 0x8000) >> 16;
806 case R_PPC_ADDR16_HI:
807 *(unsigned short *)loc = v >> 16;
810 case R_PPC_ADDR16_LO:
811 *(unsigned short *)loc = v;
816 #elif defined(__sh__)
820 #elif defined(__i386__)
825 #elif defined(__powerpc__)
835 #elif defined(__i386__)
838 #if defined(BB_USE_PLT_ENTRIES)
844 #if defined(__powerpc__)
847 /* find the plt entry and initialize it if necessary */
848 assert(isym != NULL);
850 pe = (struct arch_plt_entry*) &isym->pltent;
853 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
855 /* generate some machine code */
858 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
859 ip[1] = v; /* sym@ */
861 #if defined(__powerpc__)
862 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
863 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
864 ip[2] = 0x7d6903a6; /* mtctr r11 */
865 ip[3] = 0x4e800420; /* bctr */
870 /* relative distance to target */
872 /* if the target is too far away.... */
873 if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
875 v = plt + pe->offset - dot;
878 ret = obj_reloc_dangerous;
880 /* merge the offset into the instruction. */
882 /* Convert to words. */
885 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
887 #if defined(__powerpc__)
888 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
891 #endif /* BB_USE_PLT_ENTRIES */
894 #elif defined(__sh__)
899 #elif defined(__i386__)
907 #elif defined(__sh__)
909 *loc += f->baseaddr + rel->r_addend;
911 #elif defined(__i386__)
917 #if defined(BB_USE_GOT_ENTRIES)
921 #elif defined(__arm__)
923 #elif defined(__i386__)
928 *loc += got - dot + rel->r_addend;;
929 #elif defined(__i386__) || defined(__arm__)
936 #elif defined(__arm__)
938 #elif defined(__i386__)
941 assert(isym != NULL);
942 /* needs an entry in the .got: set it, once */
943 if (!isym->gotent.reloc_done) {
944 isym->gotent.reloc_done = 1;
945 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
947 /* make the reloc with_respect_to_.got */
949 *loc += isym->gotent.offset + rel->r_addend;
950 #elif defined(__i386__) || defined(__arm__)
951 *loc += isym->gotent.offset;
955 /* address relative to the got */
958 #elif defined(__arm__)
960 #elif defined(__i386__)
967 #endif /* BB_USE_GOT_ENTRIES */
970 printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
971 ret = obj_reloc_unhandled;
978 int arch_create_got(struct obj_file *f)
980 struct arch_file *ifile = (struct arch_file *) f;
982 #if defined(BB_USE_GOT_ENTRIES)
983 int got_offset = 0, gotneeded = 0;
985 #if defined(BB_USE_PLT_ENTRIES)
986 int plt_offset = 0, pltneeded = 0;
988 struct obj_section *relsec, *symsec, *strsec;
989 ElfW(RelM) *rel, *relend;
990 ElfW(Sym) *symtab, *extsym;
991 const char *strtab, *name;
992 struct arch_symbol *intsym;
994 for (i = 0; i < f->header.e_shnum; ++i) {
995 relsec = f->sections[i];
996 if (relsec->header.sh_type != SHT_RELM)
999 symsec = f->sections[relsec->header.sh_link];
1000 strsec = f->sections[symsec->header.sh_link];
1002 rel = (ElfW(RelM) *) relsec->contents;
1003 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1004 symtab = (ElfW(Sym) *) symsec->contents;
1005 strtab = (const char *) strsec->contents;
1007 for (; rel < relend; ++rel) {
1008 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
1010 switch (ELF32_R_TYPE(rel->r_info)) {
1011 #if defined(__arm__)
1014 #elif defined(__sh__)
1017 #elif defined(__i386__)
1022 #if defined(__powerpc__)
1028 #if defined(__arm__)
1037 if (got_offset == 0)
1039 #elif defined(__sh__)
1043 #elif defined(__i386__)
1053 if (extsym->st_name != 0) {
1054 name = strtab + extsym->st_name;
1056 name = f->sections[extsym->st_shndx]->name;
1058 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1059 #if defined(BB_USE_GOT_ENTRIES)
1060 if (!intsym->gotent.offset_done) {
1061 intsym->gotent.offset_done = 1;
1062 intsym->gotent.offset = got_offset;
1063 got_offset += BB_GOT_ENTRY_SIZE;
1066 #if defined(BB_USE_PLT_ENTRIES)
1067 if (pltneeded && intsym->pltent.allocated == 0) {
1068 intsym->pltent.allocated = 1;
1069 intsym->pltent.offset = plt_offset;
1070 plt_offset += BB_PLT_ENTRY_SIZE;
1071 intsym->pltent.inited = 0;
1078 #if defined(BB_USE_GOT_ENTRIES)
1080 struct obj_section* relsec = obj_find_section(f, ".got");
1083 obj_extend_section(relsec, got_offset);
1085 relsec = obj_create_alloced_section(f, ".got",
1091 ifile->got = relsec;
1095 #if defined(BB_USE_PLT_ENTRIES)
1097 ifile->plt = obj_create_alloced_section(f, ".plt",
1104 int arch_init_module(struct obj_file *f, struct new_module *mod)
1110 /*======================================================================*/
1112 /* Standard ELF hash function. */
1113 inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1115 unsigned long h = 0;
1122 if ((g = (h & 0xf0000000)) != 0) {
1131 unsigned long obj_elf_hash(const char *name)
1133 return obj_elf_hash_n(name, strlen(name));
1136 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1137 /* Get the kernel version in the canonical integer form. */
1139 static int get_kernel_version(char str[STRVERSIONLEN])
1141 struct utsname uts_info;
1145 if (uname(&uts_info) < 0)
1147 strncpy(str, uts_info.release, STRVERSIONLEN);
1148 p = uts_info.release;
1150 a = strtoul(p, &p, 10);
1153 b = strtoul(p + 1, &p, 10);
1156 c = strtoul(p + 1, &q, 10);
1160 return a << 16 | b << 8 | c;
1163 /* String comparison for non-co-versioned kernel and module. */
1165 static int ncv_strcmp(const char *a, const char *b)
1167 size_t alen = strlen(a), blen = strlen(b);
1169 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1170 return strncmp(a, b, alen);
1171 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1172 return strncmp(a, b, blen);
1174 return strcmp(a, b);
1177 /* String hashing for non-co-versioned kernel and module. Here
1178 we are simply forced to drop the crc from the hash. */
1180 static unsigned long ncv_symbol_hash(const char *str)
1182 size_t len = strlen(str);
1183 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1185 return obj_elf_hash_n(str, len);
1189 obj_set_symbol_compare(struct obj_file *f,
1190 int (*cmp) (const char *, const char *),
1191 unsigned long (*hash) (const char *))
1194 f->symbol_cmp = cmp;
1196 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1199 f->symbol_hash = hash;
1201 memcpy(tmptab, f->symtab, sizeof(tmptab));
1202 memset(f->symtab, 0, sizeof(f->symtab));
1204 for (i = 0; i < HASH_BUCKETS; ++i)
1205 for (sym = tmptab[i]; sym; sym = next) {
1206 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1208 sym->next = f->symtab[h];
1214 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1217 struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
1218 unsigned long symidx, int info,
1219 int secidx, ElfW(Addr) value,
1222 struct obj_symbol *sym;
1223 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1224 int n_type = ELFW(ST_TYPE) (info);
1225 int n_binding = ELFW(ST_BIND) (info);
1227 for (sym = f->symtab[hash]; sym; sym = sym->next)
1228 if (f->symbol_cmp(sym->name, name) == 0) {
1229 int o_secidx = sym->secidx;
1230 int o_info = sym->info;
1231 int o_type = ELFW(ST_TYPE) (o_info);
1232 int o_binding = ELFW(ST_BIND) (o_info);
1234 /* A redefinition! Is it legal? */
1236 if (secidx == SHN_UNDEF)
1238 else if (o_secidx == SHN_UNDEF)
1240 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1241 /* Cope with local and global symbols of the same name
1242 in the same object file, as might have been created
1243 by ld -r. The only reason locals are now seen at this
1244 level at all is so that we can do semi-sensible things
1247 struct obj_symbol *nsym, **p;
1249 nsym = arch_new_symbol();
1250 nsym->next = sym->next;
1253 /* Excise the old (local) symbol from the hash chain. */
1254 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1258 } else if (n_binding == STB_LOCAL) {
1259 /* Another symbol of the same name has already been defined.
1260 Just add this to the local table. */
1261 sym = arch_new_symbol();
1264 f->local_symtab[symidx] = sym;
1266 } else if (n_binding == STB_WEAK)
1268 else if (o_binding == STB_WEAK)
1270 /* Don't unify COMMON symbols with object types the programmer
1272 else if (secidx == SHN_COMMON
1273 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1275 else if (o_secidx == SHN_COMMON
1276 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1279 /* Don't report an error if the symbol is coming from
1280 the kernel or some external module. */
1281 if (secidx <= SHN_HIRESERVE)
1282 error_msg("%s multiply defined", name);
1287 /* Completely new symbol. */
1288 sym = arch_new_symbol();
1289 sym->next = f->symtab[hash];
1290 f->symtab[hash] = sym;
1293 if (ELFW(ST_BIND) (info) == STB_LOCAL)
1294 f->local_symtab[symidx] = sym;
1300 sym->secidx = secidx;
1306 struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
1308 struct obj_symbol *sym;
1309 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1311 for (sym = f->symtab[hash]; sym; sym = sym->next)
1312 if (f->symbol_cmp(sym->name, name) == 0)
1319 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1322 if (sym->secidx >= SHN_LORESERVE)
1325 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1327 /* As a special case, a NULL sym has value zero. */
1332 struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1334 int i, n = f->header.e_shnum;
1336 for (i = 0; i < n; ++i)
1337 if (strcmp(f->sections[i]->name, name) == 0)
1338 return f->sections[i];
1343 static int obj_load_order_prio(struct obj_section *a)
1345 unsigned long af, ac;
1347 af = a->header.sh_flags;
1350 if (a->name[0] != '.' || strlen(a->name) != 10 ||
1351 strcmp(a->name + 5, ".init"))
1355 if (!(af & SHF_WRITE))
1357 if (af & SHF_EXECINSTR)
1359 if (a->header.sh_type != SHT_NOBITS)
1366 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1368 struct obj_section **p;
1369 int prio = obj_load_order_prio(sec);
1370 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1371 if (obj_load_order_prio(*p) < prio)
1373 sec->load_next = *p;
1377 struct obj_section *obj_create_alloced_section(struct obj_file *f,
1379 unsigned long align,
1382 int newidx = f->header.e_shnum++;
1383 struct obj_section *sec;
1385 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1386 f->sections[newidx] = sec = arch_new_section();
1388 memset(sec, 0, sizeof(*sec));
1389 sec->header.sh_type = SHT_PROGBITS;
1390 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1391 sec->header.sh_size = size;
1392 sec->header.sh_addralign = align;
1396 sec->contents = xmalloc(size);
1398 obj_insert_section_load_order(f, sec);
1403 struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1405 unsigned long align,
1408 int newidx = f->header.e_shnum++;
1409 struct obj_section *sec;
1411 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1412 f->sections[newidx] = sec = arch_new_section();
1414 memset(sec, 0, sizeof(*sec));
1415 sec->header.sh_type = SHT_PROGBITS;
1416 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1417 sec->header.sh_size = size;
1418 sec->header.sh_addralign = align;
1422 sec->contents = xmalloc(size);
1424 sec->load_next = f->load_order;
1425 f->load_order = sec;
1426 if (f->load_order_search_start == &f->load_order)
1427 f->load_order_search_start = &sec->load_next;
1432 void *obj_extend_section(struct obj_section *sec, unsigned long more)
1434 unsigned long oldsize = sec->header.sh_size;
1435 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1436 return sec->contents + oldsize;
1441 /* Conditionally add the symbols from the given symbol set to the
1447 int idx, struct new_module_symbol *syms, size_t nsyms)
1449 struct new_module_symbol *s;
1453 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1455 /* Only add symbols that are already marked external. If we
1456 override locals we may cause problems for argument initialization.
1457 We will also create a false dependency on the module. */
1458 struct obj_symbol *sym;
1460 sym = obj_find_symbol(f, (char *) s->name);
1461 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1462 sym = obj_add_symbol(f, (char *) s->name, -1,
1463 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1465 /* Did our symbol just get installed? If so, mark the
1466 module as "used". */
1467 if (sym->secidx == idx)
1475 static void add_kernel_symbols(struct obj_file *f)
1477 struct external_module *m;
1480 /* Add module symbols first. */
1482 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1484 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1485 m->nsyms)) m->used = 1, ++nused;
1487 n_ext_modules_used = nused;
1489 /* And finally the symbols from the kernel proper. */
1492 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1495 static char *get_modinfo_value(struct obj_file *f, const char *key)
1497 struct obj_section *sec;
1498 char *p, *v, *n, *ep;
1499 size_t klen = strlen(key);
1501 sec = obj_find_section(f, ".modinfo");
1505 ep = p + sec->header.sh_size;
1508 n = strchr(p, '\0');
1510 if (p + klen == v && strncmp(p, key, klen) == 0)
1513 if (p + klen == n && strcmp(p, key) == 0)
1523 /*======================================================================*/
1524 /* Functions relating to module loading in pre 2.1 kernels. */
1527 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1531 struct obj_symbol *sym;
1535 if ((q = strchr(p, '=')) == NULL) {
1541 sym = obj_find_symbol(f, p);
1543 /* Also check that the parameter was not resolved from the kernel. */
1544 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1545 error_msg("symbol for parameter %s not found", p);
1549 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1551 /* Do C quoting if we begin with a ". */
1555 str = alloca(strlen(q));
1556 for (r = str, q++; *q != '"'; ++q, ++r) {
1558 error_msg("improperly terminated string argument for %s", p);
1560 } else if (*q == '\\')
1594 if (q[1] >= '0' && q[1] <= '7') {
1595 c = (c * 8) + *++q - '0';
1596 if (q[1] >= '0' && q[1] <= '7')
1597 c = (c * 8) + *++q - '0';
1610 obj_string_patch(f, sym->secidx, sym->value, str);
1611 } else if (*q >= '0' && *q <= '9') {
1613 *loc++ = strtoul(q, &q, 0);
1614 while (*q++ == ',');
1616 char *contents = f->sections[sym->secidx]->contents;
1617 char *loc = contents + sym->value;
1618 char *r; /* To search for commas */
1620 /* Break the string with comas */
1621 while ((r = strchr(q, ',')) != (char *) NULL) {
1623 obj_string_patch(f, sym->secidx, loc - contents, q);
1624 loc += sizeof(char *);
1629 obj_string_patch(f, sym->secidx, loc - contents, q);
1638 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1639 static int old_is_module_checksummed(struct obj_file *f)
1641 return obj_find_symbol(f, "Using_Versions") != NULL;
1643 /* Get the module's kernel version in the canonical integer form. */
1646 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1648 struct obj_symbol *sym;
1652 sym = obj_find_symbol(f, "kernel_version");
1656 p = f->sections[sym->secidx]->contents + sym->value;
1657 strncpy(str, p, STRVERSIONLEN);
1659 a = strtoul(p, &p, 10);
1662 b = strtoul(p + 1, &p, 10);
1665 c = strtoul(p + 1, &q, 10);
1669 return a << 16 | b << 8 | c;
1672 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1674 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
1676 /* Fetch all the symbols and divvy them up as appropriate for the modules. */
1678 static int old_get_kernel_symbols(const char *m_name)
1680 struct old_kernel_sym *ks, *k;
1681 struct new_module_symbol *s;
1682 struct external_module *mod;
1683 int nks, nms, nmod, i;
1685 nks = get_kernel_syms(NULL);
1687 perror_msg("get_kernel_syms: %s", m_name);
1691 ks = k = xmalloc(nks * sizeof(*ks));
1693 if (get_kernel_syms(ks) != nks) {
1694 perror("inconsistency with get_kernel_syms -- is someone else "
1695 "playing with modules?");
1700 /* Collect the module information. */
1705 while (k->name[0] == '#' && k->name[1]) {
1706 struct old_kernel_sym *k2;
1707 struct new_module_symbol *s;
1709 /* Find out how many symbols this module has. */
1710 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1714 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1715 mod[nmod].name = k->name + 1;
1716 mod[nmod].addr = k->value;
1718 mod[nmod].nsyms = nms;
1719 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1721 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1722 s->name = (unsigned long) k->name;
1723 s->value = k->value;
1730 n_ext_modules = nmod + 1;
1732 /* Now collect the symbols for the kernel proper. */
1734 if (k->name[0] == '#')
1737 nksyms = nms = nks - (k - ks);
1738 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1740 for (i = 0; i < nms; ++i, ++s, ++k) {
1741 s->name = (unsigned long) k->name;
1742 s->value = k->value;
1748 /* Return the kernel symbol checksum version, or zero if not used. */
1750 static int old_is_kernel_checksummed(void)
1752 /* Using_Versions is the first symbol. */
1754 && strcmp((char *) ksyms[0].name,
1755 "Using_Versions") == 0) return ksyms[0].value;
1761 static int old_create_mod_use_count(struct obj_file *f)
1763 struct obj_section *sec;
1765 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1768 obj_add_symbol(f, "mod_use_count_", -1,
1769 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1776 old_init_module(const char *m_name, struct obj_file *f,
1777 unsigned long m_size)
1780 struct old_mod_routines routines;
1781 struct old_symbol_table *symtab;
1784 /* Create the symbol table */
1786 int nsyms = 0, strsize = 0, total;
1788 /* Size things first... */
1791 for (i = 0; i < HASH_BUCKETS; ++i) {
1792 struct obj_symbol *sym;
1793 for (sym = f->symtab[i]; sym; sym = sym->next)
1794 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1795 && sym->secidx <= SHN_HIRESERVE)
1797 sym->ksymidx = nsyms++;
1798 strsize += strlen(sym->name) + 1;
1803 total = (sizeof(struct old_symbol_table)
1804 + nsyms * sizeof(struct old_module_symbol)
1805 + n_ext_modules_used * sizeof(struct old_module_ref)
1807 symtab = xmalloc(total);
1808 symtab->size = total;
1809 symtab->n_symbols = nsyms;
1810 symtab->n_refs = n_ext_modules_used;
1812 if (flag_export && nsyms) {
1813 struct old_module_symbol *ksym;
1817 ksym = symtab->symbol;
1818 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1819 + n_ext_modules_used * sizeof(struct old_module_ref));
1821 for (i = 0; i < HASH_BUCKETS; ++i) {
1822 struct obj_symbol *sym;
1823 for (sym = f->symtab[i]; sym; sym = sym->next)
1824 if (sym->ksymidx >= 0) {
1825 ksym->addr = obj_symbol_final_value(f, sym);
1827 (unsigned long) str - (unsigned long) symtab;
1829 strcpy(str, sym->name);
1830 str += strlen(sym->name) + 1;
1836 if (n_ext_modules_used) {
1837 struct old_module_ref *ref;
1840 ref = (struct old_module_ref *)
1841 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1843 for (i = 0; i < n_ext_modules; ++i)
1844 if (ext_modules[i].used)
1845 ref++->module = ext_modules[i].addr;
1849 /* Fill in routines. */
1852 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1854 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1856 /* Whew! All of the initialization is complete. Collect the final
1857 module image and give it to the kernel. */
1859 image = xmalloc(m_size);
1860 obj_create_image(f, image);
1862 /* image holds the complete relocated module, accounting correctly for
1863 mod_use_count. However the old module kernel support assume that
1864 it is receiving something which does not contain mod_use_count. */
1865 ret = old_sys_init_module(m_name, image + sizeof(long),
1866 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1867 : 0), &routines, symtab);
1869 perror_msg("init_module: %s", m_name);
1879 #define old_create_mod_use_count(x) TRUE
1880 #define old_init_module(x, y, z) TRUE
1882 #endif /* BB_FEATURE_OLD_MODULE_INTERFACE */
1886 /*======================================================================*/
1887 /* Functions relating to module loading after 2.1.18. */
1890 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1894 struct obj_symbol *sym;
1895 char *contents, *loc;
1899 if ((q = strchr(p, '=')) == NULL) {
1904 key = alloca(q - p + 6);
1905 memcpy(key, "parm_", 5);
1906 memcpy(key + 5, p, q - p);
1909 p = get_modinfo_value(f, key);
1912 error_msg("invalid parameter %s", key);
1916 sym = obj_find_symbol(f, key);
1918 /* Also check that the parameter was not resolved from the kernel. */
1919 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1920 error_msg("symbol for parameter %s not found", key);
1925 min = strtoul(p, &p, 10);
1927 max = strtoul(p + 1, &p, 10);
1933 contents = f->sections[sym->secidx]->contents;
1934 loc = contents + sym->value;
1938 if ((*p == 's') || (*p == 'c')) {
1941 /* Do C quoting if we begin with a ", else slurp the lot. */
1945 str = alloca(strlen(q));
1946 for (r = str, q++; *q != '"'; ++q, ++r) {
1948 error_msg("improperly terminated string argument for %s",
1951 } else if (*q == '\\')
1985 if (q[1] >= '0' && q[1] <= '7') {
1986 c = (c * 8) + *++q - '0';
1987 if (q[1] >= '0' && q[1] <= '7')
1988 c = (c * 8) + *++q - '0';
2005 /* In this case, the string is not quoted. We will break
2006 it using the coma (like for ints). If the user wants to
2007 include comas in a string, he just has to quote it */
2009 /* Search the next coma */
2013 if (r != (char *) NULL) {
2014 /* Recopy the current field */
2015 str = alloca(r - q + 1);
2016 memcpy(str, q, r - q);
2018 /* I don't know if it is usefull, as the previous case
2019 doesn't null terminate the string ??? */
2022 /* Keep next fields */
2033 obj_string_patch(f, sym->secidx, loc - contents, str);
2034 loc += tgt_sizeof_char_p;
2036 /* Array of chars (in fact, matrix !) */
2037 unsigned long charssize; /* size of each member */
2039 /* Get the size of each member */
2040 /* Probably we should do that outside the loop ? */
2041 if (!isdigit(*(p + 1))) {
2042 error_msg("parameter type 'c' for %s must be followed by"
2043 " the maximum size", key);
2046 charssize = strtoul(p + 1, (char **) NULL, 10);
2049 if (strlen(str) >= charssize) {
2050 error_msg("string too long for %s (max %ld)", key,
2055 /* Copy to location */
2056 strcpy((char *) loc, str);
2060 long v = strtoul(q, &q, 0);
2067 loc += tgt_sizeof_short;
2071 loc += tgt_sizeof_int;
2075 loc += tgt_sizeof_long;
2079 error_msg("unknown parameter type '%c' for %s", *p, key);
2094 goto retry_end_of_value;
2098 error_msg("too many values for %s (max %d)", key, max);
2105 error_msg("invalid argument syntax for %s", key);
2112 error_msg("too few values for %s (min %d)", key, min);
2122 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2123 static int new_is_module_checksummed(struct obj_file *f)
2125 const char *p = get_modinfo_value(f, "using_checksums");
2132 /* Get the module's kernel version in the canonical integer form. */
2135 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2140 p = get_modinfo_value(f, "kernel_version");
2143 strncpy(str, p, STRVERSIONLEN);
2145 a = strtoul(p, &p, 10);
2148 b = strtoul(p + 1, &p, 10);
2151 c = strtoul(p + 1, &q, 10);
2155 return a << 16 | b << 8 | c;
2158 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2161 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
2163 /* Fetch the loaded modules, and all currently exported symbols. */
2165 static int new_get_kernel_symbols(void)
2167 char *module_names, *mn;
2168 struct external_module *modules, *m;
2169 struct new_module_symbol *syms, *s;
2170 size_t ret, bufsize, nmod, nsyms, i, j;
2172 /* Collect the loaded modules. */
2174 module_names = xmalloc(bufsize = 256);
2176 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2177 if (errno == ENOSPC) {
2178 module_names = xrealloc(module_names, bufsize = ret);
2179 goto retry_modules_load;
2181 perror_msg("QM_MODULES");
2185 n_ext_modules = nmod = ret;
2186 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2187 memset(modules, 0, nmod * sizeof(*modules));
2189 /* Collect the modules' symbols. */
2191 for (i = 0, mn = module_names, m = modules;
2192 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2193 struct new_module_info info;
2195 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2196 if (errno == ENOENT) {
2197 /* The module was removed out from underneath us. */
2200 perror_msg("query_module: QM_INFO: %s", mn);
2204 syms = xmalloc(bufsize = 1024);
2206 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2209 syms = xrealloc(syms, bufsize = ret);
2210 goto retry_mod_sym_load;
2212 /* The module was removed out from underneath us. */
2215 perror_msg("query_module: QM_SYMBOLS: %s", mn);
2222 m->addr = info.addr;
2226 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2227 s->name += (unsigned long) syms;
2231 /* Collect the kernel's symbols. */
2233 syms = xmalloc(bufsize = 16 * 1024);
2234 retry_kern_sym_load:
2235 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2236 if (errno == ENOSPC) {
2237 syms = xrealloc(syms, bufsize = ret);
2238 goto retry_kern_sym_load;
2240 perror_msg("kernel: QM_SYMBOLS");
2243 nksyms = nsyms = ret;
2246 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2247 s->name += (unsigned long) syms;
2253 /* Return the kernel symbol checksum version, or zero if not used. */
2255 static int new_is_kernel_checksummed(void)
2257 struct new_module_symbol *s;
2260 /* Using_Versions is not the first symbol, but it should be in there. */
2262 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2263 if (strcmp((char *) s->name, "Using_Versions") == 0)
2270 static int new_create_this_module(struct obj_file *f, const char *m_name)
2272 struct obj_section *sec;
2274 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2275 sizeof(struct new_module));
2276 memset(sec->contents, 0, sizeof(struct new_module));
2278 obj_add_symbol(f, "__this_module", -1,
2279 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2280 sizeof(struct new_module));
2282 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2289 static int new_create_module_ksymtab(struct obj_file *f)
2291 struct obj_section *sec;
2294 /* We must always add the module references. */
2296 if (n_ext_modules_used) {
2297 struct new_module_ref *dep;
2298 struct obj_symbol *tm;
2300 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2301 (sizeof(struct new_module_ref)
2302 * n_ext_modules_used));
2306 tm = obj_find_symbol(f, "__this_module");
2307 dep = (struct new_module_ref *) sec->contents;
2308 for (i = 0; i < n_ext_modules; ++i)
2309 if (ext_modules[i].used) {
2310 dep->dep = ext_modules[i].addr;
2311 obj_symbol_patch(f, sec->idx,
2312 (char *) &dep->ref - sec->contents, tm);
2318 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2323 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2326 /* We don't want to export symbols residing in sections that
2327 aren't loaded. There are a number of these created so that
2328 we make sure certain module options don't appear twice. */
2330 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2332 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2334 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2335 struct obj_symbol *sym;
2336 for (sym = f->symtab[i]; sym; sym = sym->next)
2337 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2338 && sym->secidx <= SHN_HIRESERVE
2339 && (sym->secidx >= SHN_LORESERVE
2340 || loaded[sym->secidx])) {
2341 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2343 obj_symbol_patch(f, sec->idx, ofs, sym);
2344 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2351 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2359 new_init_module(const char *m_name, struct obj_file *f,
2360 unsigned long m_size)
2362 struct new_module *module;
2363 struct obj_section *sec;
2368 sec = obj_find_section(f, ".this");
2369 module = (struct new_module *) sec->contents;
2370 m_addr = sec->header.sh_addr;
2372 module->size_of_struct = sizeof(*module);
2373 module->size = m_size;
2374 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2376 sec = obj_find_section(f, "__ksymtab");
2377 if (sec && sec->header.sh_size) {
2378 module->syms = sec->header.sh_addr;
2379 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2382 if (n_ext_modules_used) {
2383 sec = obj_find_section(f, ".kmodtab");
2384 module->deps = sec->header.sh_addr;
2385 module->ndeps = n_ext_modules_used;
2389 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2391 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2393 sec = obj_find_section(f, "__ex_table");
2395 module->ex_table_start = sec->header.sh_addr;
2396 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2399 sec = obj_find_section(f, ".text.init");
2401 module->runsize = sec->header.sh_addr - m_addr;
2403 sec = obj_find_section(f, ".data.init");
2405 if (!module->runsize ||
2406 module->runsize > sec->header.sh_addr - m_addr)
2407 module->runsize = sec->header.sh_addr - m_addr;
2410 if (!arch_init_module(f, module))
2413 /* Whew! All of the initialization is complete. Collect the final
2414 module image and give it to the kernel. */
2416 image = xmalloc(m_size);
2417 obj_create_image(f, image);
2419 ret = new_sys_init_module(m_name, (struct new_module *) image);
2421 perror_msg("init_module: %s", m_name);
2430 #define new_init_module(x, y, z) TRUE
2431 #define new_create_this_module(x, y) 0
2432 #define new_create_module_ksymtab(x)
2433 #define query_module(v, w, x, y, z) -1
2435 #endif /* BB_FEATURE_NEW_MODULE_INTERFACE */
2438 /*======================================================================*/
2441 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2444 struct obj_string_patch *p;
2445 struct obj_section *strsec;
2446 size_t len = strlen(string) + 1;
2449 p = xmalloc(sizeof(*p));
2450 p->next = f->string_patches;
2451 p->reloc_secidx = secidx;
2452 p->reloc_offset = offset;
2453 f->string_patches = p;
2455 strsec = obj_find_section(f, ".kstrtab");
2456 if (strsec == NULL) {
2457 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2458 p->string_offset = 0;
2459 loc = strsec->contents;
2461 p->string_offset = strsec->header.sh_size;
2462 loc = obj_extend_section(strsec, len);
2464 memcpy(loc, string, len);
2470 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2471 struct obj_symbol *sym)
2473 struct obj_symbol_patch *p;
2475 p = xmalloc(sizeof(*p));
2476 p->next = f->symbol_patches;
2477 p->reloc_secidx = secidx;
2478 p->reloc_offset = offset;
2480 f->symbol_patches = p;
2485 int obj_check_undefineds(struct obj_file *f)
2490 for (i = 0; i < HASH_BUCKETS; ++i) {
2491 struct obj_symbol *sym;
2492 for (sym = f->symtab[i]; sym; sym = sym->next)
2493 if (sym->secidx == SHN_UNDEF) {
2494 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2495 sym->secidx = SHN_ABS;
2498 error_msg("unresolved symbol %s", sym->name);
2507 void obj_allocate_commons(struct obj_file *f)
2509 struct common_entry {
2510 struct common_entry *next;
2511 struct obj_symbol *sym;
2512 } *common_head = NULL;
2516 for (i = 0; i < HASH_BUCKETS; ++i) {
2517 struct obj_symbol *sym;
2518 for (sym = f->symtab[i]; sym; sym = sym->next)
2519 if (sym->secidx == SHN_COMMON) {
2520 /* Collect all COMMON symbols and sort them by size so as to
2521 minimize space wasted by alignment requirements. */
2523 struct common_entry **p, *n;
2524 for (p = &common_head; *p; p = &(*p)->next)
2525 if (sym->size <= (*p)->sym->size)
2528 n = alloca(sizeof(*n));
2536 for (i = 1; i < f->local_symtab_size; ++i) {
2537 struct obj_symbol *sym = f->local_symtab[i];
2538 if (sym && sym->secidx == SHN_COMMON) {
2539 struct common_entry **p, *n;
2540 for (p = &common_head; *p; p = &(*p)->next)
2541 if (sym == (*p)->sym)
2543 else if (sym->size < (*p)->sym->size) {
2544 n = alloca(sizeof(*n));
2554 /* Find the bss section. */
2555 for (i = 0; i < f->header.e_shnum; ++i)
2556 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2559 /* If for some reason there hadn't been one, create one. */
2560 if (i == f->header.e_shnum) {
2561 struct obj_section *sec;
2563 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2564 f->sections[i] = sec = arch_new_section();
2565 f->header.e_shnum = i + 1;
2567 memset(sec, 0, sizeof(*sec));
2568 sec->header.sh_type = SHT_PROGBITS;
2569 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2574 /* Allocate the COMMONS. */
2576 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2577 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2578 struct common_entry *c;
2580 for (c = common_head; c; c = c->next) {
2581 ElfW(Addr) align = c->sym->value;
2583 if (align > max_align)
2585 if (bss_size & (align - 1))
2586 bss_size = (bss_size | (align - 1)) + 1;
2589 c->sym->value = bss_size;
2591 bss_size += c->sym->size;
2594 f->sections[i]->header.sh_size = bss_size;
2595 f->sections[i]->header.sh_addralign = max_align;
2599 /* For the sake of patch relocation and parameter initialization,
2600 allocate zeroed data for NOBITS sections now. Note that after
2601 this we cannot assume NOBITS are really empty. */
2602 for (i = 0; i < f->header.e_shnum; ++i) {
2603 struct obj_section *s = f->sections[i];
2604 if (s->header.sh_type == SHT_NOBITS) {
2605 if (s->header.sh_size != 0)
2606 s->contents = memset(xmalloc(s->header.sh_size),
2607 0, s->header.sh_size);
2611 s->header.sh_type = SHT_PROGBITS;
2616 unsigned long obj_load_size(struct obj_file *f)
2618 unsigned long dot = 0;
2619 struct obj_section *sec;
2621 /* Finalize the positions of the sections relative to one another. */
2623 for (sec = f->load_order; sec; sec = sec->load_next) {
2626 align = sec->header.sh_addralign;
2627 if (align && (dot & (align - 1)))
2628 dot = (dot | (align - 1)) + 1;
2630 sec->header.sh_addr = dot;
2631 dot += sec->header.sh_size;
2637 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2639 int i, n = f->header.e_shnum;
2642 /* Finalize the addresses of the sections. */
2645 for (i = 0; i < n; ++i)
2646 f->sections[i]->header.sh_addr += base;
2648 /* And iterate over all of the relocations. */
2650 for (i = 0; i < n; ++i) {
2651 struct obj_section *relsec, *symsec, *targsec, *strsec;
2652 ElfW(RelM) * rel, *relend;
2656 relsec = f->sections[i];
2657 if (relsec->header.sh_type != SHT_RELM)
2660 symsec = f->sections[relsec->header.sh_link];
2661 targsec = f->sections[relsec->header.sh_info];
2662 strsec = f->sections[symsec->header.sh_link];
2664 rel = (ElfW(RelM) *) relsec->contents;
2665 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2666 symtab = (ElfW(Sym) *) symsec->contents;
2667 strtab = (const char *) strsec->contents;
2669 for (; rel < relend; ++rel) {
2670 ElfW(Addr) value = 0;
2671 struct obj_symbol *intsym = NULL;
2672 unsigned long symndx;
2673 ElfW(Sym) * extsym = 0;
2676 /* Attempt to find a value to use for this relocation. */
2678 symndx = ELFW(R_SYM) (rel->r_info);
2680 /* Note we've already checked for undefined symbols. */
2682 extsym = &symtab[symndx];
2683 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2684 /* Local symbols we look up in the local table to be sure
2685 we get the one that is really intended. */
2686 intsym = f->local_symtab[symndx];
2688 /* Others we look up in the hash table. */
2690 if (extsym->st_name)
2691 name = strtab + extsym->st_name;
2693 name = f->sections[extsym->st_shndx]->name;
2694 intsym = obj_find_symbol(f, name);
2697 value = obj_symbol_final_value(f, intsym);
2698 intsym->referenced = 1;
2700 #if SHT_RELM == SHT_RELA
2701 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2702 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2703 if (!extsym || !extsym->st_name ||
2704 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2706 value += rel->r_addend;
2710 switch (arch_apply_relocation
2711 (f, targsec, symsec, intsym, rel, value)) {
2715 case obj_reloc_overflow:
2716 errmsg = "Relocation overflow";
2718 case obj_reloc_dangerous:
2719 errmsg = "Dangerous relocation";
2721 case obj_reloc_unhandled:
2722 errmsg = "Unhandled relocation";
2725 error_msg("%s of type %ld for %s", errmsg,
2726 (long) ELFW(R_TYPE) (rel->r_info),
2727 strtab + extsym->st_name);
2729 error_msg("%s of type %ld", errmsg,
2730 (long) ELFW(R_TYPE) (rel->r_info));
2738 /* Finally, take care of the patches. */
2740 if (f->string_patches) {
2741 struct obj_string_patch *p;
2742 struct obj_section *strsec;
2743 ElfW(Addr) strsec_base;
2744 strsec = obj_find_section(f, ".kstrtab");
2745 strsec_base = strsec->header.sh_addr;
2747 for (p = f->string_patches; p; p = p->next) {
2748 struct obj_section *targsec = f->sections[p->reloc_secidx];
2749 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2750 = strsec_base + p->string_offset;
2754 if (f->symbol_patches) {
2755 struct obj_symbol_patch *p;
2757 for (p = f->symbol_patches; p; p = p->next) {
2758 struct obj_section *targsec = f->sections[p->reloc_secidx];
2759 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2760 = obj_symbol_final_value(f, p->sym);
2767 int obj_create_image(struct obj_file *f, char *image)
2769 struct obj_section *sec;
2770 ElfW(Addr) base = f->baseaddr;
2772 for (sec = f->load_order; sec; sec = sec->load_next) {
2775 if (sec->header.sh_size == 0)
2778 secimg = image + (sec->header.sh_addr - base);
2780 /* Note that we allocated data for NOBITS sections earlier. */
2781 memcpy(secimg, sec->contents, sec->header.sh_size);
2787 /*======================================================================*/
2789 struct obj_file *obj_load(FILE * fp)
2792 ElfW(Shdr) * section_headers;
2796 /* Read the file header. */
2798 f = arch_new_file();
2799 memset(f, 0, sizeof(*f));
2800 f->symbol_cmp = strcmp;
2801 f->symbol_hash = obj_elf_hash;
2802 f->load_order_search_start = &f->load_order;
2804 fseek(fp, 0, SEEK_SET);
2805 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2806 perror_msg("error reading ELF header");
2810 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2811 || f->header.e_ident[EI_MAG1] != ELFMAG1
2812 || f->header.e_ident[EI_MAG2] != ELFMAG2
2813 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2814 error_msg("not an ELF file");
2817 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2818 || f->header.e_ident[EI_DATA] != ELFDATAM
2819 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2820 || !MATCH_MACHINE(f->header.e_machine)) {
2821 error_msg("ELF file not for this architecture");
2824 if (f->header.e_type != ET_REL) {
2825 error_msg("ELF file not a relocatable object");
2829 /* Read the section headers. */
2831 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2832 error_msg("section header size mismatch: %lu != %lu",
2833 (unsigned long) f->header.e_shentsize,
2834 (unsigned long) sizeof(ElfW(Shdr)));
2838 shnum = f->header.e_shnum;
2839 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2840 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2842 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2843 fseek(fp, f->header.e_shoff, SEEK_SET);
2844 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2845 perror_msg("error reading ELF section headers");
2849 /* Read the section data. */
2851 for (i = 0; i < shnum; ++i) {
2852 struct obj_section *sec;
2854 f->sections[i] = sec = arch_new_section();
2855 memset(sec, 0, sizeof(*sec));
2857 sec->header = section_headers[i];
2860 switch (sec->header.sh_type) {
2871 if (sec->header.sh_size > 0) {
2872 sec->contents = xmalloc(sec->header.sh_size);
2873 fseek(fp, sec->header.sh_offset, SEEK_SET);
2874 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2875 perror_msg("error reading ELF section data");
2879 sec->contents = NULL;
2883 #if SHT_RELM == SHT_REL
2885 error_msg("RELA relocations not supported on this architecture");
2889 error_msg("REL relocations not supported on this architecture");
2894 if (sec->header.sh_type >= SHT_LOPROC) {
2895 /* Assume processor specific section types are debug
2896 info and can safely be ignored. If this is ever not
2897 the case (Hello MIPS?), don't put ifdefs here but
2898 create an arch_load_proc_section(). */
2902 error_msg("can't handle sections of type %ld",
2903 (long) sec->header.sh_type);
2908 /* Do what sort of interpretation as needed by each section. */
2910 shstrtab = f->sections[f->header.e_shstrndx]->contents;
2912 for (i = 0; i < shnum; ++i) {
2913 struct obj_section *sec = f->sections[i];
2914 sec->name = shstrtab + sec->header.sh_name;
2917 for (i = 0; i < shnum; ++i) {
2918 struct obj_section *sec = f->sections[i];
2920 if (sec->header.sh_flags & SHF_ALLOC)
2921 obj_insert_section_load_order(f, sec);
2923 switch (sec->header.sh_type) {
2926 unsigned long nsym, j;
2930 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
2931 error_msg("symbol size mismatch: %lu != %lu",
2932 (unsigned long) sec->header.sh_entsize,
2933 (unsigned long) sizeof(ElfW(Sym)));
2937 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
2938 strtab = f->sections[sec->header.sh_link]->contents;
2939 sym = (ElfW(Sym) *) sec->contents;
2941 /* Allocate space for a table of local symbols. */
2942 j = f->local_symtab_size = sec->header.sh_info;
2943 f->local_symtab = xmalloc(j *=
2944 sizeof(struct obj_symbol *));
2945 memset(f->local_symtab, 0, j);
2947 /* Insert all symbols into the hash table. */
2948 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
2951 name = strtab + sym->st_name;
2953 name = f->sections[sym->st_shndx]->name;
2955 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
2956 sym->st_value, sym->st_size);
2962 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
2963 error_msg("relocation entry size mismatch: %lu != %lu",
2964 (unsigned long) sec->header.sh_entsize,
2965 (unsigned long) sizeof(ElfW(RelM)));
2975 static void hide_special_symbols(struct obj_file *f)
2977 static const char *const specials[] = {
2984 struct obj_symbol *sym;
2985 const char *const *p;
2987 for (p = specials; *p; ++p)
2988 if ((sym = obj_find_symbol(f, *p)) != NULL)
2990 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
2995 extern int insmod_main( int argc, char **argv)
3002 unsigned long m_size;
3007 char m_name[BUFSIZ + 1] = "\0";
3008 int exit_status = EXIT_FAILURE;
3010 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3012 char k_strversion[STRVERSIONLEN];
3013 char m_strversion[STRVERSIONLEN];
3018 /* Parse any options */
3019 while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
3021 case 'f': /* force loading */
3022 flag_force_load = 1;
3024 case 'k': /* module loaded by kerneld, auto-cleanable */
3027 case 'v': /* verbose output */
3030 case 'x': /* do not export externs */
3033 case 'o': /* name the output module */
3034 strncpy(m_name, optarg, BUFSIZ);
3036 case 'L': /* Stub warning */
3037 /* This is needed for compatibility with modprobe.
3038 * In theory, this does locking, but we don't do
3039 * that. So be careful and plan your life around not
3040 * loading the same module 50 times concurrently. */
3047 if (argv[optind] == NULL) {
3051 /* Grab the module name */
3052 if ((tmp = strrchr(argv[optind], '/')) != NULL) {
3059 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3061 strncpy(m_fullName, tmp, len);
3062 if (*m_name == '\0') {
3063 strcpy(m_name, m_fullName);
3065 strcat(m_fullName, ".o");
3067 /* Get a filedesc for the module */
3068 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3069 (fp = fopen(argv[optind], "r")) == NULL) {
3070 /* Hmpf. Could not open it. Search through _PATH_MODULES to find a module named m_name */
3071 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
3072 findNamedModule, 0, m_fullName) == FALSE)
3074 if (m_filename[0] == '\0'
3075 || ((fp = fopen(m_filename, "r")) == NULL))
3077 error_msg("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3078 return EXIT_FAILURE;
3081 error_msg_and_die("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3083 memcpy(m_filename, argv[optind], strlen(argv[optind]));
3086 if ((f = obj_load(fp)) == NULL)
3087 perror_msg_and_die("Could not load the module");
3089 if (get_modinfo_value(f, "kernel_version") == NULL)
3094 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3095 /* Version correspondence? */
3097 k_version = get_kernel_version(k_strversion);
3098 if (m_has_modinfo) {
3099 m_version = new_get_module_version(f, m_strversion);
3101 m_version = old_get_module_version(f, m_strversion);
3102 if (m_version == -1) {
3103 error_msg("couldn't find the kernel version the module was "
3109 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3110 if (flag_force_load) {
3111 error_msg("Warning: kernel-module version mismatch\n"
3112 "\t%s was compiled for kernel version %s\n"
3113 "\twhile this kernel is version %s",
3114 m_filename, m_strversion, k_strversion);
3116 error_msg("kernel-module version mismatch\n"
3117 "\t%s was compiled for kernel version %s\n"
3118 "\twhile this kernel is version %s.",
3119 m_filename, m_strversion, k_strversion);
3124 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3126 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3128 if (k_new_syscalls) {
3129 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
3130 if (!new_get_kernel_symbols())
3132 k_crcs = new_is_kernel_checksummed();
3134 error_msg("Not configured to support new kernels");
3138 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
3139 if (!old_get_kernel_symbols(m_name))
3141 k_crcs = old_is_kernel_checksummed();
3143 error_msg("Not configured to support old kernels");
3148 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3150 m_crcs = new_is_module_checksummed(f);
3152 m_crcs = old_is_module_checksummed(f);
3154 if (m_crcs != k_crcs)
3155 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3156 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3158 /* Let the module know about the kernel symbols. */
3159 add_kernel_symbols(f);
3161 /* Allocate common symbols, symbol tables, and string tables. */
3164 ? !new_create_this_module(f, m_name)
3165 : !old_create_mod_use_count(f))
3170 if (!obj_check_undefineds(f)) {
3173 obj_allocate_commons(f);
3175 /* done with the module name, on to the optional var=value arguments */
3178 if (optind < argc) {
3180 ? !new_process_module_arguments(f, argc - optind, argv + optind)
3181 : !old_process_module_arguments(f, argc - optind, argv + optind))
3188 hide_special_symbols(f);
3191 new_create_module_ksymtab(f);
3193 /* Find current size of the module */
3194 m_size = obj_load_size(f);
3197 m_addr = create_module(m_name, m_size);
3198 if (m_addr==-1) switch (errno) {
3200 error_msg("A module named %s already exists", m_name);
3203 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3207 perror_msg("create_module: %s", m_name);
3211 if (!obj_relocate(f, m_addr)) {
3212 delete_module(m_name);
3217 ? !new_init_module(m_name, f, m_size)
3218 : !old_init_module(m_name, f, m_size))
3220 delete_module(m_name);
3224 exit_status = EXIT_SUCCESS;
3228 return(exit_status);