1 /* vi: set sw=4 ts=4: */
3 * Mini insmod implementation for busybox
5 * Copyright (C) 1999,2000 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>
7 * and Ron Alder <alder@lineo.com>
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
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.
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.
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
41 #include <sys/utsname.h>
42 #include <sys/syscall.h>
44 //----------------------------------------------------------------------------
45 //--------modutils module.h, lines 45-242
46 //----------------------------------------------------------------------------
48 /* Definitions for the Linux module syscall interface.
49 Copyright 1996, 1997 Linux International.
51 Contributed by Richard Henderson <rth@tamu.edu>
53 This file is part of the Linux modutils.
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.
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.
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. */
70 #ifndef MODUTILS_MODULE_H
71 #define MODUTILS_MODULE_H 1
73 #ident "$Id: insmod.c,v 1.8 2000/06/12 23:11:16 andersen Exp $"
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. */
80 /*======================================================================*/
81 /* The structures used by Linux 2.0. */
83 /* The symbol format used by get_kernel_syms(2). */
92 unsigned long module; /* kernel addresses */
96 struct old_module_symbol
102 struct old_symbol_table
104 int size; /* total, including string table!!! */
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 */
111 struct old_mod_routines
114 unsigned long cleanup;
120 unsigned long ref; /* the list of modules that refer to me */
121 unsigned long symtab;
123 int size; /* size of module in pages */
124 unsigned long addr; /* address of module */
126 unsigned long cleanup; /* cleanup routine */
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... */
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 *);
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). */
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
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
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
159 /*======================================================================*/
160 /* The structures used in Linux 2.1. */
162 /* Note: new_module_symbol does not use tgt_long intentionally */
163 struct new_module_symbol
169 struct new_module_persist;
171 struct new_module_ref
173 unsigned tgt_long dep; /* kernel addresses */
174 unsigned tgt_long ref;
175 unsigned tgt_long next_ref;
180 unsigned tgt_long size_of_struct; /* == sizeof(module) */
181 unsigned tgt_long next;
182 unsigned tgt_long name;
183 unsigned tgt_long size;
186 unsigned tgt_long flags; /* AUTOCLEAN et al */
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;
199 unsigned tgt_long gp;
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;
208 struct new_module_info
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
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,
227 /* Values for query_module's which. */
235 /*======================================================================*/
236 /* The system calls unchanged between 2.0 and 2.1. */
238 unsigned long create_module(const char *, size_t);
239 int delete_module(const char *);
242 #endif /* module.h */
244 //----------------------------------------------------------------------------
245 //--------end of modutils module.h
246 //----------------------------------------------------------------------------
250 //----------------------------------------------------------------------------
251 //--------modutils obj.h, lines 253-462
252 //----------------------------------------------------------------------------
254 /* Elf object file loading and relocation routines.
255 Copyright 1996, 1997 Linux International.
257 Contributed by Richard Henderson <rth@tamu.edu>
259 This file is part of the Linux modutils.
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.
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.
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. */
276 #ifndef MODUTILS_OBJ_H
277 #define MODUTILS_OBJ_H 1
279 #ident "$Id: insmod.c,v 1.8 2000/06/12 23:11:16 andersen Exp $"
281 /* The relocatable object is manipulated using elfin types. */
287 /* Machine-specific elf macros for i386 et al. */
289 #define ELFCLASSM ELFCLASS32
290 #define ELFDATAM ELFDATA2LSB
292 #define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
294 #define SHT_RELM SHT_REL
295 #define Elf32_RelM Elf32_Rel
299 # if ELFCLASSM == ELFCLASS32
300 # define ElfW(x) Elf32_ ## x
301 # define ELFW(x) ELF32_ ## x
303 # define ElfW(x) Elf64_ ## x
304 # define ELFW(x) ELF64_ ## x
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))
313 #ifndef ELF64_ST_INFO
314 # define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
317 struct obj_string_patch;
318 struct obj_symbol_patch;
325 struct obj_section *load_next;
331 struct obj_symbol *next; /* hash table link */
335 int secidx; /* the defining section index/module */
337 int ksymidx; /* for export to the kernel symtab */
338 int referenced; /* actually used in the link */
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. */
345 #define HASH_BUCKETS 521
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];
371 struct obj_string_patch
373 struct obj_string_patch *next;
375 ElfW(Addr) reloc_offset;
376 ElfW(Addr) string_offset;
379 struct obj_symbol_patch
381 struct obj_symbol_patch *next;
383 ElfW(Addr) reloc_offset;
384 struct obj_symbol *sym;
388 /* Generic object manipulation routines. */
390 unsigned long obj_elf_hash(const char *);
392 unsigned long obj_elf_hash_n(const char *, unsigned long len);
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);
398 struct obj_symbol *obj_find_symbol (struct obj_file *f,
401 ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
402 struct obj_symbol *sym);
404 void obj_set_symbol_compare(struct obj_file *f,
405 int (*cmp)(const char *, const char *),
406 unsigned long (*hash)(const char *));
408 struct obj_section *obj_find_section (struct obj_file *f,
411 void obj_insert_section_load_order (struct obj_file *f,
412 struct obj_section *sec);
414 struct obj_section *obj_create_alloced_section (struct obj_file *f,
419 struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
424 void *obj_extend_section (struct obj_section *sec, unsigned long more);
426 int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
429 int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
430 struct obj_symbol *sym);
432 int obj_check_undefineds(struct obj_file *f);
434 void obj_allocate_commons(struct obj_file *f);
436 unsigned long obj_load_size (struct obj_file *f);
438 int obj_relocate (struct obj_file *f, ElfW(Addr) base);
440 struct obj_file *obj_load(FILE *f);
442 int obj_create_image (struct obj_file *f, char *image);
444 /* Architecture specific manipulation routines. */
446 struct obj_file *arch_new_file (void);
448 struct obj_section *arch_new_section (void);
450 struct obj_symbol *arch_new_symbol (void);
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);
458 int arch_create_got (struct obj_file *f);
461 int arch_init_module (struct obj_file *f, struct new_module *);
464 //----------------------------------------------------------------------------
465 //--------end of modutils obj.h
466 //----------------------------------------------------------------------------
472 #define _PATH_MODULES "/lib/modules"
473 #define STRVERSIONLEN 32
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"
479 /*======================================================================*/
481 int flag_force_load = 0;
482 int flag_autoclean = 0;
483 int flag_verbose = 0;
487 /*======================================================================*/
489 struct i386_got_entry {
491 unsigned offset_done:1;
492 unsigned reloc_done:1;
496 struct obj_file root;
497 struct obj_section *got;
501 struct obj_symbol root;
502 struct i386_got_entry gotent;
507 struct external_module {
512 struct new_module_symbol *syms;
515 struct new_module_symbol *ksyms;
518 struct external_module *ext_modules;
520 int n_ext_modules_used;
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)
533 _syscall1(int, delete_module, const char *, name)
535 extern int delete_module(const char *);
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,
543 unsigned long create_module(const char *name, size_t size)
545 long ret = _create_module(name, size);
547 if (ret == -1 && errno > 125) {
554 _syscall2(unsigned long, create_module, const char *, name, size_t, size)
556 static char m_filename[BUFSIZ + 1] = "\0";
557 static char m_fullName[BUFSIZ + 1] = "\0";
558 static const char insmod_usage[] =
559 "insmod [OPTION]... MODULE [symbol=value]...\n"
560 #ifndef BB_FEATURE_TRIVIAL_HELP
561 "\nLoads the specified kernel modules into the kernel.\n\n"
563 "\t-f\tForce module to load into the wrong kernel version.\n"
564 "\t-k\tMake module autoclean-able.\n"
565 "\t-v\tverbose output\n" "\t-x\tdo not export externs\n"
569 /*======================================================================*/
571 void *xrealloc(void *old, size_t size)
573 void *ptr = realloc(old, size);
575 perror("Out of memory");
582 static int findNamedModule(const char *fileName, struct stat *statbuf,
585 char *fullName = (char *) userDate;
588 if (fullName[0] == '\0')
591 char *tmp = strrchr(fileName, '/');
594 tmp = (char *) fileName;
597 if (check_wildcard_match(tmp, fullName) == TRUE) {
598 /* Stop searching if we find a match */
599 memcpy(m_filename, fileName, strlen(fileName));
607 /*======================================================================*/
609 struct obj_file *arch_new_file(void)
612 f = xmalloc(sizeof(*f));
617 struct obj_section *arch_new_section(void)
619 return xmalloc(sizeof(struct obj_section));
622 struct obj_symbol *arch_new_symbol(void)
624 struct i386_symbol *sym;
625 sym = xmalloc(sizeof(*sym));
626 memset(&sym->gotent, 0, sizeof(sym->gotent));
630 arch_apply_relocation(struct obj_file *f,
631 struct obj_section *targsec,
632 struct obj_section *symsec,
633 struct obj_symbol *sym,
634 Elf32_Rel * rel, Elf32_Addr v)
636 struct i386_file *ifile = (struct i386_file *) f;
637 struct i386_symbol *isym = (struct i386_symbol *) sym;
639 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset);
640 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
641 Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0;
643 enum obj_reloc ret = obj_reloc_ok;
645 switch (ELF32_R_TYPE(rel->r_info)) {
673 assert(isym != NULL);
674 if (!isym->gotent.reloc_done) {
675 isym->gotent.reloc_done = 1;
676 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
679 *loc += isym->gotent.offset;
688 ret = obj_reloc_unhandled;
695 int arch_create_got(struct obj_file *f)
697 struct i386_file *ifile = (struct i386_file *) f;
698 int i, n, offset = 0, gotneeded = 0;
700 n = ifile->root.header.e_shnum;
701 for (i = 0; i < n; ++i) {
702 struct obj_section *relsec, *symsec, *strsec;
703 Elf32_Rel *rel, *relend;
707 relsec = ifile->root.sections[i];
708 if (relsec->header.sh_type != SHT_REL)
711 symsec = ifile->root.sections[relsec->header.sh_link];
712 strsec = ifile->root.sections[symsec->header.sh_link];
714 rel = (Elf32_Rel *) relsec->contents;
715 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
716 symtab = (Elf32_Sym *) symsec->contents;
717 strtab = (const char *) strsec->contents;
719 for (; rel < relend; ++rel) {
721 struct i386_symbol *intsym;
724 switch (ELF32_R_TYPE(rel->r_info)) {
735 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
737 name = strtab + extsym->st_name;
739 name = f->sections[extsym->st_shndx]->name;
741 (struct i386_symbol *) obj_find_symbol(&ifile->root, name);
743 if (!intsym->gotent.offset_done) {
744 intsym->gotent.offset_done = 1;
745 intsym->gotent.offset = offset;
751 if (offset > 0 || gotneeded)
753 obj_create_alloced_section(&ifile->root, ".got", 4, offset);
758 int arch_init_module(struct obj_file *f, struct new_module *mod)
764 /*======================================================================*/
766 /* Standard ELF hash function. */
767 inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
776 if ((g = (h & 0xf0000000)) != 0) {
785 unsigned long obj_elf_hash(const char *name)
787 return obj_elf_hash_n(name, strlen(name));
790 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
791 /* Get the kernel version in the canonical integer form. */
793 static int get_kernel_version(char str[STRVERSIONLEN])
795 struct utsname uts_info;
799 if (uname(&uts_info) < 0)
801 strncpy(str, uts_info.release, STRVERSIONLEN);
802 p = uts_info.release;
804 a = strtoul(p, &p, 10);
807 b = strtoul(p + 1, &p, 10);
810 c = strtoul(p + 1, &q, 10);
814 return a << 16 | b << 8 | c;
817 /* String comparison for non-co-versioned kernel and module. */
819 static int ncv_strcmp(const char *a, const char *b)
821 size_t alen = strlen(a), blen = strlen(b);
823 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
824 return strncmp(a, b, alen);
825 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
826 return strncmp(a, b, blen);
831 /* String hashing for non-co-versioned kernel and module. Here
832 we are simply forced to drop the crc from the hash. */
834 static unsigned long ncv_symbol_hash(const char *str)
836 size_t len = strlen(str);
837 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
839 return obj_elf_hash_n(str, len);
843 obj_set_symbol_compare(struct obj_file *f,
844 int (*cmp) (const char *, const char *),
845 unsigned long (*hash) (const char *))
850 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
853 f->symbol_hash = hash;
855 memcpy(tmptab, f->symtab, sizeof(tmptab));
856 memset(f->symtab, 0, sizeof(f->symtab));
858 for (i = 0; i < HASH_BUCKETS; ++i)
859 for (sym = tmptab[i]; sym; sym = next) {
860 unsigned long h = hash(sym->name) % HASH_BUCKETS;
862 sym->next = f->symtab[h];
868 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
871 struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
872 unsigned long symidx, int info,
873 int secidx, ElfW(Addr) value,
876 struct obj_symbol *sym;
877 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
878 int n_type = ELFW(ST_TYPE) (info);
879 int n_binding = ELFW(ST_BIND) (info);
881 for (sym = f->symtab[hash]; sym; sym = sym->next)
882 if (f->symbol_cmp(sym->name, name) == 0) {
883 int o_secidx = sym->secidx;
884 int o_info = sym->info;
885 int o_type = ELFW(ST_TYPE) (o_info);
886 int o_binding = ELFW(ST_BIND) (o_info);
888 /* A redefinition! Is it legal? */
890 if (secidx == SHN_UNDEF)
892 else if (o_secidx == SHN_UNDEF)
894 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
895 /* Cope with local and global symbols of the same name
896 in the same object file, as might have been created
897 by ld -r. The only reason locals are now seen at this
898 level at all is so that we can do semi-sensible things
901 struct obj_symbol *nsym, **p;
903 nsym = arch_new_symbol();
904 nsym->next = sym->next;
907 /* Excise the old (local) symbol from the hash chain. */
908 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
912 } else if (n_binding == STB_LOCAL) {
913 /* Another symbol of the same name has already been defined.
914 Just add this to the local table. */
915 sym = arch_new_symbol();
918 f->local_symtab[symidx] = sym;
920 } else if (n_binding == STB_WEAK)
922 else if (o_binding == STB_WEAK)
924 /* Don't unify COMMON symbols with object types the programmer
926 else if (secidx == SHN_COMMON
927 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
929 else if (o_secidx == SHN_COMMON
930 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
933 /* Don't report an error if the symbol is coming from
934 the kernel or some external module. */
935 if (secidx <= SHN_HIRESERVE)
936 fprintf(stderr, "%s multiply defined\n", name);
941 /* Completely new symbol. */
942 sym = arch_new_symbol();
943 sym->next = f->symtab[hash];
944 f->symtab[hash] = sym;
947 if (ELFW(ST_BIND) (info) == STB_LOCAL)
948 f->local_symtab[symidx] = sym;
954 sym->secidx = secidx;
960 struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
962 struct obj_symbol *sym;
963 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
965 for (sym = f->symtab[hash]; sym; sym = sym->next)
966 if (f->symbol_cmp(sym->name, name) == 0)
973 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
976 if (sym->secidx >= SHN_LORESERVE)
979 return sym->value + f->sections[sym->secidx]->header.sh_addr;
981 /* As a special case, a NULL sym has value zero. */
986 struct obj_section *obj_find_section(struct obj_file *f, const char *name)
988 int i, n = f->header.e_shnum;
990 for (i = 0; i < n; ++i)
991 if (strcmp(f->sections[i]->name, name) == 0)
992 return f->sections[i];
997 static int obj_load_order_prio(struct obj_section *a)
999 unsigned long af, ac;
1001 af = a->header.sh_flags;
1004 if (a->name[0] != '.' || strlen(a->name) != 10 ||
1005 strcmp(a->name + 5, ".init"))
1009 if (!(af & SHF_WRITE))
1011 if (af & SHF_EXECINSTR)
1013 if (a->header.sh_type != SHT_NOBITS)
1020 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1022 struct obj_section **p;
1023 int prio = obj_load_order_prio(sec);
1024 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1025 if (obj_load_order_prio(*p) < prio)
1027 sec->load_next = *p;
1031 struct obj_section *obj_create_alloced_section(struct obj_file *f,
1033 unsigned long align,
1036 int newidx = f->header.e_shnum++;
1037 struct obj_section *sec;
1039 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1040 f->sections[newidx] = sec = arch_new_section();
1042 memset(sec, 0, sizeof(*sec));
1043 sec->header.sh_type = SHT_PROGBITS;
1044 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1045 sec->header.sh_size = size;
1046 sec->header.sh_addralign = align;
1050 sec->contents = xmalloc(size);
1052 obj_insert_section_load_order(f, sec);
1057 struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1059 unsigned long align,
1062 int newidx = f->header.e_shnum++;
1063 struct obj_section *sec;
1065 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1066 f->sections[newidx] = sec = arch_new_section();
1068 memset(sec, 0, sizeof(*sec));
1069 sec->header.sh_type = SHT_PROGBITS;
1070 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1071 sec->header.sh_size = size;
1072 sec->header.sh_addralign = align;
1076 sec->contents = xmalloc(size);
1078 sec->load_next = f->load_order;
1079 f->load_order = sec;
1080 if (f->load_order_search_start == &f->load_order)
1081 f->load_order_search_start = &sec->load_next;
1086 void *obj_extend_section(struct obj_section *sec, unsigned long more)
1088 unsigned long oldsize = sec->header.sh_size;
1089 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1090 return sec->contents + oldsize;
1095 /* Conditionally add the symbols from the given symbol set to the
1101 int idx, struct new_module_symbol *syms, size_t nsyms)
1103 struct new_module_symbol *s;
1107 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1109 /* Only add symbols that are already marked external. If we
1110 override locals we may cause problems for argument initialization.
1111 We will also create a false dependency on the module. */
1112 struct obj_symbol *sym;
1114 sym = obj_find_symbol(f, (char *) s->name);
1115 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1116 sym = obj_add_symbol(f, (char *) s->name, -1,
1117 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1119 /* Did our symbol just get installed? If so, mark the
1120 module as "used". */
1121 if (sym->secidx == idx)
1129 static void add_kernel_symbols(struct obj_file *f)
1131 struct external_module *m;
1132 size_t i, nused = 0;
1134 /* Add module symbols first. */
1136 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1138 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1139 m->nsyms)) m->used = 1, ++nused;
1141 n_ext_modules_used = nused;
1143 /* And finally the symbols from the kernel proper. */
1146 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1149 static char *get_modinfo_value(struct obj_file *f, const char *key)
1151 struct obj_section *sec;
1152 char *p, *v, *n, *ep;
1153 size_t klen = strlen(key);
1155 sec = obj_find_section(f, ".modinfo");
1159 ep = p + sec->header.sh_size;
1162 n = strchr(p, '\0');
1164 if (v - p == klen && strncmp(p, key, klen) == 0)
1167 if (n - p == klen && strcmp(p, key) == 0)
1177 /*======================================================================*/
1178 /* Functions relating to module loading in pre 2.1 kernels. */
1181 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1185 struct obj_symbol *sym;
1189 if ((q = strchr(p, '=')) == NULL)
1193 sym = obj_find_symbol(f, p);
1195 /* Also check that the parameter was not resolved from the kernel. */
1196 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1197 fprintf(stderr, "symbol for parameter %s not found\n", p);
1201 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1203 /* Do C quoting if we begin with a ". */
1207 str = alloca(strlen(q));
1208 for (r = str, q++; *q != '"'; ++q, ++r) {
1211 "improperly terminated string argument for %s\n",
1214 } else if (*q == '\\')
1248 if (q[1] >= '0' && q[1] <= '7') {
1249 c = (c * 8) + *++q - '0';
1250 if (q[1] >= '0' && q[1] <= '7')
1251 c = (c * 8) + *++q - '0';
1264 obj_string_patch(f, sym->secidx, sym->value, str);
1265 } else if (*q >= '0' && *q <= '9') {
1267 *loc++ = strtoul(q, &q, 0);
1268 while (*q++ == ',');
1270 char *contents = f->sections[sym->secidx]->contents;
1271 char *loc = contents + sym->value;
1272 char *r; /* To search for commas */
1274 /* Break the string with comas */
1275 while ((r = strchr(q, ',')) != (char *) NULL) {
1277 obj_string_patch(f, sym->secidx, loc - contents, q);
1278 loc += sizeof(char *);
1283 obj_string_patch(f, sym->secidx, loc - contents, q);
1292 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1293 static int old_is_module_checksummed(struct obj_file *f)
1295 return obj_find_symbol(f, "Using_Versions") != NULL;
1297 /* Get the module's kernel version in the canonical integer form. */
1300 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1302 struct obj_symbol *sym;
1306 sym = obj_find_symbol(f, "kernel_version");
1310 p = f->sections[sym->secidx]->contents + sym->value;
1311 strncpy(str, p, STRVERSIONLEN);
1313 a = strtoul(p, &p, 10);
1316 b = strtoul(p + 1, &p, 10);
1319 c = strtoul(p + 1, &q, 10);
1323 return a << 16 | b << 8 | c;
1326 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1328 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
1330 /* Fetch all the symbols and divvy them up as appropriate for the modules. */
1332 static int old_get_kernel_symbols(void)
1334 struct old_kernel_sym *ks, *k;
1335 struct new_module_symbol *s;
1336 struct external_module *mod;
1337 int nks, nms, nmod, i;
1339 nks = get_kernel_syms(NULL);
1341 perror("get_kernel_syms: %m");
1345 ks = k = xmalloc(nks * sizeof(*ks));
1347 if (get_kernel_syms(ks) != nks) {
1348 perror("inconsistency with get_kernel_syms -- is someone else "
1349 "playing with modules?");
1354 /* Collect the module information. */
1359 while (k->name[0] == '#' && k->name[1]) {
1360 struct old_kernel_sym *k2;
1361 struct new_module_symbol *s;
1363 /* Find out how many symbols this module has. */
1364 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1368 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1369 mod[nmod].name = k->name + 1;
1370 mod[nmod].addr = k->value;
1372 mod[nmod].nsyms = nms;
1373 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1375 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1376 s->name = (unsigned long) k->name;
1377 s->value = k->value;
1384 n_ext_modules = nmod + 1;
1386 /* Now collect the symbols for the kernel proper. */
1388 if (k->name[0] == '#')
1391 nksyms = nms = nks - (k - ks);
1392 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1394 for (i = 0; i < nms; ++i, ++s, ++k) {
1395 s->name = (unsigned long) k->name;
1396 s->value = k->value;
1402 /* Return the kernel symbol checksum version, or zero if not used. */
1404 static int old_is_kernel_checksummed(void)
1406 /* Using_Versions is the first symbol. */
1408 && strcmp((char *) ksyms[0].name,
1409 "Using_Versions") == 0) return ksyms[0].value;
1415 static int old_create_mod_use_count(struct obj_file *f)
1417 struct obj_section *sec;
1419 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1422 obj_add_symbol(f, "mod_use_count_", -1,
1423 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1430 old_init_module(const char *m_name, struct obj_file *f,
1431 unsigned long m_size)
1434 struct old_mod_routines routines;
1435 struct old_symbol_table *symtab;
1438 /* Create the symbol table */
1440 int nsyms = 0, strsize = 0, total;
1442 /* Size things first... */
1445 for (i = 0; i < HASH_BUCKETS; ++i) {
1446 struct obj_symbol *sym;
1447 for (sym = f->symtab[i]; sym; sym = sym->next)
1448 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1449 && sym->secidx <= SHN_HIRESERVE)
1451 sym->ksymidx = nsyms++;
1452 strsize += strlen(sym->name) + 1;
1457 total = (sizeof(struct old_symbol_table)
1458 + nsyms * sizeof(struct old_module_symbol)
1459 + n_ext_modules_used * sizeof(struct old_module_ref)
1461 symtab = xmalloc(total);
1462 symtab->size = total;
1463 symtab->n_symbols = nsyms;
1464 symtab->n_refs = n_ext_modules_used;
1466 if (flag_export && nsyms) {
1467 struct old_module_symbol *ksym;
1471 ksym = symtab->symbol;
1472 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1473 + n_ext_modules_used * sizeof(struct old_module_ref));
1475 for (i = 0; i < HASH_BUCKETS; ++i) {
1476 struct obj_symbol *sym;
1477 for (sym = f->symtab[i]; sym; sym = sym->next)
1478 if (sym->ksymidx >= 0) {
1479 ksym->addr = obj_symbol_final_value(f, sym);
1481 (unsigned long) str - (unsigned long) symtab;
1483 str = stpcpy(str, sym->name) + 1;
1489 if (n_ext_modules_used) {
1490 struct old_module_ref *ref;
1493 ref = (struct old_module_ref *)
1494 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1496 for (i = 0; i < n_ext_modules; ++i)
1497 if (ext_modules[i].used)
1498 ref++->module = ext_modules[i].addr;
1502 /* Fill in routines. */
1505 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1507 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1509 /* Whew! All of the initialization is complete. Collect the final
1510 module image and give it to the kernel. */
1512 image = xmalloc(m_size);
1513 obj_create_image(f, image);
1515 /* image holds the complete relocated module, accounting correctly for
1516 mod_use_count. However the old module kernel support assume that
1517 it is receiving something which does not contain mod_use_count. */
1518 ret = old_sys_init_module(m_name, image + sizeof(long),
1519 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1520 : 0), &routines, symtab);
1522 perror("init_module: %m");
1532 #define old_create_mod_use_count(x) TRUE
1533 #define old_init_module(x, y, z) TRUE
1535 #endif /* BB_FEATURE_INSMOD_OLD_KERNEL */
1539 /*======================================================================*/
1540 /* Functions relating to module loading after 2.1.18. */
1543 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1547 struct obj_symbol *sym;
1548 char *contents, *loc;
1552 if ((q = strchr(p, '=')) == NULL)
1555 key = alloca(q - p + 6);
1556 memcpy(key, "parm_", 5);
1557 memcpy(key + 5, p, q - p);
1560 p = get_modinfo_value(f, key);
1563 fprintf(stderr, "invalid parameter %s\n", key);
1567 sym = obj_find_symbol(f, key);
1569 /* Also check that the parameter was not resolved from the kernel. */
1570 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1571 fprintf(stderr, "symbol for parameter %s not found\n", key);
1576 min = strtoul(p, &p, 10);
1578 max = strtoul(p + 1, &p, 10);
1584 contents = f->sections[sym->secidx]->contents;
1585 loc = contents + sym->value;
1589 if ((*p == 's') || (*p == 'c')) {
1592 /* Do C quoting if we begin with a ", else slurp the lot. */
1596 str = alloca(strlen(q));
1597 for (r = str, q++; *q != '"'; ++q, ++r) {
1600 "improperly terminated string argument for %s\n",
1603 } else if (*q == '\\')
1637 if (q[1] >= '0' && q[1] <= '7') {
1638 c = (c * 8) + *++q - '0';
1639 if (q[1] >= '0' && q[1] <= '7')
1640 c = (c * 8) + *++q - '0';
1657 /* In this case, the string is not quoted. We will break
1658 it using the coma (like for ints). If the user wants to
1659 include comas in a string, he just has to quote it */
1661 /* Search the next coma */
1665 if (r != (char *) NULL) {
1666 /* Recopy the current field */
1667 str = alloca(r - q + 1);
1668 memcpy(str, q, r - q);
1670 /* I don't know if it is usefull, as the previous case
1671 doesn't null terminate the string ??? */
1674 /* Keep next fields */
1685 obj_string_patch(f, sym->secidx, loc - contents, str);
1686 loc += tgt_sizeof_char_p;
1688 /* Array of chars (in fact, matrix !) */
1689 long charssize; /* size of each member */
1691 /* Get the size of each member */
1692 /* Probably we should do that outside the loop ? */
1693 if (!isdigit(*(p + 1))) {
1695 "parameter type 'c' for %s must be followed by"
1696 " the maximum size\n", key);
1699 charssize = strtoul(p + 1, (char **) NULL, 10);
1702 if (strlen(str) >= charssize) {
1704 "string too long for %s (max %ld)\n", key,
1709 /* Copy to location */
1710 strcpy((char *) loc, str);
1714 long v = strtoul(q, &q, 0);
1721 loc += tgt_sizeof_short;
1725 loc += tgt_sizeof_int;
1729 loc += tgt_sizeof_long;
1733 fprintf(stderr, "unknown parameter type '%c' for %s\n",
1749 goto retry_end_of_value;
1753 fprintf(stderr, "too many values for %s (max %d)\n",
1761 fprintf(stderr, "invalid argument syntax for %s\n", key);
1768 fprintf(stderr, "too few values for %s (min %d)\n", key, min);
1778 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1779 static int new_is_module_checksummed(struct obj_file *f)
1781 const char *p = get_modinfo_value(f, "using_checksums");
1788 /* Get the module's kernel version in the canonical integer form. */
1791 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1796 p = get_modinfo_value(f, "kernel_version");
1799 strncpy(str, p, STRVERSIONLEN);
1801 a = strtoul(p, &p, 10);
1804 b = strtoul(p + 1, &p, 10);
1807 c = strtoul(p + 1, &q, 10);
1811 return a << 16 | b << 8 | c;
1814 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1817 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
1819 /* Fetch the loaded modules, and all currently exported symbols. */
1821 static int new_get_kernel_symbols(void)
1823 char *module_names, *mn;
1824 struct external_module *modules, *m;
1825 struct new_module_symbol *syms, *s;
1826 size_t ret, bufsize, nmod, nsyms, i, j;
1828 /* Collect the loaded modules. */
1830 module_names = xmalloc(bufsize = 256);
1832 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
1833 if (errno == ENOSPC) {
1834 module_names = xrealloc(module_names, bufsize = ret);
1835 goto retry_modules_load;
1837 perror("QM_MODULES: %m\n");
1841 n_ext_modules = nmod = ret;
1842 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
1843 memset(modules, 0, nmod * sizeof(*modules));
1845 /* Collect the modules' symbols. */
1847 for (i = 0, mn = module_names, m = modules;
1848 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
1849 struct new_module_info info;
1851 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
1852 if (errno == ENOENT) {
1853 /* The module was removed out from underneath us. */
1856 perror("query_module: QM_INFO: %m");
1860 syms = xmalloc(bufsize = 1024);
1862 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
1865 syms = xrealloc(syms, bufsize = ret);
1866 goto retry_mod_sym_load;
1868 /* The module was removed out from underneath us. */
1871 perror("query_module: QM_SYMBOLS: %m");
1878 m->addr = info.addr;
1882 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
1883 s->name += (unsigned long) syms;
1887 /* Collect the kernel's symbols. */
1889 syms = xmalloc(bufsize = 16 * 1024);
1890 retry_kern_sym_load:
1891 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
1892 if (errno == ENOSPC) {
1893 syms = xrealloc(syms, bufsize = ret);
1894 goto retry_kern_sym_load;
1896 perror("kernel: QM_SYMBOLS: %m");
1899 nksyms = nsyms = ret;
1902 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
1903 s->name += (unsigned long) syms;
1909 /* Return the kernel symbol checksum version, or zero if not used. */
1911 static int new_is_kernel_checksummed(void)
1913 struct new_module_symbol *s;
1916 /* Using_Versions is not the first symbol, but it should be in there. */
1918 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
1919 if (strcmp((char *) s->name, "Using_Versions") == 0)
1926 static int new_create_this_module(struct obj_file *f, const char *m_name)
1928 struct obj_section *sec;
1930 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
1931 sizeof(struct new_module));
1932 memset(sec->contents, 0, sizeof(struct new_module));
1934 obj_add_symbol(f, "__this_module", -1,
1935 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1936 sizeof(struct new_module));
1938 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
1945 static int new_create_module_ksymtab(struct obj_file *f)
1947 struct obj_section *sec;
1950 /* We must always add the module references. */
1952 if (n_ext_modules_used) {
1953 struct new_module_ref *dep;
1954 struct obj_symbol *tm;
1956 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
1957 (sizeof(struct new_module_ref)
1958 * n_ext_modules_used));
1962 tm = obj_find_symbol(f, "__this_module");
1963 dep = (struct new_module_ref *) sec->contents;
1964 for (i = 0; i < n_ext_modules; ++i)
1965 if (ext_modules[i].used) {
1966 dep->dep = ext_modules[i].addr;
1967 obj_symbol_patch(f, sec->idx,
1968 (char *) &dep->ref - sec->contents, tm);
1974 if (flag_export && !obj_find_section(f, "__ksymtab")) {
1979 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
1982 /* We don't want to export symbols residing in sections that
1983 aren't loaded. There are a number of these created so that
1984 we make sure certain module options don't appear twice. */
1986 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
1988 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
1990 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
1991 struct obj_symbol *sym;
1992 for (sym = f->symtab[i]; sym; sym = sym->next)
1993 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1994 && sym->secidx <= SHN_HIRESERVE
1995 && (sym->secidx >= SHN_LORESERVE
1996 || loaded[sym->secidx])) {
1997 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
1999 obj_symbol_patch(f, sec->idx, ofs, sym);
2000 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2007 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2015 new_init_module(const char *m_name, struct obj_file *f,
2016 unsigned long m_size)
2018 struct new_module *module;
2019 struct obj_section *sec;
2024 sec = obj_find_section(f, ".this");
2025 module = (struct new_module *) sec->contents;
2026 m_addr = sec->header.sh_addr;
2028 module->size_of_struct = sizeof(*module);
2029 module->size = m_size;
2030 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2032 sec = obj_find_section(f, "__ksymtab");
2033 if (sec && sec->header.sh_size) {
2034 module->syms = sec->header.sh_addr;
2035 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2038 if (n_ext_modules_used) {
2039 sec = obj_find_section(f, ".kmodtab");
2040 module->deps = sec->header.sh_addr;
2041 module->ndeps = n_ext_modules_used;
2045 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2047 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2049 sec = obj_find_section(f, "__ex_table");
2051 module->ex_table_start = sec->header.sh_addr;
2052 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2055 sec = obj_find_section(f, ".text.init");
2057 module->runsize = sec->header.sh_addr - m_addr;
2059 sec = obj_find_section(f, ".data.init");
2061 if (!module->runsize ||
2062 module->runsize > sec->header.sh_addr - m_addr)
2063 module->runsize = sec->header.sh_addr - m_addr;
2066 if (!arch_init_module(f, module))
2069 /* Whew! All of the initialization is complete. Collect the final
2070 module image and give it to the kernel. */
2072 image = xmalloc(m_size);
2073 obj_create_image(f, image);
2075 ret = new_sys_init_module(m_name, (struct new_module *) image);
2077 perror("init_module: %m");
2086 #define new_init_module(x, y, z) TRUE
2087 #define new_create_this_module(x, y) 0
2088 #define new_create_module_ksymtab(x)
2090 #endif /* BB_FEATURE_INSMOD_OLD_KERNEL */
2093 /*======================================================================*/
2096 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2099 struct obj_string_patch *p;
2100 struct obj_section *strsec;
2101 size_t len = strlen(string) + 1;
2104 p = xmalloc(sizeof(*p));
2105 p->next = f->string_patches;
2106 p->reloc_secidx = secidx;
2107 p->reloc_offset = offset;
2108 f->string_patches = p;
2110 strsec = obj_find_section(f, ".kstrtab");
2111 if (strsec == NULL) {
2112 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2113 p->string_offset = 0;
2114 loc = strsec->contents;
2116 p->string_offset = strsec->header.sh_size;
2117 loc = obj_extend_section(strsec, len);
2119 memcpy(loc, string, len);
2125 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2126 struct obj_symbol *sym)
2128 struct obj_symbol_patch *p;
2130 p = xmalloc(sizeof(*p));
2131 p->next = f->symbol_patches;
2132 p->reloc_secidx = secidx;
2133 p->reloc_offset = offset;
2135 f->symbol_patches = p;
2140 int obj_check_undefineds(struct obj_file *f)
2145 for (i = 0; i < HASH_BUCKETS; ++i) {
2146 struct obj_symbol *sym;
2147 for (sym = f->symtab[i]; sym; sym = sym->next)
2148 if (sym->secidx == SHN_UNDEF) {
2149 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2150 sym->secidx = SHN_ABS;
2153 fprintf(stderr, "unresolved symbol %s\n", sym->name);
2162 void obj_allocate_commons(struct obj_file *f)
2164 struct common_entry {
2165 struct common_entry *next;
2166 struct obj_symbol *sym;
2167 } *common_head = NULL;
2171 for (i = 0; i < HASH_BUCKETS; ++i) {
2172 struct obj_symbol *sym;
2173 for (sym = f->symtab[i]; sym; sym = sym->next)
2174 if (sym->secidx == SHN_COMMON) {
2175 /* Collect all COMMON symbols and sort them by size so as to
2176 minimize space wasted by alignment requirements. */
2178 struct common_entry **p, *n;
2179 for (p = &common_head; *p; p = &(*p)->next)
2180 if (sym->size <= (*p)->sym->size)
2183 n = alloca(sizeof(*n));
2191 for (i = 1; i < f->local_symtab_size; ++i) {
2192 struct obj_symbol *sym = f->local_symtab[i];
2193 if (sym && sym->secidx == SHN_COMMON) {
2194 struct common_entry **p, *n;
2195 for (p = &common_head; *p; p = &(*p)->next)
2196 if (sym == (*p)->sym)
2198 else if (sym->size < (*p)->sym->size) {
2199 n = alloca(sizeof(*n));
2209 /* Find the bss section. */
2210 for (i = 0; i < f->header.e_shnum; ++i)
2211 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2214 /* If for some reason there hadn't been one, create one. */
2215 if (i == f->header.e_shnum) {
2216 struct obj_section *sec;
2218 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2219 f->sections[i] = sec = arch_new_section();
2220 f->header.e_shnum = i + 1;
2222 memset(sec, 0, sizeof(*sec));
2223 sec->header.sh_type = SHT_PROGBITS;
2224 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2229 /* Allocate the COMMONS. */
2231 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2232 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2233 struct common_entry *c;
2235 for (c = common_head; c; c = c->next) {
2236 ElfW(Addr) align = c->sym->value;
2238 if (align > max_align)
2240 if (bss_size & (align - 1))
2241 bss_size = (bss_size | (align - 1)) + 1;
2244 c->sym->value = bss_size;
2246 bss_size += c->sym->size;
2249 f->sections[i]->header.sh_size = bss_size;
2250 f->sections[i]->header.sh_addralign = max_align;
2254 /* For the sake of patch relocation and parameter initialization,
2255 allocate zeroed data for NOBITS sections now. Note that after
2256 this we cannot assume NOBITS are really empty. */
2257 for (i = 0; i < f->header.e_shnum; ++i) {
2258 struct obj_section *s = f->sections[i];
2259 if (s->header.sh_type == SHT_NOBITS) {
2260 s->contents = memset(xmalloc(s->header.sh_size),
2261 0, s->header.sh_size);
2262 s->header.sh_type = SHT_PROGBITS;
2267 unsigned long obj_load_size(struct obj_file *f)
2269 unsigned long dot = 0;
2270 struct obj_section *sec;
2272 /* Finalize the positions of the sections relative to one another. */
2274 for (sec = f->load_order; sec; sec = sec->load_next) {
2277 align = sec->header.sh_addralign;
2278 if (align && (dot & (align - 1)))
2279 dot = (dot | (align - 1)) + 1;
2281 sec->header.sh_addr = dot;
2282 dot += sec->header.sh_size;
2288 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2290 int i, n = f->header.e_shnum;
2293 /* Finalize the addresses of the sections. */
2296 for (i = 0; i < n; ++i)
2297 f->sections[i]->header.sh_addr += base;
2299 /* And iterate over all of the relocations. */
2301 for (i = 0; i < n; ++i) {
2302 struct obj_section *relsec, *symsec, *targsec, *strsec;
2303 ElfW(RelM) * rel, *relend;
2307 relsec = f->sections[i];
2308 if (relsec->header.sh_type != SHT_RELM)
2311 symsec = f->sections[relsec->header.sh_link];
2312 targsec = f->sections[relsec->header.sh_info];
2313 strsec = f->sections[symsec->header.sh_link];
2315 rel = (ElfW(RelM) *) relsec->contents;
2316 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2317 symtab = (ElfW(Sym) *) symsec->contents;
2318 strtab = (const char *) strsec->contents;
2320 for (; rel < relend; ++rel) {
2321 ElfW(Addr) value = 0;
2322 struct obj_symbol *intsym = NULL;
2323 unsigned long symndx;
2324 ElfW(Sym) * extsym = 0;
2327 /* Attempt to find a value to use for this relocation. */
2329 symndx = ELFW(R_SYM) (rel->r_info);
2331 /* Note we've already checked for undefined symbols. */
2333 extsym = &symtab[symndx];
2334 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2335 /* Local symbols we look up in the local table to be sure
2336 we get the one that is really intended. */
2337 intsym = f->local_symtab[symndx];
2339 /* Others we look up in the hash table. */
2341 if (extsym->st_name)
2342 name = strtab + extsym->st_name;
2344 name = f->sections[extsym->st_shndx]->name;
2345 intsym = obj_find_symbol(f, name);
2348 value = obj_symbol_final_value(f, intsym);
2349 intsym->referenced = 1;
2351 #if SHT_RELM == SHT_RELA
2352 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2353 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2354 if (!extsym || !extsym->st_name ||
2355 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2357 value += rel->r_addend;
2361 switch (arch_apply_relocation
2362 (f, targsec, symsec, intsym, rel, value)) {
2366 case obj_reloc_overflow:
2367 errmsg = "Relocation overflow";
2369 case obj_reloc_dangerous:
2370 errmsg = "Dangerous relocation";
2372 case obj_reloc_unhandled:
2373 errmsg = "Unhandled relocation";
2376 fprintf(stderr, "%s of type %ld for %s\n", errmsg,
2377 (long) ELFW(R_TYPE) (rel->r_info),
2378 strtab + extsym->st_name);
2380 fprintf(stderr, "%s of type %ld\n", errmsg,
2381 (long) ELFW(R_TYPE) (rel->r_info));
2389 /* Finally, take care of the patches. */
2391 if (f->string_patches) {
2392 struct obj_string_patch *p;
2393 struct obj_section *strsec;
2394 ElfW(Addr) strsec_base;
2395 strsec = obj_find_section(f, ".kstrtab");
2396 strsec_base = strsec->header.sh_addr;
2398 for (p = f->string_patches; p; p = p->next) {
2399 struct obj_section *targsec = f->sections[p->reloc_secidx];
2400 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2401 = strsec_base + p->string_offset;
2405 if (f->symbol_patches) {
2406 struct obj_symbol_patch *p;
2408 for (p = f->symbol_patches; p; p = p->next) {
2409 struct obj_section *targsec = f->sections[p->reloc_secidx];
2410 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2411 = obj_symbol_final_value(f, p->sym);
2418 int obj_create_image(struct obj_file *f, char *image)
2420 struct obj_section *sec;
2421 ElfW(Addr) base = f->baseaddr;
2423 for (sec = f->load_order; sec; sec = sec->load_next) {
2426 if (sec->header.sh_size == 0)
2429 secimg = image + (sec->header.sh_addr - base);
2431 /* Note that we allocated data for NOBITS sections earlier. */
2432 memcpy(secimg, sec->contents, sec->header.sh_size);
2438 /*======================================================================*/
2440 struct obj_file *obj_load(FILE * fp)
2443 ElfW(Shdr) * section_headers;
2447 /* Read the file header. */
2449 f = arch_new_file();
2450 memset(f, 0, sizeof(*f));
2451 f->symbol_cmp = strcmp;
2452 f->symbol_hash = obj_elf_hash;
2453 f->load_order_search_start = &f->load_order;
2455 fseek(fp, 0, SEEK_SET);
2456 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2457 perror("error reading ELF header: %m");
2461 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2462 || f->header.e_ident[EI_MAG1] != ELFMAG1
2463 || f->header.e_ident[EI_MAG2] != ELFMAG2
2464 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2465 fprintf(stderr, "not an ELF file\n");
2468 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2469 || f->header.e_ident[EI_DATA] != ELFDATAM
2470 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2471 || !MATCH_MACHINE(f->header.e_machine)) {
2472 fprintf(stderr, "ELF file not for this architecture\n");
2475 if (f->header.e_type != ET_REL) {
2476 fprintf(stderr, "ELF file not a relocatable object\n");
2480 /* Read the section headers. */
2482 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2483 fprintf(stderr, "section header size mismatch: %lu != %lu\n",
2484 (unsigned long) f->header.e_shentsize,
2485 (unsigned long) sizeof(ElfW(Shdr)));
2489 shnum = f->header.e_shnum;
2490 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2491 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2493 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2494 fseek(fp, f->header.e_shoff, SEEK_SET);
2495 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2496 perror("error reading ELF section headers: %m");
2500 /* Read the section data. */
2502 for (i = 0; i < shnum; ++i) {
2503 struct obj_section *sec;
2505 f->sections[i] = sec = arch_new_section();
2506 memset(sec, 0, sizeof(*sec));
2508 sec->header = section_headers[i];
2511 switch (sec->header.sh_type) {
2522 if (sec->header.sh_size > 0) {
2523 sec->contents = xmalloc(sec->header.sh_size);
2524 fseek(fp, sec->header.sh_offset, SEEK_SET);
2525 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2527 "error reading ELF section data: %m\n");
2531 sec->contents = NULL;
2535 #if SHT_RELM == SHT_REL
2538 "RELA relocations not supported on this architecture\n");
2543 "REL relocations not supported on this architecture\n");
2548 if (sec->header.sh_type >= SHT_LOPROC) {
2549 /* Assume processor specific section types are debug
2550 info and can safely be ignored. If this is ever not
2551 the case (Hello MIPS?), don't put ifdefs here but
2552 create an arch_load_proc_section(). */
2556 fprintf(stderr, "can't handle sections of type %ld\n",
2557 (long) sec->header.sh_type);
2562 /* Do what sort of interpretation as needed by each section. */
2564 shstrtab = f->sections[f->header.e_shstrndx]->contents;
2566 for (i = 0; i < shnum; ++i) {
2567 struct obj_section *sec = f->sections[i];
2568 sec->name = shstrtab + sec->header.sh_name;
2571 for (i = 0; i < shnum; ++i) {
2572 struct obj_section *sec = f->sections[i];
2574 if (sec->header.sh_flags & SHF_ALLOC)
2575 obj_insert_section_load_order(f, sec);
2577 switch (sec->header.sh_type) {
2580 unsigned long nsym, j;
2584 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
2585 fprintf(stderr, "symbol size mismatch: %lu != %lu\n",
2586 (unsigned long) sec->header.sh_entsize,
2587 (unsigned long) sizeof(ElfW(Sym)));
2591 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
2592 strtab = f->sections[sec->header.sh_link]->contents;
2593 sym = (ElfW(Sym) *) sec->contents;
2595 /* Allocate space for a table of local symbols. */
2596 j = f->local_symtab_size = sec->header.sh_info;
2597 f->local_symtab = xmalloc(j *=
2598 sizeof(struct obj_symbol *));
2599 memset(f->local_symtab, 0, j);
2601 /* Insert all symbols into the hash table. */
2602 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
2605 name = strtab + sym->st_name;
2607 name = f->sections[sym->st_shndx]->name;
2609 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
2610 sym->st_value, sym->st_size);
2616 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
2618 "relocation entry size mismatch: %lu != %lu\n",
2619 (unsigned long) sec->header.sh_entsize,
2620 (unsigned long) sizeof(ElfW(RelM)));
2630 static void hide_special_symbols(struct obj_file *f)
2632 static const char *const specials[] = {
2639 struct obj_symbol *sym;
2640 const char *const *p;
2642 for (p = specials; *p; ++p)
2643 if ((sym = obj_find_symbol(f, *p)) != NULL)
2645 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
2650 extern int insmod_main( int argc, char **argv)
2656 unsigned long m_size;
2660 char m_name[BUFSIZ + 1] = "\0";
2661 int exit_status = FALSE;
2663 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2665 char k_strversion[STRVERSIONLEN];
2666 char m_strversion[STRVERSIONLEN];
2673 usage(insmod_usage);
2676 /* Parse any options */
2677 while (--argc > 0 && **(++argv) == '-') {
2678 while (*(++(*argv))) {
2680 case 'f': /* force loading */
2681 flag_force_load = 1;
2683 case 'k': /* module loaded by kerneld, auto-cleanable */
2686 case 'v': /* verbose output */
2689 case 'x': /* do not export externs */
2693 usage(insmod_usage);
2699 usage(insmod_usage);
2701 /* Grab the module name */
2702 if ((tmp = strrchr(*argv, '/')) != NULL) {
2709 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
2711 memcpy(m_name, tmp, len);
2712 strcpy(m_fullName, m_name);
2713 strcat(m_fullName, ".o");
2715 /* Get a filedesc for the module */
2716 if ((fp = fopen(*argv, "r")) == NULL) {
2717 /* Hmpf. Could not open it. Search through _PATH_MODULES to find a module named m_name */
2718 if (recursiveAction(_PATH_MODULES, TRUE, FALSE, FALSE,
2719 findNamedModule, 0, m_fullName) == TRUE)
2721 if (m_filename[0] == '\0'
2722 || ((fp = fopen(m_filename, "r")) == NULL))
2724 perror("No module by that name found in " _PATH_MODULES
2730 memcpy(m_filename, *argv, strlen(*argv));
2733 if ((f = obj_load(fp)) == NULL) {
2734 perror("Could not load the module\n");
2738 if (get_modinfo_value(f, "kernel_version") == NULL)
2743 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2744 /* Version correspondence? */
2746 k_version = get_kernel_version(k_strversion);
2747 if (m_has_modinfo) {
2748 m_version = new_get_module_version(f, m_strversion);
2750 m_version = old_get_module_version(f, m_strversion);
2751 if (m_version == -1) {
2753 "couldn't find the kernel version the module was compiled for\n");
2758 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
2759 if (flag_force_load) {
2760 fprintf(stderr, "Warning: kernel-module version mismatch\n"
2761 "\t%s was compiled for kernel version %s\n"
2762 "\twhile this kernel is version %s\n",
2763 m_filename, m_strversion, k_strversion);
2765 fprintf(stderr, "kernel-module version mismatch\n"
2766 "\t%s was compiled for kernel version %s\n"
2767 "\twhile this kernel is version %s.\n",
2768 m_filename, m_strversion, k_strversion);
2773 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2775 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
2777 if (k_new_syscalls) {
2778 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
2779 if (!new_get_kernel_symbols())
2781 k_crcs = new_is_kernel_checksummed();
2783 fprintf(stderr, "Not configured to support new kernels\n");
2787 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
2788 if (!old_get_kernel_symbols())
2790 k_crcs = old_is_kernel_checksummed();
2792 fprintf(stderr, "Not configured to support old kernels\n");
2797 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2799 m_crcs = new_is_module_checksummed(f);
2801 m_crcs = old_is_module_checksummed(f);
2803 if (m_crcs != k_crcs)
2804 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
2805 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2807 /* Let the module know about the kernel symbols. */
2808 add_kernel_symbols(f);
2810 /* Allocate common symbols, symbol tables, and string tables. */
2813 ? !new_create_this_module(f, m_name)
2814 : !old_create_mod_use_count(f))
2819 if (!obj_check_undefineds(f)) {
2822 obj_allocate_commons(f);
2824 if (optind < argc) {
2826 ? !new_process_module_arguments(f, argc - optind, argv + optind)
2827 : !old_process_module_arguments(f, argc - optind, argv + optind))
2834 hide_special_symbols(f);
2837 new_create_module_ksymtab(f);
2839 /* Find current size of the module */
2840 m_size = obj_load_size(f);
2844 m_addr = create_module(m_name, m_size);
2849 fprintf(stderr, "A module named %s already exists\n", m_name);
2853 "Can't allocate kernel memory for module; needed %lu bytes\n",
2857 perror("create_module: %m");
2861 if (!obj_relocate(f, m_addr)) {
2862 delete_module(m_name);
2867 ? !new_init_module(m_name, f, m_size)
2868 : !old_init_module(m_name, f, m_size))
2870 delete_module(m_name);