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