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
42 #include <sys/utsname.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.20 2000/08/01 18:16:56 kraai 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.20 2000/08/01 18:16:56 kraai 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)
532 #ifndef __NR_query_module
533 #define __NR_query_module 167
535 _syscall5(int, query_module, const char *, name, int, which,
536 void *, buf, size_t, bufsize, size_t*, ret);
538 _syscall1(int, delete_module, const char *, name)
540 extern int delete_module(const char *);
543 #if defined(__i386__) || defined(__m68k__) || defined(__arm__)
544 /* Jump through hoops to fixup error return codes */
545 #define __NR__create_module __NR_create_module
546 static inline _syscall2(long, _create_module, const char *, name, size_t,
548 unsigned long create_module(const char *name, size_t size)
550 long ret = _create_module(name, size);
552 if (ret == -1 && errno > 125) {
559 _syscall2(unsigned long, create_module, const char *, name, size_t, size)
561 static char m_filename[BUFSIZ + 1] = "\0";
562 static char m_fullName[BUFSIZ + 1] = "\0";
564 /*======================================================================*/
567 static int findNamedModule(const char *fileName, struct stat *statbuf,
570 char *fullName = (char *) userDate;
573 if (fullName[0] == '\0')
576 char *tmp = strrchr(fileName, '/');
579 tmp = (char *) fileName;
582 if (check_wildcard_match(tmp, fullName) == TRUE) {
583 /* Stop searching if we find a match */
584 memcpy(m_filename, fileName, strlen(fileName));
592 /*======================================================================*/
594 struct obj_file *arch_new_file(void)
597 f = xmalloc(sizeof(*f));
602 struct obj_section *arch_new_section(void)
604 return xmalloc(sizeof(struct obj_section));
607 struct obj_symbol *arch_new_symbol(void)
609 struct i386_symbol *sym;
610 sym = xmalloc(sizeof(*sym));
611 memset(&sym->gotent, 0, sizeof(sym->gotent));
615 arch_apply_relocation(struct obj_file *f,
616 struct obj_section *targsec,
617 struct obj_section *symsec,
618 struct obj_symbol *sym,
619 Elf32_Rel * rel, Elf32_Addr v)
621 struct i386_file *ifile = (struct i386_file *) f;
622 struct i386_symbol *isym = (struct i386_symbol *) sym;
624 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset);
625 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
626 Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0;
628 enum obj_reloc ret = obj_reloc_ok;
630 switch (ELF32_R_TYPE(rel->r_info)) {
658 assert(isym != NULL);
659 if (!isym->gotent.reloc_done) {
660 isym->gotent.reloc_done = 1;
661 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
664 *loc += isym->gotent.offset;
673 ret = obj_reloc_unhandled;
680 int arch_create_got(struct obj_file *f)
682 struct i386_file *ifile = (struct i386_file *) f;
683 int i, n, offset = 0, gotneeded = 0;
685 n = ifile->root.header.e_shnum;
686 for (i = 0; i < n; ++i) {
687 struct obj_section *relsec, *symsec, *strsec;
688 Elf32_Rel *rel, *relend;
692 relsec = ifile->root.sections[i];
693 if (relsec->header.sh_type != SHT_REL)
696 symsec = ifile->root.sections[relsec->header.sh_link];
697 strsec = ifile->root.sections[symsec->header.sh_link];
699 rel = (Elf32_Rel *) relsec->contents;
700 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
701 symtab = (Elf32_Sym *) symsec->contents;
702 strtab = (const char *) strsec->contents;
704 for (; rel < relend; ++rel) {
706 struct i386_symbol *intsym;
709 switch (ELF32_R_TYPE(rel->r_info)) {
720 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
722 name = strtab + extsym->st_name;
724 name = f->sections[extsym->st_shndx]->name;
726 (struct i386_symbol *) obj_find_symbol(&ifile->root, name);
728 if (!intsym->gotent.offset_done) {
729 intsym->gotent.offset_done = 1;
730 intsym->gotent.offset = offset;
736 if (offset > 0 || gotneeded)
738 obj_create_alloced_section(&ifile->root, ".got", 4, offset);
743 int arch_init_module(struct obj_file *f, struct new_module *mod)
749 /*======================================================================*/
751 /* Standard ELF hash function. */
752 inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
761 if ((g = (h & 0xf0000000)) != 0) {
770 unsigned long obj_elf_hash(const char *name)
772 return obj_elf_hash_n(name, strlen(name));
775 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
776 /* Get the kernel version in the canonical integer form. */
778 static int get_kernel_version(char str[STRVERSIONLEN])
780 struct utsname uts_info;
784 if (uname(&uts_info) < 0)
786 strncpy(str, uts_info.release, STRVERSIONLEN);
787 p = uts_info.release;
789 a = strtoul(p, &p, 10);
792 b = strtoul(p + 1, &p, 10);
795 c = strtoul(p + 1, &q, 10);
799 return a << 16 | b << 8 | c;
802 /* String comparison for non-co-versioned kernel and module. */
804 static int ncv_strcmp(const char *a, const char *b)
806 size_t alen = strlen(a), blen = strlen(b);
808 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
809 return strncmp(a, b, alen);
810 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
811 return strncmp(a, b, blen);
816 /* String hashing for non-co-versioned kernel and module. Here
817 we are simply forced to drop the crc from the hash. */
819 static unsigned long ncv_symbol_hash(const char *str)
821 size_t len = strlen(str);
822 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
824 return obj_elf_hash_n(str, len);
828 obj_set_symbol_compare(struct obj_file *f,
829 int (*cmp) (const char *, const char *),
830 unsigned long (*hash) (const char *))
835 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
838 f->symbol_hash = hash;
840 memcpy(tmptab, f->symtab, sizeof(tmptab));
841 memset(f->symtab, 0, sizeof(f->symtab));
843 for (i = 0; i < HASH_BUCKETS; ++i)
844 for (sym = tmptab[i]; sym; sym = next) {
845 unsigned long h = hash(sym->name) % HASH_BUCKETS;
847 sym->next = f->symtab[h];
853 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
856 struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
857 unsigned long symidx, int info,
858 int secidx, ElfW(Addr) value,
861 struct obj_symbol *sym;
862 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
863 int n_type = ELFW(ST_TYPE) (info);
864 int n_binding = ELFW(ST_BIND) (info);
866 for (sym = f->symtab[hash]; sym; sym = sym->next)
867 if (f->symbol_cmp(sym->name, name) == 0) {
868 int o_secidx = sym->secidx;
869 int o_info = sym->info;
870 int o_type = ELFW(ST_TYPE) (o_info);
871 int o_binding = ELFW(ST_BIND) (o_info);
873 /* A redefinition! Is it legal? */
875 if (secidx == SHN_UNDEF)
877 else if (o_secidx == SHN_UNDEF)
879 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
880 /* Cope with local and global symbols of the same name
881 in the same object file, as might have been created
882 by ld -r. The only reason locals are now seen at this
883 level at all is so that we can do semi-sensible things
886 struct obj_symbol *nsym, **p;
888 nsym = arch_new_symbol();
889 nsym->next = sym->next;
892 /* Excise the old (local) symbol from the hash chain. */
893 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
897 } else if (n_binding == STB_LOCAL) {
898 /* Another symbol of the same name has already been defined.
899 Just add this to the local table. */
900 sym = arch_new_symbol();
903 f->local_symtab[symidx] = sym;
905 } else if (n_binding == STB_WEAK)
907 else if (o_binding == STB_WEAK)
909 /* Don't unify COMMON symbols with object types the programmer
911 else if (secidx == SHN_COMMON
912 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
914 else if (o_secidx == SHN_COMMON
915 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
918 /* Don't report an error if the symbol is coming from
919 the kernel or some external module. */
920 if (secidx <= SHN_HIRESERVE)
921 errorMsg("%s multiply defined\n", name);
926 /* Completely new symbol. */
927 sym = arch_new_symbol();
928 sym->next = f->symtab[hash];
929 f->symtab[hash] = sym;
932 if (ELFW(ST_BIND) (info) == STB_LOCAL)
933 f->local_symtab[symidx] = sym;
939 sym->secidx = secidx;
945 struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
947 struct obj_symbol *sym;
948 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
950 for (sym = f->symtab[hash]; sym; sym = sym->next)
951 if (f->symbol_cmp(sym->name, name) == 0)
958 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
961 if (sym->secidx >= SHN_LORESERVE)
964 return sym->value + f->sections[sym->secidx]->header.sh_addr;
966 /* As a special case, a NULL sym has value zero. */
971 struct obj_section *obj_find_section(struct obj_file *f, const char *name)
973 int i, n = f->header.e_shnum;
975 for (i = 0; i < n; ++i)
976 if (strcmp(f->sections[i]->name, name) == 0)
977 return f->sections[i];
982 static int obj_load_order_prio(struct obj_section *a)
984 unsigned long af, ac;
986 af = a->header.sh_flags;
989 if (a->name[0] != '.' || strlen(a->name) != 10 ||
990 strcmp(a->name + 5, ".init"))
994 if (!(af & SHF_WRITE))
996 if (af & SHF_EXECINSTR)
998 if (a->header.sh_type != SHT_NOBITS)
1005 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1007 struct obj_section **p;
1008 int prio = obj_load_order_prio(sec);
1009 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1010 if (obj_load_order_prio(*p) < prio)
1012 sec->load_next = *p;
1016 struct obj_section *obj_create_alloced_section(struct obj_file *f,
1018 unsigned long align,
1021 int newidx = f->header.e_shnum++;
1022 struct obj_section *sec;
1024 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1025 f->sections[newidx] = sec = arch_new_section();
1027 memset(sec, 0, sizeof(*sec));
1028 sec->header.sh_type = SHT_PROGBITS;
1029 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1030 sec->header.sh_size = size;
1031 sec->header.sh_addralign = align;
1035 sec->contents = xmalloc(size);
1037 obj_insert_section_load_order(f, sec);
1042 struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1044 unsigned long align,
1047 int newidx = f->header.e_shnum++;
1048 struct obj_section *sec;
1050 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1051 f->sections[newidx] = sec = arch_new_section();
1053 memset(sec, 0, sizeof(*sec));
1054 sec->header.sh_type = SHT_PROGBITS;
1055 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1056 sec->header.sh_size = size;
1057 sec->header.sh_addralign = align;
1061 sec->contents = xmalloc(size);
1063 sec->load_next = f->load_order;
1064 f->load_order = sec;
1065 if (f->load_order_search_start == &f->load_order)
1066 f->load_order_search_start = &sec->load_next;
1071 void *obj_extend_section(struct obj_section *sec, unsigned long more)
1073 unsigned long oldsize = sec->header.sh_size;
1074 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1075 return sec->contents + oldsize;
1080 /* Conditionally add the symbols from the given symbol set to the
1086 int idx, struct new_module_symbol *syms, size_t nsyms)
1088 struct new_module_symbol *s;
1092 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1094 /* Only add symbols that are already marked external. If we
1095 override locals we may cause problems for argument initialization.
1096 We will also create a false dependency on the module. */
1097 struct obj_symbol *sym;
1099 sym = obj_find_symbol(f, (char *) s->name);
1100 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1101 sym = obj_add_symbol(f, (char *) s->name, -1,
1102 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1104 /* Did our symbol just get installed? If so, mark the
1105 module as "used". */
1106 if (sym->secidx == idx)
1114 static void add_kernel_symbols(struct obj_file *f)
1116 struct external_module *m;
1119 /* Add module symbols first. */
1121 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1123 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1124 m->nsyms)) m->used = 1, ++nused;
1126 n_ext_modules_used = nused;
1128 /* And finally the symbols from the kernel proper. */
1131 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1134 static char *get_modinfo_value(struct obj_file *f, const char *key)
1136 struct obj_section *sec;
1137 char *p, *v, *n, *ep;
1138 size_t klen = strlen(key);
1140 sec = obj_find_section(f, ".modinfo");
1144 ep = p + sec->header.sh_size;
1147 n = strchr(p, '\0');
1149 if (p + klen == v && strncmp(p, key, klen) == 0)
1152 if (p + klen == n && strcmp(p, key) == 0)
1162 /*======================================================================*/
1163 /* Functions relating to module loading in pre 2.1 kernels. */
1166 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1170 struct obj_symbol *sym;
1174 if ((q = strchr(p, '=')) == NULL) {
1180 sym = obj_find_symbol(f, p);
1182 /* Also check that the parameter was not resolved from the kernel. */
1183 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1184 errorMsg("symbol for parameter %s not found\n", p);
1188 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1190 /* Do C quoting if we begin with a ". */
1194 str = alloca(strlen(q));
1195 for (r = str, q++; *q != '"'; ++q, ++r) {
1197 errorMsg("improperly terminated string argument for %s\n", p);
1199 } else if (*q == '\\')
1233 if (q[1] >= '0' && q[1] <= '7') {
1234 c = (c * 8) + *++q - '0';
1235 if (q[1] >= '0' && q[1] <= '7')
1236 c = (c * 8) + *++q - '0';
1249 obj_string_patch(f, sym->secidx, sym->value, str);
1250 } else if (*q >= '0' && *q <= '9') {
1252 *loc++ = strtoul(q, &q, 0);
1253 while (*q++ == ',');
1255 char *contents = f->sections[sym->secidx]->contents;
1256 char *loc = contents + sym->value;
1257 char *r; /* To search for commas */
1259 /* Break the string with comas */
1260 while ((r = strchr(q, ',')) != (char *) NULL) {
1262 obj_string_patch(f, sym->secidx, loc - contents, q);
1263 loc += sizeof(char *);
1268 obj_string_patch(f, sym->secidx, loc - contents, q);
1277 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1278 static int old_is_module_checksummed(struct obj_file *f)
1280 return obj_find_symbol(f, "Using_Versions") != NULL;
1282 /* Get the module's kernel version in the canonical integer form. */
1285 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1287 struct obj_symbol *sym;
1291 sym = obj_find_symbol(f, "kernel_version");
1295 p = f->sections[sym->secidx]->contents + sym->value;
1296 strncpy(str, p, STRVERSIONLEN);
1298 a = strtoul(p, &p, 10);
1301 b = strtoul(p + 1, &p, 10);
1304 c = strtoul(p + 1, &q, 10);
1308 return a << 16 | b << 8 | c;
1311 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1313 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
1315 /* Fetch all the symbols and divvy them up as appropriate for the modules. */
1317 static int old_get_kernel_symbols(void)
1319 struct old_kernel_sym *ks, *k;
1320 struct new_module_symbol *s;
1321 struct external_module *mod;
1322 int nks, nms, nmod, i;
1324 nks = get_kernel_syms(NULL);
1326 errorMsg("get_kernel_syms: %s: %s", m_name, strerror(errno));
1330 ks = k = xmalloc(nks * sizeof(*ks));
1332 if (get_kernel_syms(ks) != nks) {
1333 perror("inconsistency with get_kernel_syms -- is someone else "
1334 "playing with modules?");
1339 /* Collect the module information. */
1344 while (k->name[0] == '#' && k->name[1]) {
1345 struct old_kernel_sym *k2;
1346 struct new_module_symbol *s;
1348 /* Find out how many symbols this module has. */
1349 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1353 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1354 mod[nmod].name = k->name + 1;
1355 mod[nmod].addr = k->value;
1357 mod[nmod].nsyms = nms;
1358 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1360 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1361 s->name = (unsigned long) k->name;
1362 s->value = k->value;
1369 n_ext_modules = nmod + 1;
1371 /* Now collect the symbols for the kernel proper. */
1373 if (k->name[0] == '#')
1376 nksyms = nms = nks - (k - ks);
1377 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1379 for (i = 0; i < nms; ++i, ++s, ++k) {
1380 s->name = (unsigned long) k->name;
1381 s->value = k->value;
1387 /* Return the kernel symbol checksum version, or zero if not used. */
1389 static int old_is_kernel_checksummed(void)
1391 /* Using_Versions is the first symbol. */
1393 && strcmp((char *) ksyms[0].name,
1394 "Using_Versions") == 0) return ksyms[0].value;
1400 static int old_create_mod_use_count(struct obj_file *f)
1402 struct obj_section *sec;
1404 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1407 obj_add_symbol(f, "mod_use_count_", -1,
1408 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1415 old_init_module(const char *m_name, struct obj_file *f,
1416 unsigned long m_size)
1419 struct old_mod_routines routines;
1420 struct old_symbol_table *symtab;
1423 /* Create the symbol table */
1425 int nsyms = 0, strsize = 0, total;
1427 /* Size things first... */
1430 for (i = 0; i < HASH_BUCKETS; ++i) {
1431 struct obj_symbol *sym;
1432 for (sym = f->symtab[i]; sym; sym = sym->next)
1433 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1434 && sym->secidx <= SHN_HIRESERVE)
1436 sym->ksymidx = nsyms++;
1437 strsize += strlen(sym->name) + 1;
1442 total = (sizeof(struct old_symbol_table)
1443 + nsyms * sizeof(struct old_module_symbol)
1444 + n_ext_modules_used * sizeof(struct old_module_ref)
1446 symtab = xmalloc(total);
1447 symtab->size = total;
1448 symtab->n_symbols = nsyms;
1449 symtab->n_refs = n_ext_modules_used;
1451 if (flag_export && nsyms) {
1452 struct old_module_symbol *ksym;
1456 ksym = symtab->symbol;
1457 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1458 + n_ext_modules_used * sizeof(struct old_module_ref));
1460 for (i = 0; i < HASH_BUCKETS; ++i) {
1461 struct obj_symbol *sym;
1462 for (sym = f->symtab[i]; sym; sym = sym->next)
1463 if (sym->ksymidx >= 0) {
1464 ksym->addr = obj_symbol_final_value(f, sym);
1466 (unsigned long) str - (unsigned long) symtab;
1468 str = stpcpy(str, sym->name) + 1;
1474 if (n_ext_modules_used) {
1475 struct old_module_ref *ref;
1478 ref = (struct old_module_ref *)
1479 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1481 for (i = 0; i < n_ext_modules; ++i)
1482 if (ext_modules[i].used)
1483 ref++->module = ext_modules[i].addr;
1487 /* Fill in routines. */
1490 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1492 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1494 /* Whew! All of the initialization is complete. Collect the final
1495 module image and give it to the kernel. */
1497 image = xmalloc(m_size);
1498 obj_create_image(f, image);
1500 /* image holds the complete relocated module, accounting correctly for
1501 mod_use_count. However the old module kernel support assume that
1502 it is receiving something which does not contain mod_use_count. */
1503 ret = old_sys_init_module(m_name, image + sizeof(long),
1504 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1505 : 0), &routines, symtab);
1507 errorMsg("init_module: %s: %s", m_name, strerror(errno));
1517 #define old_create_mod_use_count(x) TRUE
1518 #define old_init_module(x, y, z) TRUE
1520 #endif /* BB_FEATURE_INSMOD_OLD_KERNEL */
1524 /*======================================================================*/
1525 /* Functions relating to module loading after 2.1.18. */
1528 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1532 struct obj_symbol *sym;
1533 char *contents, *loc;
1537 if ((q = strchr(p, '=')) == NULL) {
1542 key = alloca(q - p + 6);
1543 memcpy(key, "parm_", 5);
1544 memcpy(key + 5, p, q - p);
1547 p = get_modinfo_value(f, key);
1550 errorMsg("invalid parameter %s\n", key);
1554 sym = obj_find_symbol(f, key);
1556 /* Also check that the parameter was not resolved from the kernel. */
1557 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1558 errorMsg("symbol for parameter %s not found\n", key);
1563 min = strtoul(p, &p, 10);
1565 max = strtoul(p + 1, &p, 10);
1571 contents = f->sections[sym->secidx]->contents;
1572 loc = contents + sym->value;
1576 if ((*p == 's') || (*p == 'c')) {
1579 /* Do C quoting if we begin with a ", else slurp the lot. */
1583 str = alloca(strlen(q));
1584 for (r = str, q++; *q != '"'; ++q, ++r) {
1586 errorMsg("improperly terminated string argument for %s\n",
1589 } else if (*q == '\\')
1623 if (q[1] >= '0' && q[1] <= '7') {
1624 c = (c * 8) + *++q - '0';
1625 if (q[1] >= '0' && q[1] <= '7')
1626 c = (c * 8) + *++q - '0';
1643 /* In this case, the string is not quoted. We will break
1644 it using the coma (like for ints). If the user wants to
1645 include comas in a string, he just has to quote it */
1647 /* Search the next coma */
1651 if (r != (char *) NULL) {
1652 /* Recopy the current field */
1653 str = alloca(r - q + 1);
1654 memcpy(str, q, r - q);
1656 /* I don't know if it is usefull, as the previous case
1657 doesn't null terminate the string ??? */
1660 /* Keep next fields */
1671 obj_string_patch(f, sym->secidx, loc - contents, str);
1672 loc += tgt_sizeof_char_p;
1674 /* Array of chars (in fact, matrix !) */
1675 unsigned long charssize; /* size of each member */
1677 /* Get the size of each member */
1678 /* Probably we should do that outside the loop ? */
1679 if (!isdigit(*(p + 1))) {
1680 errorMsg("parameter type 'c' for %s must be followed by"
1681 " the maximum size\n", key);
1684 charssize = strtoul(p + 1, (char **) NULL, 10);
1687 if (strlen(str) >= charssize) {
1688 errorMsg("string too long for %s (max %ld)\n", key,
1693 /* Copy to location */
1694 strcpy((char *) loc, str);
1698 long v = strtoul(q, &q, 0);
1705 loc += tgt_sizeof_short;
1709 loc += tgt_sizeof_int;
1713 loc += tgt_sizeof_long;
1717 errorMsg("unknown parameter type '%c' for %s\n", *p, key);
1732 goto retry_end_of_value;
1736 errorMsg("too many values for %s (max %d)\n", key, max);
1743 errorMsg("invalid argument syntax for %s\n", key);
1750 errorMsg("too few values for %s (min %d)\n", key, min);
1760 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1761 static int new_is_module_checksummed(struct obj_file *f)
1763 const char *p = get_modinfo_value(f, "using_checksums");
1770 /* Get the module's kernel version in the canonical integer form. */
1773 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1778 p = get_modinfo_value(f, "kernel_version");
1781 strncpy(str, p, STRVERSIONLEN);
1783 a = strtoul(p, &p, 10);
1786 b = strtoul(p + 1, &p, 10);
1789 c = strtoul(p + 1, &q, 10);
1793 return a << 16 | b << 8 | c;
1796 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1799 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
1801 /* Fetch the loaded modules, and all currently exported symbols. */
1803 static int new_get_kernel_symbols(void)
1805 char *module_names, *mn;
1806 struct external_module *modules, *m;
1807 struct new_module_symbol *syms, *s;
1808 size_t ret, bufsize, nmod, nsyms, i, j;
1810 /* Collect the loaded modules. */
1812 module_names = xmalloc(bufsize = 256);
1814 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
1815 if (errno == ENOSPC) {
1816 module_names = xrealloc(module_names, bufsize = ret);
1817 goto retry_modules_load;
1819 errorMsg("QM_MODULES: %s", strerror(errno));
1823 n_ext_modules = nmod = ret;
1824 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
1825 memset(modules, 0, nmod * sizeof(*modules));
1827 /* Collect the modules' symbols. */
1829 for (i = 0, mn = module_names, m = modules;
1830 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
1831 struct new_module_info info;
1833 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
1834 if (errno == ENOENT) {
1835 /* The module was removed out from underneath us. */
1838 errorMsg("query_module: QM_INFO: %s: %s", mn, strerror(errno));
1842 syms = xmalloc(bufsize = 1024);
1844 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
1847 syms = xrealloc(syms, bufsize = ret);
1848 goto retry_mod_sym_load;
1850 /* The module was removed out from underneath us. */
1853 errorMsg("query_module: QM_SYMBOLS: %s: %s", mn, strerror(errno));
1860 m->addr = info.addr;
1864 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
1865 s->name += (unsigned long) syms;
1869 /* Collect the kernel's symbols. */
1871 syms = xmalloc(bufsize = 16 * 1024);
1872 retry_kern_sym_load:
1873 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
1874 if (errno == ENOSPC) {
1875 syms = xrealloc(syms, bufsize = ret);
1876 goto retry_kern_sym_load;
1878 errorMsg("kernel: QM_SYMBOLS: %s", strerror(errno));
1881 nksyms = nsyms = ret;
1884 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
1885 s->name += (unsigned long) syms;
1891 /* Return the kernel symbol checksum version, or zero if not used. */
1893 static int new_is_kernel_checksummed(void)
1895 struct new_module_symbol *s;
1898 /* Using_Versions is not the first symbol, but it should be in there. */
1900 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
1901 if (strcmp((char *) s->name, "Using_Versions") == 0)
1908 static int new_create_this_module(struct obj_file *f, const char *m_name)
1910 struct obj_section *sec;
1912 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
1913 sizeof(struct new_module));
1914 memset(sec->contents, 0, sizeof(struct new_module));
1916 obj_add_symbol(f, "__this_module", -1,
1917 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1918 sizeof(struct new_module));
1920 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
1927 static int new_create_module_ksymtab(struct obj_file *f)
1929 struct obj_section *sec;
1932 /* We must always add the module references. */
1934 if (n_ext_modules_used) {
1935 struct new_module_ref *dep;
1936 struct obj_symbol *tm;
1938 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
1939 (sizeof(struct new_module_ref)
1940 * n_ext_modules_used));
1944 tm = obj_find_symbol(f, "__this_module");
1945 dep = (struct new_module_ref *) sec->contents;
1946 for (i = 0; i < n_ext_modules; ++i)
1947 if (ext_modules[i].used) {
1948 dep->dep = ext_modules[i].addr;
1949 obj_symbol_patch(f, sec->idx,
1950 (char *) &dep->ref - sec->contents, tm);
1956 if (flag_export && !obj_find_section(f, "__ksymtab")) {
1961 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
1964 /* We don't want to export symbols residing in sections that
1965 aren't loaded. There are a number of these created so that
1966 we make sure certain module options don't appear twice. */
1968 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
1970 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
1972 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
1973 struct obj_symbol *sym;
1974 for (sym = f->symtab[i]; sym; sym = sym->next)
1975 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1976 && sym->secidx <= SHN_HIRESERVE
1977 && (sym->secidx >= SHN_LORESERVE
1978 || loaded[sym->secidx])) {
1979 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
1981 obj_symbol_patch(f, sec->idx, ofs, sym);
1982 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
1989 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
1997 new_init_module(const char *m_name, struct obj_file *f,
1998 unsigned long m_size)
2000 struct new_module *module;
2001 struct obj_section *sec;
2006 sec = obj_find_section(f, ".this");
2007 module = (struct new_module *) sec->contents;
2008 m_addr = sec->header.sh_addr;
2010 module->size_of_struct = sizeof(*module);
2011 module->size = m_size;
2012 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2014 sec = obj_find_section(f, "__ksymtab");
2015 if (sec && sec->header.sh_size) {
2016 module->syms = sec->header.sh_addr;
2017 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2020 if (n_ext_modules_used) {
2021 sec = obj_find_section(f, ".kmodtab");
2022 module->deps = sec->header.sh_addr;
2023 module->ndeps = n_ext_modules_used;
2027 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2029 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2031 sec = obj_find_section(f, "__ex_table");
2033 module->ex_table_start = sec->header.sh_addr;
2034 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2037 sec = obj_find_section(f, ".text.init");
2039 module->runsize = sec->header.sh_addr - m_addr;
2041 sec = obj_find_section(f, ".data.init");
2043 if (!module->runsize ||
2044 module->runsize > sec->header.sh_addr - m_addr)
2045 module->runsize = sec->header.sh_addr - m_addr;
2048 if (!arch_init_module(f, module))
2051 /* Whew! All of the initialization is complete. Collect the final
2052 module image and give it to the kernel. */
2054 image = xmalloc(m_size);
2055 obj_create_image(f, image);
2057 ret = new_sys_init_module(m_name, (struct new_module *) image);
2059 errorMsg("init_module: %s: %s", m_name, strerror(errno));
2068 #define new_init_module(x, y, z) TRUE
2069 #define new_create_this_module(x, y) 0
2070 #define new_create_module_ksymtab(x)
2072 #endif /* BB_FEATURE_INSMOD_OLD_KERNEL */
2075 /*======================================================================*/
2078 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2081 struct obj_string_patch *p;
2082 struct obj_section *strsec;
2083 size_t len = strlen(string) + 1;
2086 p = xmalloc(sizeof(*p));
2087 p->next = f->string_patches;
2088 p->reloc_secidx = secidx;
2089 p->reloc_offset = offset;
2090 f->string_patches = p;
2092 strsec = obj_find_section(f, ".kstrtab");
2093 if (strsec == NULL) {
2094 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2095 p->string_offset = 0;
2096 loc = strsec->contents;
2098 p->string_offset = strsec->header.sh_size;
2099 loc = obj_extend_section(strsec, len);
2101 memcpy(loc, string, len);
2107 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2108 struct obj_symbol *sym)
2110 struct obj_symbol_patch *p;
2112 p = xmalloc(sizeof(*p));
2113 p->next = f->symbol_patches;
2114 p->reloc_secidx = secidx;
2115 p->reloc_offset = offset;
2117 f->symbol_patches = p;
2122 int obj_check_undefineds(struct obj_file *f)
2127 for (i = 0; i < HASH_BUCKETS; ++i) {
2128 struct obj_symbol *sym;
2129 for (sym = f->symtab[i]; sym; sym = sym->next)
2130 if (sym->secidx == SHN_UNDEF) {
2131 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2132 sym->secidx = SHN_ABS;
2135 errorMsg("unresolved symbol %s\n", sym->name);
2144 void obj_allocate_commons(struct obj_file *f)
2146 struct common_entry {
2147 struct common_entry *next;
2148 struct obj_symbol *sym;
2149 } *common_head = NULL;
2153 for (i = 0; i < HASH_BUCKETS; ++i) {
2154 struct obj_symbol *sym;
2155 for (sym = f->symtab[i]; sym; sym = sym->next)
2156 if (sym->secidx == SHN_COMMON) {
2157 /* Collect all COMMON symbols and sort them by size so as to
2158 minimize space wasted by alignment requirements. */
2160 struct common_entry **p, *n;
2161 for (p = &common_head; *p; p = &(*p)->next)
2162 if (sym->size <= (*p)->sym->size)
2165 n = alloca(sizeof(*n));
2173 for (i = 1; i < f->local_symtab_size; ++i) {
2174 struct obj_symbol *sym = f->local_symtab[i];
2175 if (sym && sym->secidx == SHN_COMMON) {
2176 struct common_entry **p, *n;
2177 for (p = &common_head; *p; p = &(*p)->next)
2178 if (sym == (*p)->sym)
2180 else if (sym->size < (*p)->sym->size) {
2181 n = alloca(sizeof(*n));
2191 /* Find the bss section. */
2192 for (i = 0; i < f->header.e_shnum; ++i)
2193 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2196 /* If for some reason there hadn't been one, create one. */
2197 if (i == f->header.e_shnum) {
2198 struct obj_section *sec;
2200 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2201 f->sections[i] = sec = arch_new_section();
2202 f->header.e_shnum = i + 1;
2204 memset(sec, 0, sizeof(*sec));
2205 sec->header.sh_type = SHT_PROGBITS;
2206 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2211 /* Allocate the COMMONS. */
2213 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2214 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2215 struct common_entry *c;
2217 for (c = common_head; c; c = c->next) {
2218 ElfW(Addr) align = c->sym->value;
2220 if (align > max_align)
2222 if (bss_size & (align - 1))
2223 bss_size = (bss_size | (align - 1)) + 1;
2226 c->sym->value = bss_size;
2228 bss_size += c->sym->size;
2231 f->sections[i]->header.sh_size = bss_size;
2232 f->sections[i]->header.sh_addralign = max_align;
2236 /* For the sake of patch relocation and parameter initialization,
2237 allocate zeroed data for NOBITS sections now. Note that after
2238 this we cannot assume NOBITS are really empty. */
2239 for (i = 0; i < f->header.e_shnum; ++i) {
2240 struct obj_section *s = f->sections[i];
2241 if (s->header.sh_type == SHT_NOBITS) {
2242 s->contents = memset(xmalloc(s->header.sh_size),
2243 0, s->header.sh_size);
2244 s->header.sh_type = SHT_PROGBITS;
2249 unsigned long obj_load_size(struct obj_file *f)
2251 unsigned long dot = 0;
2252 struct obj_section *sec;
2254 /* Finalize the positions of the sections relative to one another. */
2256 for (sec = f->load_order; sec; sec = sec->load_next) {
2259 align = sec->header.sh_addralign;
2260 if (align && (dot & (align - 1)))
2261 dot = (dot | (align - 1)) + 1;
2263 sec->header.sh_addr = dot;
2264 dot += sec->header.sh_size;
2270 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2272 int i, n = f->header.e_shnum;
2275 /* Finalize the addresses of the sections. */
2278 for (i = 0; i < n; ++i)
2279 f->sections[i]->header.sh_addr += base;
2281 /* And iterate over all of the relocations. */
2283 for (i = 0; i < n; ++i) {
2284 struct obj_section *relsec, *symsec, *targsec, *strsec;
2285 ElfW(RelM) * rel, *relend;
2289 relsec = f->sections[i];
2290 if (relsec->header.sh_type != SHT_RELM)
2293 symsec = f->sections[relsec->header.sh_link];
2294 targsec = f->sections[relsec->header.sh_info];
2295 strsec = f->sections[symsec->header.sh_link];
2297 rel = (ElfW(RelM) *) relsec->contents;
2298 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2299 symtab = (ElfW(Sym) *) symsec->contents;
2300 strtab = (const char *) strsec->contents;
2302 for (; rel < relend; ++rel) {
2303 ElfW(Addr) value = 0;
2304 struct obj_symbol *intsym = NULL;
2305 unsigned long symndx;
2306 ElfW(Sym) * extsym = 0;
2309 /* Attempt to find a value to use for this relocation. */
2311 symndx = ELFW(R_SYM) (rel->r_info);
2313 /* Note we've already checked for undefined symbols. */
2315 extsym = &symtab[symndx];
2316 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2317 /* Local symbols we look up in the local table to be sure
2318 we get the one that is really intended. */
2319 intsym = f->local_symtab[symndx];
2321 /* Others we look up in the hash table. */
2323 if (extsym->st_name)
2324 name = strtab + extsym->st_name;
2326 name = f->sections[extsym->st_shndx]->name;
2327 intsym = obj_find_symbol(f, name);
2330 value = obj_symbol_final_value(f, intsym);
2331 intsym->referenced = 1;
2333 #if SHT_RELM == SHT_RELA
2334 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2335 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2336 if (!extsym || !extsym->st_name ||
2337 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2339 value += rel->r_addend;
2343 switch (arch_apply_relocation
2344 (f, targsec, symsec, intsym, rel, value)) {
2348 case obj_reloc_overflow:
2349 errmsg = "Relocation overflow";
2351 case obj_reloc_dangerous:
2352 errmsg = "Dangerous relocation";
2354 case obj_reloc_unhandled:
2355 errmsg = "Unhandled relocation";
2358 errorMsg("%s of type %ld for %s\n", errmsg,
2359 (long) ELFW(R_TYPE) (rel->r_info),
2360 strtab + extsym->st_name);
2362 errorMsg("%s of type %ld\n", errmsg,
2363 (long) ELFW(R_TYPE) (rel->r_info));
2371 /* Finally, take care of the patches. */
2373 if (f->string_patches) {
2374 struct obj_string_patch *p;
2375 struct obj_section *strsec;
2376 ElfW(Addr) strsec_base;
2377 strsec = obj_find_section(f, ".kstrtab");
2378 strsec_base = strsec->header.sh_addr;
2380 for (p = f->string_patches; p; p = p->next) {
2381 struct obj_section *targsec = f->sections[p->reloc_secidx];
2382 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2383 = strsec_base + p->string_offset;
2387 if (f->symbol_patches) {
2388 struct obj_symbol_patch *p;
2390 for (p = f->symbol_patches; p; p = p->next) {
2391 struct obj_section *targsec = f->sections[p->reloc_secidx];
2392 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2393 = obj_symbol_final_value(f, p->sym);
2400 int obj_create_image(struct obj_file *f, char *image)
2402 struct obj_section *sec;
2403 ElfW(Addr) base = f->baseaddr;
2405 for (sec = f->load_order; sec; sec = sec->load_next) {
2408 if (sec->header.sh_size == 0)
2411 secimg = image + (sec->header.sh_addr - base);
2413 /* Note that we allocated data for NOBITS sections earlier. */
2414 memcpy(secimg, sec->contents, sec->header.sh_size);
2420 /*======================================================================*/
2422 struct obj_file *obj_load(FILE * fp)
2425 ElfW(Shdr) * section_headers;
2429 /* Read the file header. */
2431 f = arch_new_file();
2432 memset(f, 0, sizeof(*f));
2433 f->symbol_cmp = strcmp;
2434 f->symbol_hash = obj_elf_hash;
2435 f->load_order_search_start = &f->load_order;
2437 fseek(fp, 0, SEEK_SET);
2438 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2439 errorMsg("error reading ELF header: %s", strerror(errno));
2443 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2444 || f->header.e_ident[EI_MAG1] != ELFMAG1
2445 || f->header.e_ident[EI_MAG2] != ELFMAG2
2446 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2447 errorMsg("not an ELF file\n");
2450 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2451 || f->header.e_ident[EI_DATA] != ELFDATAM
2452 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2453 || !MATCH_MACHINE(f->header.e_machine)) {
2454 errorMsg("ELF file not for this architecture\n");
2457 if (f->header.e_type != ET_REL) {
2458 errorMsg("ELF file not a relocatable object\n");
2462 /* Read the section headers. */
2464 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2465 errorMsg("section header size mismatch: %lu != %lu\n",
2466 (unsigned long) f->header.e_shentsize,
2467 (unsigned long) sizeof(ElfW(Shdr)));
2471 shnum = f->header.e_shnum;
2472 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2473 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2475 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2476 fseek(fp, f->header.e_shoff, SEEK_SET);
2477 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2478 errorMsg("error reading ELF section headers: %s", strerror(errno));
2482 /* Read the section data. */
2484 for (i = 0; i < shnum; ++i) {
2485 struct obj_section *sec;
2487 f->sections[i] = sec = arch_new_section();
2488 memset(sec, 0, sizeof(*sec));
2490 sec->header = section_headers[i];
2493 switch (sec->header.sh_type) {
2504 if (sec->header.sh_size > 0) {
2505 sec->contents = xmalloc(sec->header.sh_size);
2506 fseek(fp, sec->header.sh_offset, SEEK_SET);
2507 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2508 errorMsg("error reading ELF section data: %s", strerror(errno));
2512 sec->contents = NULL;
2516 #if SHT_RELM == SHT_REL
2518 errorMsg("RELA relocations not supported on this architecture\n");
2522 errorMsg("REL relocations not supported on this architecture\n");
2527 if (sec->header.sh_type >= SHT_LOPROC) {
2528 /* Assume processor specific section types are debug
2529 info and can safely be ignored. If this is ever not
2530 the case (Hello MIPS?), don't put ifdefs here but
2531 create an arch_load_proc_section(). */
2535 errorMsg("can't handle sections of type %ld\n",
2536 (long) sec->header.sh_type);
2541 /* Do what sort of interpretation as needed by each section. */
2543 shstrtab = f->sections[f->header.e_shstrndx]->contents;
2545 for (i = 0; i < shnum; ++i) {
2546 struct obj_section *sec = f->sections[i];
2547 sec->name = shstrtab + sec->header.sh_name;
2550 for (i = 0; i < shnum; ++i) {
2551 struct obj_section *sec = f->sections[i];
2553 if (sec->header.sh_flags & SHF_ALLOC)
2554 obj_insert_section_load_order(f, sec);
2556 switch (sec->header.sh_type) {
2559 unsigned long nsym, j;
2563 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
2564 errorMsg("symbol size mismatch: %lu != %lu\n",
2565 (unsigned long) sec->header.sh_entsize,
2566 (unsigned long) sizeof(ElfW(Sym)));
2570 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
2571 strtab = f->sections[sec->header.sh_link]->contents;
2572 sym = (ElfW(Sym) *) sec->contents;
2574 /* Allocate space for a table of local symbols. */
2575 j = f->local_symtab_size = sec->header.sh_info;
2576 f->local_symtab = xmalloc(j *=
2577 sizeof(struct obj_symbol *));
2578 memset(f->local_symtab, 0, j);
2580 /* Insert all symbols into the hash table. */
2581 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
2584 name = strtab + sym->st_name;
2586 name = f->sections[sym->st_shndx]->name;
2588 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
2589 sym->st_value, sym->st_size);
2595 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
2596 errorMsg("relocation entry size mismatch: %lu != %lu\n",
2597 (unsigned long) sec->header.sh_entsize,
2598 (unsigned long) sizeof(ElfW(RelM)));
2608 static void hide_special_symbols(struct obj_file *f)
2610 static const char *const specials[] = {
2617 struct obj_symbol *sym;
2618 const char *const *p;
2620 for (p = specials; *p; ++p)
2621 if ((sym = obj_find_symbol(f, *p)) != NULL)
2623 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
2628 extern int insmod_main( int argc, char **argv)
2634 unsigned long m_size;
2638 char m_name[BUFSIZ + 1] = "\0";
2639 int exit_status = FALSE;
2641 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2643 char k_strversion[STRVERSIONLEN];
2644 char m_strversion[STRVERSIONLEN];
2651 usage(insmod_usage);
2654 /* Parse any options */
2655 while (--argc > 0 && **(++argv) == '-') {
2656 while (*(++(*argv))) {
2658 case 'f': /* force loading */
2659 flag_force_load = 1;
2661 case 'k': /* module loaded by kerneld, auto-cleanable */
2664 case 'v': /* verbose output */
2667 case 'x': /* do not export externs */
2671 usage(insmod_usage);
2677 usage(insmod_usage);
2679 /* Grab the module name */
2680 if ((tmp = strrchr(*argv, '/')) != NULL) {
2687 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
2689 memcpy(m_name, tmp, len);
2690 strcpy(m_fullName, m_name);
2691 strcat(m_fullName, ".o");
2693 /* Get a filedesc for the module */
2694 if ((fp = fopen(*argv, "r")) == NULL) {
2695 /* Hmpf. Could not open it. Search through _PATH_MODULES to find a module named m_name */
2696 if (recursiveAction(_PATH_MODULES, TRUE, FALSE, FALSE,
2697 findNamedModule, 0, m_fullName) == FALSE)
2699 if (m_filename[0] == '\0'
2700 || ((fp = fopen(m_filename, "r")) == NULL))
2702 errorMsg("No module named '%s' found in '%s'\n", m_fullName, _PATH_MODULES);
2706 fatalError("No module named '%s' found in '%s'\n", m_fullName, _PATH_MODULES);
2708 memcpy(m_filename, *argv, strlen(*argv));
2711 if ((f = obj_load(fp)) == NULL) {
2712 perror("Could not load the module\n");
2716 if (get_modinfo_value(f, "kernel_version") == NULL)
2721 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2722 /* Version correspondence? */
2724 k_version = get_kernel_version(k_strversion);
2725 if (m_has_modinfo) {
2726 m_version = new_get_module_version(f, m_strversion);
2728 m_version = old_get_module_version(f, m_strversion);
2729 if (m_version == -1) {
2730 errorMsg("couldn't find the kernel version the module was "
2736 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
2737 if (flag_force_load) {
2738 errorMsg("Warning: kernel-module version mismatch\n"
2739 "\t%s was compiled for kernel version %s\n"
2740 "\twhile this kernel is version %s\n",
2741 m_filename, m_strversion, k_strversion);
2743 errorMsg("kernel-module version mismatch\n"
2744 "\t%s was compiled for kernel version %s\n"
2745 "\twhile this kernel is version %s.\n",
2746 m_filename, m_strversion, k_strversion);
2751 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2753 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
2755 if (k_new_syscalls) {
2756 #ifdef BB_FEATURE_INSMOD_NEW_KERNEL
2757 if (!new_get_kernel_symbols())
2759 k_crcs = new_is_kernel_checksummed();
2761 errorMsg("Not configured to support new kernels\n");
2765 #ifdef BB_FEATURE_INSMOD_OLD_KERNEL
2766 if (!old_get_kernel_symbols())
2768 k_crcs = old_is_kernel_checksummed();
2770 errorMsg("Not configured to support old kernels\n");
2775 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2777 m_crcs = new_is_module_checksummed(f);
2779 m_crcs = old_is_module_checksummed(f);
2781 if (m_crcs != k_crcs)
2782 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
2783 #endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2785 /* Let the module know about the kernel symbols. */
2786 add_kernel_symbols(f);
2788 /* Allocate common symbols, symbol tables, and string tables. */
2791 ? !new_create_this_module(f, m_name)
2792 : !old_create_mod_use_count(f))
2797 if (!obj_check_undefineds(f)) {
2800 obj_allocate_commons(f);
2802 if (optind < argc) {
2804 ? !new_process_module_arguments(f, argc - optind, argv + optind)
2805 : !old_process_module_arguments(f, argc - optind, argv + optind))
2812 hide_special_symbols(f);
2815 new_create_module_ksymtab(f);
2817 /* Find current size of the module */
2818 m_size = obj_load_size(f);
2822 m_addr = create_module(m_name, m_size);
2827 errorMsg("A module named %s already exists\n", m_name);
2830 errorMsg("Can't allocate kernel memory for module; needed %lu bytes\n",
2834 errorMsg("create_module: %s: %s", m_name, strerror(errno));
2838 if (!obj_relocate(f, m_addr)) {
2839 delete_module(m_name);
2844 ? !new_init_module(m_name, f, m_size)
2845 : !old_init_module(m_name, f, m_size))
2847 delete_module(m_name);
2855 return(exit_status);