source: MondoRescue/branches/stable/mindi-busybox/modutils/insmod.c@ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 18 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 104.2 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini insmod implementation for busybox
4 *
5 * This version of insmod supports ARM, CRIS, H8/300, x86, ia64, x86_64,
6 * m68k, MIPS, PowerPC, S390, SH3/4/5, Sparc, v850e, and x86_64.
7 *
8 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
9 * and Ron Alder <alder@lineo.com>
10 *
11 * Rodney Radford <rradford@mindspring.com> 17-Aug-2004.
12 * Added x86_64 support.
13 *
14 * Miles Bader <miles@gnu.org> added NEC V850E support.
15 *
16 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
17 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
18 *
19 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
20 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
21 * very minor changes required to also work with StrongArm and presumably
22 * all ARM based systems.
23 *
24 * Yoshinori Sato <ysato@users.sourceforge.jp> 19-May-2004.
25 * added Renesas H8/300 support.
26 *
27 * Paul Mundt <lethal@linux-sh.org> 08-Aug-2003.
28 * Integrated support for sh64 (SH-5), from preliminary modutils
29 * patches from Benedict Gaster <benedict.gaster@superh.com>.
30 * Currently limited to support for 32bit ABI.
31 *
32 * Magnus Damm <damm@opensource.se> 22-May-2002.
33 * The plt and got code are now using the same structs.
34 * Added generic linked list code to fully support PowerPC.
35 * Replaced the mess in arch_apply_relocation() with architecture blocks.
36 * The arch_create_got() function got cleaned up with architecture blocks.
37 * These blocks should be easy maintain and sync with obj_xxx.c in modutils.
38 *
39 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
40 * PowerPC specific code stolen from modutils-2.3.16,
41 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
42 * I've only tested the code on mpc8xx platforms in big-endian mode.
43 * Did some cleanup and added CONFIG_USE_xxx_ENTRIES...
44 *
45 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
46 * based on modutils-2.4.2
47 * MIPS specific support for Elf loading and relocation.
48 * Copyright 1996, 1997 Linux International.
49 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
50 *
51 * Based almost entirely on the Linux modutils-2.3.11 implementation.
52 * Copyright 1996, 1997 Linux International.
53 * New implementation contributed by Richard Henderson <rth@tamu.edu>
54 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
55 * Restructured (and partly rewritten) by:
56 * Björn Ekwall <bj0rn@blox.se> February 1999
57 *
58 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
59 */
60
61#include "busybox.h"
62#include <stdlib.h>
63#include <stdio.h>
64#include <stddef.h>
65#include <errno.h>
66#include <unistd.h>
67#include <dirent.h>
68#include <ctype.h>
69#include <assert.h>
70#include <string.h>
71#include <getopt.h>
72#include <fcntl.h>
73#include <sys/utsname.h>
74
75#if !defined(CONFIG_FEATURE_2_4_MODULES) && \
76 !defined(CONFIG_FEATURE_2_6_MODULES)
77#define CONFIG_FEATURE_2_4_MODULES
78#endif
79
80#if !defined(CONFIG_FEATURE_2_4_MODULES)
81#define insmod_ng_main insmod_main
82#endif
83
84#if defined(CONFIG_FEATURE_2_6_MODULES)
85extern int insmod_ng_main( int argc, char **argv);
86#endif
87
88
89#if defined(CONFIG_FEATURE_2_4_MODULES)
90
91
92#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
93#define LOADBITS 0
94#else
95#define LOADBITS 1
96#endif
97
98
99/* Alpha */
100#if defined(__alpha__)
101#define MATCH_MACHINE(x) (x == EM_ALPHA)
102#define SHT_RELM SHT_RELA
103#define Elf64_RelM Elf64_Rela
104#define ELFCLASSM ELFCLASS64
105#endif
106
107/* ARM support */
108#if defined(__arm__)
109#define MATCH_MACHINE(x) (x == EM_ARM)
110#define SHT_RELM SHT_REL
111#define Elf32_RelM Elf32_Rel
112#define ELFCLASSM ELFCLASS32
113#define CONFIG_USE_PLT_ENTRIES
114#define CONFIG_PLT_ENTRY_SIZE 8
115#define CONFIG_USE_GOT_ENTRIES
116#define CONFIG_GOT_ENTRY_SIZE 8
117#define CONFIG_USE_SINGLE
118#endif
119
120/* blackfin */
121#if defined(BFIN)
122#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
123#define SHT_RELM SHT_RELA
124#define Elf32_RelM Elf32_Rela
125#define ELFCLASSM ELFCLASS32
126#endif
127
128/* CRIS */
129#if defined(__cris__)
130#define MATCH_MACHINE(x) (x == EM_CRIS)
131#define SHT_RELM SHT_RELA
132#define Elf32_RelM Elf32_Rela
133#define ELFCLASSM ELFCLASS32
134#ifndef EM_CRIS
135#define EM_CRIS 76
136#define R_CRIS_NONE 0
137#define R_CRIS_32 3
138#endif
139#endif
140
141/* H8/300 */
142#if defined(__H8300H__) || defined(__H8300S__)
143#define MATCH_MACHINE(x) (x == EM_H8_300)
144#define SHT_RELM SHT_RELA
145#define Elf32_RelM Elf32_Rela
146#define ELFCLASSM ELFCLASS32
147#define CONFIG_USE_SINGLE
148#define SYMBOL_PREFIX "_"
149#endif
150
151/* PA-RISC / HP-PA */
152#if defined(__hppa__)
153#define MATCH_MACHINE(x) (x == EM_PARISC)
154#define SHT_RELM SHT_RELA
155#if defined(__LP64__)
156#define Elf64_RelM Elf64_Rela
157#define ELFCLASSM ELFCLASS64
158#else
159#define Elf32_RelM Elf32_Rela
160#define ELFCLASSM ELFCLASS32
161#endif
162#endif
163
164/* x86 */
165#if defined(__i386__)
166#ifndef EM_486
167#define MATCH_MACHINE(x) (x == EM_386)
168#else
169#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
170#endif
171#define SHT_RELM SHT_REL
172#define Elf32_RelM Elf32_Rel
173#define ELFCLASSM ELFCLASS32
174#define CONFIG_USE_GOT_ENTRIES
175#define CONFIG_GOT_ENTRY_SIZE 4
176#define CONFIG_USE_SINGLE
177#endif
178
179/* IA64, aka Itanium */
180#if defined(__ia64__)
181#define MATCH_MACHINE(x) (x == EM_IA_64)
182#define SHT_RELM SHT_RELA
183#define Elf64_RelM Elf64_Rela
184#define ELFCLASSM ELFCLASS64
185#endif
186
187/* m68k */
188#if defined(__mc68000__)
189#define MATCH_MACHINE(x) (x == EM_68K)
190#define SHT_RELM SHT_RELA
191#define Elf32_RelM Elf32_Rela
192#define ELFCLASSM ELFCLASS32
193#define CONFIG_USE_GOT_ENTRIES
194#define CONFIG_GOT_ENTRY_SIZE 4
195#define CONFIG_USE_SINGLE
196#endif
197
198/* Microblaze */
199#if defined(__microblaze__)
200#define CONFIG_USE_SINGLE
201#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
202#define SHT_RELM SHT_RELA
203#define Elf32_RelM Elf32_Rela
204#define ELFCLASSM ELFCLASS32
205#endif
206
207/* MIPS */
208#if defined(__mips__)
209#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
210#define SHT_RELM SHT_REL
211#define Elf32_RelM Elf32_Rel
212#define ELFCLASSM ELFCLASS32
213/* Account for ELF spec changes. */
214#ifndef EM_MIPS_RS3_LE
215#ifdef EM_MIPS_RS4_BE
216#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
217#else
218#define EM_MIPS_RS3_LE 10
219#endif
220#endif /* !EM_MIPS_RS3_LE */
221#define ARCHDATAM "__dbe_table"
222#endif
223
224/* Nios II */
225#if defined(__nios2__)
226#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
227#define SHT_RELM SHT_RELA
228#define Elf32_RelM Elf32_Rela
229#define ELFCLASSM ELFCLASS32
230#endif
231
232/* PowerPC */
233#if defined(__powerpc64__)
234#define MATCH_MACHINE(x) (x == EM_PPC64)
235#define SHT_RELM SHT_RELA
236#define Elf64_RelM Elf64_Rela
237#define ELFCLASSM ELFCLASS64
238#elif defined(__powerpc__)
239#define MATCH_MACHINE(x) (x == EM_PPC)
240#define SHT_RELM SHT_RELA
241#define Elf32_RelM Elf32_Rela
242#define ELFCLASSM ELFCLASS32
243#define CONFIG_USE_PLT_ENTRIES
244#define CONFIG_PLT_ENTRY_SIZE 16
245#define CONFIG_USE_PLT_LIST
246#define CONFIG_LIST_ARCHTYPE ElfW(Addr)
247#define CONFIG_USE_LIST
248#define ARCHDATAM "__ftr_fixup"
249#endif
250
251/* S390 */
252#if defined(__s390__)
253#define MATCH_MACHINE(x) (x == EM_S390)
254#define SHT_RELM SHT_RELA
255#define Elf32_RelM Elf32_Rela
256#define ELFCLASSM ELFCLASS32
257#define CONFIG_USE_PLT_ENTRIES
258#define CONFIG_PLT_ENTRY_SIZE 8
259#define CONFIG_USE_GOT_ENTRIES
260#define CONFIG_GOT_ENTRY_SIZE 8
261#define CONFIG_USE_SINGLE
262#endif
263
264/* SuperH */
265#if defined(__sh__)
266#define MATCH_MACHINE(x) (x == EM_SH)
267#define SHT_RELM SHT_RELA
268#define Elf32_RelM Elf32_Rela
269#define ELFCLASSM ELFCLASS32
270#define CONFIG_USE_GOT_ENTRIES
271#define CONFIG_GOT_ENTRY_SIZE 4
272#define CONFIG_USE_SINGLE
273/* the SH changes have only been tested in =little endian= mode */
274/* I'm not sure about big endian, so let's warn: */
275#if defined(__sh__) && BB_BIG_ENDIAN
276# error insmod.c may require changes for use on big endian SH
277#endif
278/* it may or may not work on the SH1/SH2... Error on those also */
279#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
280#error insmod.c may require changes for SH1 or SH2 use
281#endif
282#endif
283
284/* Sparc */
285#if defined(__sparc__)
286#define MATCH_MACHINE(x) (x == EM_SPARC)
287#define SHT_RELM SHT_RELA
288#define Elf32_RelM Elf32_Rela
289#define ELFCLASSM ELFCLASS32
290#endif
291
292/* v850e */
293#if defined (__v850e__)
294#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
295#define SHT_RELM SHT_RELA
296#define Elf32_RelM Elf32_Rela
297#define ELFCLASSM ELFCLASS32
298#define CONFIG_USE_PLT_ENTRIES
299#define CONFIG_PLT_ENTRY_SIZE 8
300#define CONFIG_USE_SINGLE
301#ifndef EM_CYGNUS_V850 /* grumble */
302#define EM_CYGNUS_V850 0x9080
303#endif
304#define SYMBOL_PREFIX "_"
305#endif
306
307/* X86_64 */
308#if defined(__x86_64__)
309#define MATCH_MACHINE(x) (x == EM_X86_64)
310#define SHT_RELM SHT_RELA
311#define CONFIG_USE_GOT_ENTRIES
312#define CONFIG_GOT_ENTRY_SIZE 8
313#define CONFIG_USE_SINGLE
314#define Elf64_RelM Elf64_Rela
315#define ELFCLASSM ELFCLASS64
316#endif
317
318#ifndef SHT_RELM
319#error Sorry, but insmod.c does not yet support this architecture...
320#endif
321
322
323//----------------------------------------------------------------------------
324//--------modutils module.h, lines 45-242
325//----------------------------------------------------------------------------
326
327/* Definitions for the Linux module syscall interface.
328 Copyright 1996, 1997 Linux International.
329
330 Contributed by Richard Henderson <rth@tamu.edu>
331
332 This file is part of the Linux modutils.
333
334 This program is free software; you can redistribute it and/or modify it
335 under the terms of the GNU General Public License as published by the
336 Free Software Foundation; either version 2 of the License, or (at your
337 option) any later version.
338
339 This program is distributed in the hope that it will be useful, but
340 WITHOUT ANY WARRANTY; without even the implied warranty of
341 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
342 General Public License for more details.
343
344 You should have received a copy of the GNU General Public License
345 along with this program; if not, write to the Free Software Foundation,
346 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
347
348
349#ifndef MODUTILS_MODULE_H
350/* Why? static const int MODUTILS_MODULE_H = 1;*/
351
352#ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"
353
354/*======================================================================*/
355/* For sizeof() which are related to the module platform and not to the
356 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
357
358#define tgt_sizeof_char sizeof(char)
359#define tgt_sizeof_short sizeof(short)
360#define tgt_sizeof_int sizeof(int)
361#define tgt_sizeof_long sizeof(long)
362#define tgt_sizeof_char_p sizeof(char *)
363#define tgt_sizeof_void_p sizeof(void *)
364#define tgt_long long
365
366#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
367#undef tgt_sizeof_long
368#undef tgt_sizeof_char_p
369#undef tgt_sizeof_void_p
370#undef tgt_long
371enum {
372 tgt_sizeof_long = 8,
373 tgt_sizeof_char_p = 8,
374 tgt_sizeof_void_p = 8
375};
376#define tgt_long long long
377#endif
378
379/*======================================================================*/
380/* The structures used in Linux 2.1. */
381
382/* Note: new_module_symbol does not use tgt_long intentionally */
383struct new_module_symbol
384{
385 unsigned long value;
386 unsigned long name;
387};
388
389struct new_module_persist;
390
391struct new_module_ref
392{
393 unsigned tgt_long dep; /* kernel addresses */
394 unsigned tgt_long ref;
395 unsigned tgt_long next_ref;
396};
397
398struct new_module
399{
400 unsigned tgt_long size_of_struct; /* == sizeof(module) */
401 unsigned tgt_long next;
402 unsigned tgt_long name;
403 unsigned tgt_long size;
404
405 tgt_long usecount;
406 unsigned tgt_long flags; /* AUTOCLEAN et al */
407
408 unsigned nsyms;
409 unsigned ndeps;
410
411 unsigned tgt_long syms;
412 unsigned tgt_long deps;
413 unsigned tgt_long refs;
414 unsigned tgt_long init;
415 unsigned tgt_long cleanup;
416 unsigned tgt_long ex_table_start;
417 unsigned tgt_long ex_table_end;
418#ifdef __alpha__
419 unsigned tgt_long gp;
420#endif
421 /* Everything after here is extension. */
422 unsigned tgt_long persist_start;
423 unsigned tgt_long persist_end;
424 unsigned tgt_long can_unload;
425 unsigned tgt_long runsize;
426 const char *kallsyms_start; /* All symbols for kernel debugging */
427 const char *kallsyms_end;
428 const char *archdata_start; /* arch specific data for module */
429 const char *archdata_end;
430 const char *kernel_data; /* Reserved for kernel internal use */
431};
432
433#ifdef ARCHDATAM
434#define ARCHDATA_SEC_NAME ARCHDATAM
435#else
436#define ARCHDATA_SEC_NAME "__archdata"
437#endif
438#define KALLSYMS_SEC_NAME "__kallsyms"
439
440
441struct new_module_info
442{
443 unsigned long addr;
444 unsigned long size;
445 unsigned long flags;
446 long usecount;
447};
448
449/* Bits of module.flags. */
450enum {
451 NEW_MOD_RUNNING = 1,
452 NEW_MOD_DELETED = 2,
453 NEW_MOD_AUTOCLEAN = 4,
454 NEW_MOD_VISITED = 8,
455 NEW_MOD_USED_ONCE = 16
456};
457
458int init_module(const char *name, const struct new_module *);
459int query_module(const char *name, int which, void *buf,
460 size_t bufsize, size_t *ret);
461
462/* Values for query_module's which. */
463enum {
464 QM_MODULES = 1,
465 QM_DEPS = 2,
466 QM_REFS = 3,
467 QM_SYMBOLS = 4,
468 QM_INFO = 5
469};
470
471/*======================================================================*/
472/* The system calls unchanged between 2.0 and 2.1. */
473
474unsigned long create_module(const char *, size_t);
475int delete_module(const char *);
476
477
478#endif /* module.h */
479
480//----------------------------------------------------------------------------
481//--------end of modutils module.h
482//----------------------------------------------------------------------------
483
484
485
486//----------------------------------------------------------------------------
487//--------modutils obj.h, lines 253-462
488//----------------------------------------------------------------------------
489
490/* Elf object file loading and relocation routines.
491 Copyright 1996, 1997 Linux International.
492
493 Contributed by Richard Henderson <rth@tamu.edu>
494
495 This file is part of the Linux modutils.
496
497 This program is free software; you can redistribute it and/or modify it
498 under the terms of the GNU General Public License as published by the
499 Free Software Foundation; either version 2 of the License, or (at your
500 option) any later version.
501
502 This program is distributed in the hope that it will be useful, but
503 WITHOUT ANY WARRANTY; without even the implied warranty of
504 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
505 General Public License for more details.
506
507 You should have received a copy of the GNU General Public License
508 along with this program; if not, write to the Free Software Foundation,
509 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
510
511
512#ifndef MODUTILS_OBJ_H
513/* Why? static const int MODUTILS_OBJ_H = 1; */
514
515#ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"
516
517/* The relocatable object is manipulated using elfin types. */
518
519#include <stdio.h>
520#include <elf.h>
521#include <endian.h>
522
523#ifndef ElfW
524# if ELFCLASSM == ELFCLASS32
525# define ElfW(x) Elf32_ ## x
526# define ELFW(x) ELF32_ ## x
527# else
528# define ElfW(x) Elf64_ ## x
529# define ELFW(x) ELF64_ ## x
530# endif
531#endif
532
533/* For some reason this is missing from some ancient C libraries.... */
534#ifndef ELF32_ST_INFO
535# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
536#endif
537
538#ifndef ELF64_ST_INFO
539# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
540#endif
541
542#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
543#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
544#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
545#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
546#define ELF_R_SYM(val) ELFW(R_SYM)(val)
547
548struct obj_string_patch;
549struct obj_symbol_patch;
550
551struct obj_section
552{
553 ElfW(Shdr) header;
554 const char *name;
555 char *contents;
556 struct obj_section *load_next;
557 int idx;
558};
559
560struct obj_symbol
561{
562 struct obj_symbol *next; /* hash table link */
563 const char *name;
564 unsigned long value;
565 unsigned long size;
566 int secidx; /* the defining section index/module */
567 int info;
568 int ksymidx; /* for export to the kernel symtab */
569 int referenced; /* actually used in the link */
570};
571
572/* Hardcode the hash table size. We shouldn't be needing so many
573 symbols that we begin to degrade performance, and we get a big win
574 by giving the compiler a constant divisor. */
575
576#define HASH_BUCKETS 521
577
578struct obj_file
579{
580 ElfW(Ehdr) header;
581 ElfW(Addr) baseaddr;
582 struct obj_section **sections;
583 struct obj_section *load_order;
584 struct obj_section **load_order_search_start;
585 struct obj_string_patch *string_patches;
586 struct obj_symbol_patch *symbol_patches;
587 int (*symbol_cmp)(const char *, const char *);
588 unsigned long (*symbol_hash)(const char *);
589 unsigned long local_symtab_size;
590 struct obj_symbol **local_symtab;
591 struct obj_symbol *symtab[HASH_BUCKETS];
592};
593
594enum obj_reloc
595{
596 obj_reloc_ok,
597 obj_reloc_overflow,
598 obj_reloc_dangerous,
599 obj_reloc_unhandled
600};
601
602struct obj_string_patch
603{
604 struct obj_string_patch *next;
605 int reloc_secidx;
606 ElfW(Addr) reloc_offset;
607 ElfW(Addr) string_offset;
608};
609
610struct obj_symbol_patch
611{
612 struct obj_symbol_patch *next;
613 int reloc_secidx;
614 ElfW(Addr) reloc_offset;
615 struct obj_symbol *sym;
616};
617
618
619/* Generic object manipulation routines. */
620
621static unsigned long obj_elf_hash(const char *);
622
623static unsigned long obj_elf_hash_n(const char *, unsigned long len);
624
625static struct obj_symbol *obj_find_symbol (struct obj_file *f,
626 const char *name);
627
628static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
629 struct obj_symbol *sym);
630
631#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
632static void obj_set_symbol_compare(struct obj_file *f,
633 int (*cmp)(const char *, const char *),
634 unsigned long (*hash)(const char *));
635#endif
636
637static struct obj_section *obj_find_section (struct obj_file *f,
638 const char *name);
639
640static void obj_insert_section_load_order (struct obj_file *f,
641 struct obj_section *sec);
642
643static struct obj_section *obj_create_alloced_section (struct obj_file *f,
644 const char *name,
645 unsigned long align,
646 unsigned long size);
647
648static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
649 const char *name,
650 unsigned long align,
651 unsigned long size);
652
653static void *obj_extend_section (struct obj_section *sec, unsigned long more);
654
655static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
656 const char *string);
657
658static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
659 struct obj_symbol *sym);
660
661static int obj_check_undefineds(struct obj_file *f);
662
663static void obj_allocate_commons(struct obj_file *f);
664
665static unsigned long obj_load_size (struct obj_file *f);
666
667static int obj_relocate (struct obj_file *f, ElfW(Addr) base);
668
669static struct obj_file *obj_load(FILE *f, int loadprogbits);
670
671static int obj_create_image (struct obj_file *f, char *image);
672
673/* Architecture specific manipulation routines. */
674
675static struct obj_file *arch_new_file (void);
676
677static struct obj_section *arch_new_section (void);
678
679static struct obj_symbol *arch_new_symbol (void);
680
681static enum obj_reloc arch_apply_relocation (struct obj_file *f,
682 struct obj_section *targsec,
683 struct obj_section *symsec,
684 struct obj_symbol *sym,
685 ElfW(RelM) *rel, ElfW(Addr) value);
686
687static void arch_create_got (struct obj_file *f);
688#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
689static int obj_gpl_license(struct obj_file *f, const char **license);
690#endif /* ENABLE_FEATURE_CHECK_TAINTED_MODULE */
691#endif /* obj.h */
692//----------------------------------------------------------------------------
693//--------end of modutils obj.h
694//----------------------------------------------------------------------------
695
696
697/* SPFX is always a string, so it can be concatenated to string constants. */
698#ifdef SYMBOL_PREFIX
699#define SPFX SYMBOL_PREFIX
700#else
701#define SPFX ""
702#endif
703
704
705#define _PATH_MODULES "/lib/modules"
706enum { STRVERSIONLEN = 32 };
707
708/*======================================================================*/
709
710static int flag_force_load = 0;
711static int flag_autoclean = 0;
712static int flag_verbose = 0;
713static int flag_quiet = 0;
714static int flag_export = 1;
715
716
717/*======================================================================*/
718
719#if defined(CONFIG_USE_LIST)
720
721struct arch_list_entry
722{
723 struct arch_list_entry *next;
724 CONFIG_LIST_ARCHTYPE addend;
725 int offset;
726 int inited : 1;
727};
728
729#endif
730
731#if defined(CONFIG_USE_SINGLE)
732
733struct arch_single_entry
734{
735 int offset;
736 int inited : 1;
737 int allocated : 1;
738};
739
740#endif
741
742#if defined(__mips__)
743struct mips_hi16
744{
745 struct mips_hi16 *next;
746 ElfW(Addr) *addr;
747 ElfW(Addr) value;
748};
749#endif
750
751struct arch_file {
752 struct obj_file root;
753#if defined(CONFIG_USE_PLT_ENTRIES)
754 struct obj_section *plt;
755#endif
756#if defined(CONFIG_USE_GOT_ENTRIES)
757 struct obj_section *got;
758#endif
759#if defined(__mips__)
760 struct mips_hi16 *mips_hi16_list;
761#endif
762};
763
764struct arch_symbol {
765 struct obj_symbol root;
766#if defined(CONFIG_USE_PLT_ENTRIES)
767#if defined(CONFIG_USE_PLT_LIST)
768 struct arch_list_entry *pltent;
769#else
770 struct arch_single_entry pltent;
771#endif
772#endif
773#if defined(CONFIG_USE_GOT_ENTRIES)
774 struct arch_single_entry gotent;
775#endif
776};
777
778
779struct external_module {
780 const char *name;
781 ElfW(Addr) addr;
782 int used;
783 size_t nsyms;
784 struct new_module_symbol *syms;
785};
786
787static struct new_module_symbol *ksyms;
788static size_t nksyms;
789
790static struct external_module *ext_modules;
791static int n_ext_modules;
792static int n_ext_modules_used;
793extern int delete_module(const char *);
794
795static char *m_filename;
796static char *m_fullName;
797
798
799
800/*======================================================================*/
801
802
803static int check_module_name_match(const char *filename, struct stat *statbuf,
804 void *userdata)
805{
806 char *fullname = (char *) userdata;
807
808 if (fullname[0] == '\0')
809 return (FALSE);
810 else {
811 char *tmp, *tmp1 = bb_xstrdup(filename);
812 tmp = bb_get_last_path_component(tmp1);
813 if (strcmp(tmp, fullname) == 0) {
814 free(tmp1);
815 /* Stop searching if we find a match */
816 m_filename = bb_xstrdup(filename);
817 return (FALSE);
818 }
819 free(tmp1);
820 }
821 return (TRUE);
822}
823
824
825/*======================================================================*/
826
827static struct obj_file *arch_new_file(void)
828{
829 struct arch_file *f;
830 f = xmalloc(sizeof(*f));
831
832 memset(f, 0, sizeof(*f));
833
834 return &f->root;
835}
836
837static struct obj_section *arch_new_section(void)
838{
839 return xmalloc(sizeof(struct obj_section));
840}
841
842static struct obj_symbol *arch_new_symbol(void)
843{
844 struct arch_symbol *sym;
845 sym = xmalloc(sizeof(*sym));
846
847 memset(sym, 0, sizeof(*sym));
848
849 return &sym->root;
850}
851
852static enum obj_reloc
853arch_apply_relocation(struct obj_file *f,
854 struct obj_section *targsec,
855 struct obj_section *symsec,
856 struct obj_symbol *sym,
857 ElfW(RelM) *rel, ElfW(Addr) v)
858{
859 struct arch_file *ifile = (struct arch_file *) f;
860 enum obj_reloc ret = obj_reloc_ok;
861 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
862 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
863#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
864 struct arch_symbol *isym = (struct arch_symbol *) sym;
865#endif
866#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) || defined(__sh__) || defined(__s390__)
867#if defined(CONFIG_USE_GOT_ENTRIES)
868 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
869#endif
870#endif
871#if defined(CONFIG_USE_PLT_ENTRIES)
872 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
873 unsigned long *ip;
874# if defined(CONFIG_USE_PLT_LIST)
875 struct arch_list_entry *pe;
876# else
877 struct arch_single_entry *pe;
878# endif
879#endif
880
881 switch (ELF_R_TYPE(rel->r_info)) {
882
883#if defined(__arm__)
884
885 case R_ARM_NONE:
886 break;
887
888 case R_ARM_ABS32:
889 *loc += v;
890 break;
891
892 case R_ARM_GOT32:
893 goto bb_use_got;
894
895 case R_ARM_GOTPC:
896 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
897 * (which is .got) similar to branch,
898 * but is full 32 bits relative */
899
900 assert(got != 0);
901 *loc += got - dot;
902 break;
903
904 case R_ARM_PC24:
905 case R_ARM_PLT32:
906 goto bb_use_plt;
907
908 case R_ARM_GOTOFF: /* address relative to the got */
909 assert(got != 0);
910 *loc += v - got;
911 break;
912
913#elif defined(__cris__)
914
915 case R_CRIS_NONE:
916 break;
917
918 case R_CRIS_32:
919 /* CRIS keeps the relocation value in the r_addend field and
920 * should not use whats in *loc at all
921 */
922 *loc = v;
923 break;
924
925#elif defined(__H8300H__) || defined(__H8300S__)
926
927 case R_H8_DIR24R8:
928 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
929 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
930 break;
931 case R_H8_DIR24A8:
932 *loc += v;
933 break;
934 case R_H8_DIR32:
935 case R_H8_DIR32A16:
936 *loc += v;
937 break;
938 case R_H8_PCREL16:
939 v -= dot + 2;
940 if ((ElfW(Sword))v > 0x7fff ||
941 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
942 ret = obj_reloc_overflow;
943 else
944 *(unsigned short *)loc = v;
945 break;
946 case R_H8_PCREL8:
947 v -= dot + 1;
948 if ((ElfW(Sword))v > 0x7f ||
949 (ElfW(Sword))v < -(ElfW(Sword))0x80)
950 ret = obj_reloc_overflow;
951 else
952 *(unsigned char *)loc = v;
953 break;
954
955#elif defined(__i386__)
956
957 case R_386_NONE:
958 break;
959
960 case R_386_32:
961 *loc += v;
962 break;
963
964 case R_386_PLT32:
965 case R_386_PC32:
966 *loc += v - dot;
967 break;
968
969 case R_386_GLOB_DAT:
970 case R_386_JMP_SLOT:
971 *loc = v;
972 break;
973
974 case R_386_RELATIVE:
975 *loc += f->baseaddr;
976 break;
977
978 case R_386_GOTPC:
979 assert(got != 0);
980 *loc += got - dot;
981 break;
982
983 case R_386_GOT32:
984 goto bb_use_got;
985
986 case R_386_GOTOFF:
987 assert(got != 0);
988 *loc += v - got;
989 break;
990
991#elif defined (__microblaze__)
992 case R_MICROBLAZE_NONE:
993 case R_MICROBLAZE_64_NONE:
994 case R_MICROBLAZE_32_SYM_OP_SYM:
995 case R_MICROBLAZE_32_PCREL:
996 break;
997
998 case R_MICROBLAZE_64_PCREL: {
999 /* dot is the address of the current instruction.
1000 * v is the target symbol address.
1001 * So we need to extract the offset in the code,
1002 * adding v, then subtrating the current address
1003 * of this instruction.
1004 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
1005 */
1006
1007 /* Get split offset stored in code */
1008 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
1009 (loc[1] & 0xFFFF);
1010
1011 /* Adjust relative offset. -4 adjustment required
1012 * because dot points to the IMM insn, but branch
1013 * is computed relative to the branch instruction itself.
1014 */
1015 temp += v - dot - 4;
1016
1017 /* Store back into code */
1018 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
1019 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
1020
1021 break;
1022 }
1023
1024 case R_MICROBLAZE_32:
1025 *loc += v;
1026 break;
1027
1028 case R_MICROBLAZE_64: {
1029 /* Get split pointer stored in code */
1030 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
1031 (loc[1] & 0xFFFF);
1032
1033 /* Add reloc offset */
1034 temp1+=v;
1035
1036 /* Store back into code */
1037 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
1038 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
1039
1040 break;
1041 }
1042
1043 case R_MICROBLAZE_32_PCREL_LO:
1044 case R_MICROBLAZE_32_LO:
1045 case R_MICROBLAZE_SRO32:
1046 case R_MICROBLAZE_SRW32:
1047 ret = obj_reloc_unhandled;
1048 break;
1049
1050#elif defined(__mc68000__)
1051
1052 case R_68K_NONE:
1053 break;
1054
1055 case R_68K_32:
1056 *loc += v;
1057 break;
1058
1059 case R_68K_8:
1060 if (v > 0xff) {
1061 ret = obj_reloc_overflow;
1062 }
1063 *(char *)loc = v;
1064 break;
1065
1066 case R_68K_16:
1067 if (v > 0xffff) {
1068 ret = obj_reloc_overflow;
1069 }
1070 *(short *)loc = v;
1071 break;
1072
1073 case R_68K_PC8:
1074 v -= dot;
1075 if ((ElfW(Sword))v > 0x7f ||
1076 (ElfW(Sword))v < -(ElfW(Sword))0x80) {
1077 ret = obj_reloc_overflow;
1078 }
1079 *(char *)loc = v;
1080 break;
1081
1082 case R_68K_PC16:
1083 v -= dot;
1084 if ((ElfW(Sword))v > 0x7fff ||
1085 (ElfW(Sword))v < -(ElfW(Sword))0x8000) {
1086 ret = obj_reloc_overflow;
1087 }
1088 *(short *)loc = v;
1089 break;
1090
1091 case R_68K_PC32:
1092 *(int *)loc = v - dot;
1093 break;
1094
1095 case R_68K_GLOB_DAT:
1096 case R_68K_JMP_SLOT:
1097 *loc = v;
1098 break;
1099
1100 case R_68K_RELATIVE:
1101 *(int *)loc += f->baseaddr;
1102 break;
1103
1104 case R_68K_GOT32:
1105 goto bb_use_got;
1106
1107# ifdef R_68K_GOTOFF
1108 case R_68K_GOTOFF:
1109 assert(got != 0);
1110 *loc += v - got;
1111 break;
1112# endif
1113
1114#elif defined(__mips__)
1115
1116 case R_MIPS_NONE:
1117 break;
1118
1119 case R_MIPS_32:
1120 *loc += v;
1121 break;
1122
1123 case R_MIPS_26:
1124 if (v % 4)
1125 ret = obj_reloc_dangerous;
1126 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1127 ret = obj_reloc_overflow;
1128 *loc =
1129 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1130 0x03ffffff);
1131 break;
1132
1133 case R_MIPS_HI16:
1134 {
1135 struct mips_hi16 *n;
1136
1137 /* We cannot relocate this one now because we don't know the value
1138 of the carry we need to add. Save the information, and let LO16
1139 do the actual relocation. */
1140 n = (struct mips_hi16 *) xmalloc(sizeof *n);
1141 n->addr = loc;
1142 n->value = v;
1143 n->next = ifile->mips_hi16_list;
1144 ifile->mips_hi16_list = n;
1145 break;
1146 }
1147
1148 case R_MIPS_LO16:
1149 {
1150 unsigned long insnlo = *loc;
1151 ElfW(Addr) val, vallo;
1152
1153 /* Sign extend the addend we extract from the lo insn. */
1154 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1155
1156 if (ifile->mips_hi16_list != NULL) {
1157 struct mips_hi16 *l;
1158
1159 l = ifile->mips_hi16_list;
1160 while (l != NULL) {
1161 struct mips_hi16 *next;
1162 unsigned long insn;
1163
1164 /* The value for the HI16 had best be the same. */
1165 assert(v == l->value);
1166
1167 /* Do the HI16 relocation. Note that we actually don't
1168 need to know anything about the LO16 itself, except where
1169 to find the low 16 bits of the addend needed by the LO16. */
1170 insn = *l->addr;
1171 val =
1172 ((insn & 0xffff) << 16) +
1173 vallo;
1174 val += v;
1175
1176 /* Account for the sign extension that will happen in the
1177 low bits. */
1178 val =
1179 ((val >> 16) +
1180 ((val & 0x8000) !=
1181 0)) & 0xffff;
1182
1183 insn = (insn & ~0xffff) | val;
1184 *l->addr = insn;
1185
1186 next = l->next;
1187 free(l);
1188 l = next;
1189 }
1190
1191 ifile->mips_hi16_list = NULL;
1192 }
1193
1194 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1195 val = v + vallo;
1196 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1197 *loc = insnlo;
1198 break;
1199 }
1200
1201#elif defined(__nios2__)
1202
1203 case R_NIOS2_NONE:
1204 break;
1205
1206 case R_NIOS2_BFD_RELOC_32:
1207 *loc += v;
1208 break;
1209
1210 case R_NIOS2_BFD_RELOC_16:
1211 if (v > 0xffff) {
1212 ret = obj_reloc_overflow;
1213 }
1214 *(short *)loc = v;
1215 break;
1216
1217 case R_NIOS2_BFD_RELOC_8:
1218 if (v > 0xff) {
1219 ret = obj_reloc_overflow;
1220 }
1221 *(char *)loc = v;
1222 break;
1223
1224 case R_NIOS2_S16:
1225 {
1226 Elf32_Addr word;
1227
1228 if ((Elf32_Sword)v > 0x7fff ||
1229 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1230 ret = obj_reloc_overflow;
1231 }
1232
1233 word = *loc;
1234 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1235 (word & 0x3f);
1236 }
1237 break;
1238
1239 case R_NIOS2_U16:
1240 {
1241 Elf32_Addr word;
1242
1243 if (v > 0xffff) {
1244 ret = obj_reloc_overflow;
1245 }
1246
1247 word = *loc;
1248 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1249 (word & 0x3f);
1250 }
1251 break;
1252
1253 case R_NIOS2_PCREL16:
1254 {
1255 Elf32_Addr word;
1256
1257 v -= dot + 4;
1258 if ((Elf32_Sword)v > 0x7fff ||
1259 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1260 ret = obj_reloc_overflow;
1261 }
1262
1263 word = *loc;
1264 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1265 }
1266 break;
1267
1268 case R_NIOS2_GPREL:
1269 {
1270 Elf32_Addr word, gp;
1271 /* get _gp */
1272 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
1273 v-=gp;
1274 if ((Elf32_Sword)v > 0x7fff ||
1275 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1276 ret = obj_reloc_overflow;
1277 }
1278
1279 word = *loc;
1280 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1281 }
1282 break;
1283
1284 case R_NIOS2_CALL26:
1285 if (v & 3)
1286 ret = obj_reloc_dangerous;
1287 if ((v >> 28) != (dot >> 28))
1288 ret = obj_reloc_overflow;
1289 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1290 break;
1291
1292 case R_NIOS2_IMM5:
1293 {
1294 Elf32_Addr word;
1295
1296 if (v > 0x1f) {
1297 ret = obj_reloc_overflow;
1298 }
1299
1300 word = *loc & ~0x7c0;
1301 *loc = word | ((v & 0x1f) << 6);
1302 }
1303 break;
1304
1305 case R_NIOS2_IMM6:
1306 {
1307 Elf32_Addr word;
1308
1309 if (v > 0x3f) {
1310 ret = obj_reloc_overflow;
1311 }
1312
1313 word = *loc & ~0xfc0;
1314 *loc = word | ((v & 0x3f) << 6);
1315 }
1316 break;
1317
1318 case R_NIOS2_IMM8:
1319 {
1320 Elf32_Addr word;
1321
1322 if (v > 0xff) {
1323 ret = obj_reloc_overflow;
1324 }
1325
1326 word = *loc & ~0x3fc0;
1327 *loc = word | ((v & 0xff) << 6);
1328 }
1329 break;
1330
1331 case R_NIOS2_HI16:
1332 {
1333 Elf32_Addr word;
1334
1335 word = *loc;
1336 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1337 (word & 0x3f);
1338 }
1339 break;
1340
1341 case R_NIOS2_LO16:
1342 {
1343 Elf32_Addr word;
1344
1345 word = *loc;
1346 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1347 (word & 0x3f);
1348 }
1349 break;
1350
1351 case R_NIOS2_HIADJ16:
1352 {
1353 Elf32_Addr word1, word2;
1354
1355 word1 = *loc;
1356 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1357 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1358 (word1 & 0x3f);
1359 }
1360 break;
1361
1362#elif defined(__powerpc64__)
1363 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
1364
1365#elif defined(__powerpc__)
1366
1367 case R_PPC_ADDR16_HA:
1368 *(unsigned short *)loc = (v + 0x8000) >> 16;
1369 break;
1370
1371 case R_PPC_ADDR16_HI:
1372 *(unsigned short *)loc = v >> 16;
1373 break;
1374
1375 case R_PPC_ADDR16_LO:
1376 *(unsigned short *)loc = v;
1377 break;
1378
1379 case R_PPC_REL24:
1380 goto bb_use_plt;
1381
1382 case R_PPC_REL32:
1383 *loc = v - dot;
1384 break;
1385
1386 case R_PPC_ADDR32:
1387 *loc = v;
1388 break;
1389
1390#elif defined(__s390__)
1391
1392 case R_390_32:
1393 *(unsigned int *) loc += v;
1394 break;
1395 case R_390_16:
1396 *(unsigned short *) loc += v;
1397 break;
1398 case R_390_8:
1399 *(unsigned char *) loc += v;
1400 break;
1401
1402 case R_390_PC32:
1403 *(unsigned int *) loc += v - dot;
1404 break;
1405 case R_390_PC16DBL:
1406 *(unsigned short *) loc += (v - dot) >> 1;
1407 break;
1408 case R_390_PC16:
1409 *(unsigned short *) loc += v - dot;
1410 break;
1411
1412 case R_390_PLT32:
1413 case R_390_PLT16DBL:
1414 /* find the plt entry and initialize it. */
1415 assert(isym != NULL);
1416 pe = (struct arch_single_entry *) &isym->pltent;
1417 assert(pe->allocated);
1418 if (pe->inited == 0) {
1419 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1420 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1421 ip[1] = 0x100607f1;
1422 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1423 ip[2] = v - 2;
1424 else
1425 ip[2] = v;
1426 pe->inited = 1;
1427 }
1428
1429 /* Insert relative distance to target. */
1430 v = plt + pe->offset - dot;
1431 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1432 *(unsigned int *) loc = (unsigned int) v;
1433 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1434 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1435 break;
1436
1437 case R_390_GLOB_DAT:
1438 case R_390_JMP_SLOT:
1439 *loc = v;
1440 break;
1441
1442 case R_390_RELATIVE:
1443 *loc += f->baseaddr;
1444 break;
1445
1446 case R_390_GOTPC:
1447 assert(got != 0);
1448 *(unsigned long *) loc += got - dot;
1449 break;
1450
1451 case R_390_GOT12:
1452 case R_390_GOT16:
1453 case R_390_GOT32:
1454 assert(isym != NULL);
1455 assert(got != 0);
1456 if (!isym->gotent.inited)
1457 {
1458 isym->gotent.inited = 1;
1459 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1460 }
1461 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1462 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1463 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1464 *(unsigned short *) loc += isym->gotent.offset;
1465 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1466 *(unsigned int *) loc += isym->gotent.offset;
1467 break;
1468
1469# ifndef R_390_GOTOFF32
1470# define R_390_GOTOFF32 R_390_GOTOFF
1471# endif
1472 case R_390_GOTOFF32:
1473 assert(got != 0);
1474 *loc += v - got;
1475 break;
1476
1477#elif defined(__sh__)
1478
1479 case R_SH_NONE:
1480 break;
1481
1482 case R_SH_DIR32:
1483 *loc += v;
1484 break;
1485
1486 case R_SH_REL32:
1487 *loc += v - dot;
1488 break;
1489
1490 case R_SH_PLT32:
1491 *loc = v - dot;
1492 break;
1493
1494 case R_SH_GLOB_DAT:
1495 case R_SH_JMP_SLOT:
1496 *loc = v;
1497 break;
1498
1499 case R_SH_RELATIVE:
1500 *loc = f->baseaddr + rel->r_addend;
1501 break;
1502
1503 case R_SH_GOTPC:
1504 assert(got != 0);
1505 *loc = got - dot + rel->r_addend;
1506 break;
1507
1508 case R_SH_GOT32:
1509 goto bb_use_got;
1510
1511 case R_SH_GOTOFF:
1512 assert(got != 0);
1513 *loc = v - got;
1514 break;
1515
1516# if defined(__SH5__)
1517 case R_SH_IMM_MEDLOW16:
1518 case R_SH_IMM_LOW16:
1519 {
1520 ElfW(Addr) word;
1521
1522 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1523 v >>= 16;
1524
1525 /*
1526 * movi and shori have the format:
1527 *
1528 * | op | imm | reg | reserved |
1529 * 31..26 25..10 9.. 4 3 .. 0
1530 *
1531 * so we simply mask and or in imm.
1532 */
1533 word = *loc & ~0x3fffc00;
1534 word |= (v & 0xffff) << 10;
1535
1536 *loc = word;
1537
1538 break;
1539 }
1540
1541 case R_SH_IMM_MEDLOW16_PCREL:
1542 case R_SH_IMM_LOW16_PCREL:
1543 {
1544 ElfW(Addr) word;
1545
1546 word = *loc & ~0x3fffc00;
1547
1548 v -= dot;
1549
1550 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1551 v >>= 16;
1552
1553 word |= (v & 0xffff) << 10;
1554
1555 *loc = word;
1556
1557 break;
1558 }
1559# endif /* __SH5__ */
1560
1561#elif defined (__v850e__)
1562
1563 case R_V850_NONE:
1564 break;
1565
1566 case R_V850_32:
1567 /* We write two shorts instead of a long because even
1568 32-bit insns only need half-word alignment, but
1569 32-bit data needs to be long-word aligned. */
1570 v += ((unsigned short *)loc)[0];
1571 v += ((unsigned short *)loc)[1] << 16;
1572 ((unsigned short *)loc)[0] = v & 0xffff;
1573 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1574 break;
1575
1576 case R_V850_22_PCREL:
1577 goto bb_use_plt;
1578
1579#elif defined(__x86_64__)
1580
1581 case R_X86_64_NONE:
1582 break;
1583
1584 case R_X86_64_64:
1585 *loc += v;
1586 break;
1587
1588 case R_X86_64_32:
1589 *(unsigned int *) loc += v;
1590 if (v > 0xffffffff)
1591 {
1592 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1593 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1594 }
1595 break;
1596
1597 case R_X86_64_32S:
1598 *(signed int *) loc += v;
1599 break;
1600
1601 case R_X86_64_16:
1602 *(unsigned short *) loc += v;
1603 break;
1604
1605 case R_X86_64_8:
1606 *(unsigned char *) loc += v;
1607 break;
1608
1609 case R_X86_64_PC32:
1610 *(unsigned int *) loc += v - dot;
1611 break;
1612
1613 case R_X86_64_PC16:
1614 *(unsigned short *) loc += v - dot;
1615 break;
1616
1617 case R_X86_64_PC8:
1618 *(unsigned char *) loc += v - dot;
1619 break;
1620
1621 case R_X86_64_GLOB_DAT:
1622 case R_X86_64_JUMP_SLOT:
1623 *loc = v;
1624 break;
1625
1626 case R_X86_64_RELATIVE:
1627 *loc += f->baseaddr;
1628 break;
1629
1630 case R_X86_64_GOT32:
1631 case R_X86_64_GOTPCREL:
1632 goto bb_use_got;
1633# if 0
1634 assert(isym != NULL);
1635 if (!isym->gotent.reloc_done)
1636 {
1637 isym->gotent.reloc_done = 1;
1638 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1639 }
1640 /* XXX are these really correct? */
1641 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1642 *(unsigned int *) loc += v + isym->gotent.offset;
1643 else
1644 *loc += isym->gotent.offset;
1645 break;
1646# endif
1647
1648#else
1649# warning "no idea how to handle relocations on your arch"
1650#endif
1651
1652 default:
1653 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1654 ret = obj_reloc_unhandled;
1655 break;
1656
1657#if defined(CONFIG_USE_PLT_ENTRIES)
1658
1659bb_use_plt:
1660
1661 /* find the plt entry and initialize it if necessary */
1662 assert(isym != NULL);
1663
1664#if defined(CONFIG_USE_PLT_LIST)
1665 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1666 pe = pe->next;
1667 assert(pe != NULL);
1668#else
1669 pe = &isym->pltent;
1670#endif
1671
1672 if (! pe->inited) {
1673 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1674
1675 /* generate some machine code */
1676
1677#if defined(__arm__)
1678 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1679 ip[1] = v; /* sym@ */
1680#endif
1681#if defined(__powerpc__)
1682 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1683 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1684 ip[2] = 0x7d6903a6; /* mtctr r11 */
1685 ip[3] = 0x4e800420; /* bctr */
1686#endif
1687#if defined (__v850e__)
1688 /* We have to trash a register, so we assume that any control
1689 transfer more than 21-bits away must be a function call
1690 (so we can use a call-clobbered register). */
1691 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1692 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
1693#endif
1694 pe->inited = 1;
1695 }
1696
1697 /* relative distance to target */
1698 v -= dot;
1699 /* if the target is too far away.... */
1700#if defined (__arm__) || defined (__powerpc__)
1701 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1702#elif defined (__v850e__)
1703 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1704#endif
1705 /* go via the plt */
1706 v = plt + pe->offset - dot;
1707
1708#if defined (__v850e__)
1709 if (v & 1)
1710#else
1711 if (v & 3)
1712#endif
1713 ret = obj_reloc_dangerous;
1714
1715 /* merge the offset into the instruction. */
1716#if defined(__arm__)
1717 /* Convert to words. */
1718 v >>= 2;
1719
1720 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1721#endif
1722#if defined(__powerpc__)
1723 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1724#endif
1725#if defined (__v850e__)
1726 /* We write two shorts instead of a long because even 32-bit insns
1727 only need half-word alignment, but the 32-bit data write needs
1728 to be long-word aligned. */
1729 ((unsigned short *)loc)[0] =
1730 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1731 | ((v >> 16) & 0x3f); /* offs high part */
1732 ((unsigned short *)loc)[1] =
1733 (v & 0xffff); /* offs low part */
1734#endif
1735 break;
1736#endif /* CONFIG_USE_PLT_ENTRIES */
1737
1738#if defined(CONFIG_USE_GOT_ENTRIES)
1739bb_use_got:
1740
1741 assert(isym != NULL);
1742 /* needs an entry in the .got: set it, once */
1743 if (!isym->gotent.inited) {
1744 isym->gotent.inited = 1;
1745 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1746 }
1747 /* make the reloc with_respect_to_.got */
1748#if defined(__sh__)
1749 *loc += isym->gotent.offset + rel->r_addend;
1750#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1751 *loc += isym->gotent.offset;
1752#endif
1753 break;
1754
1755#endif /* CONFIG_USE_GOT_ENTRIES */
1756 }
1757
1758 return ret;
1759}
1760
1761
1762#if defined(CONFIG_USE_LIST)
1763
1764static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1765 int offset, int size)
1766{
1767 struct arch_list_entry *pe;
1768
1769 for (pe = *list; pe != NULL; pe = pe->next) {
1770 if (pe->addend == rel->r_addend) {
1771 break;
1772 }
1773 }
1774
1775 if (pe == NULL) {
1776 pe = xmalloc(sizeof(struct arch_list_entry));
1777 pe->next = *list;
1778 pe->addend = rel->r_addend;
1779 pe->offset = offset;
1780 pe->inited = 0;
1781 *list = pe;
1782 return size;
1783 }
1784 return 0;
1785}
1786
1787#endif
1788
1789#if defined(CONFIG_USE_SINGLE)
1790
1791static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
1792 int offset, int size)
1793{
1794 if (single->allocated == 0) {
1795 single->allocated = 1;
1796 single->offset = offset;
1797 single->inited = 0;
1798 return size;
1799 }
1800 return 0;
1801}
1802
1803#endif
1804
1805#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
1806
1807static struct obj_section *arch_xsect_init(struct obj_file *f, char *name,
1808 int offset, int size)
1809{
1810 struct obj_section *myrelsec = obj_find_section(f, name);
1811
1812 if (offset == 0) {
1813 offset += size;
1814 }
1815
1816 if (myrelsec) {
1817 obj_extend_section(myrelsec, offset);
1818 } else {
1819 myrelsec = obj_create_alloced_section(f, name,
1820 size, offset);
1821 assert(myrelsec);
1822 }
1823
1824 return myrelsec;
1825}
1826
1827#endif
1828
1829static void arch_create_got(struct obj_file *f)
1830{
1831#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
1832 struct arch_file *ifile = (struct arch_file *) f;
1833 int i;
1834#if defined(CONFIG_USE_GOT_ENTRIES)
1835 int got_offset = 0, got_needed = 0, got_allocate;
1836#endif
1837#if defined(CONFIG_USE_PLT_ENTRIES)
1838 int plt_offset = 0, plt_needed = 0, plt_allocate;
1839#endif
1840 struct obj_section *relsec, *symsec, *strsec;
1841 ElfW(RelM) *rel, *relend;
1842 ElfW(Sym) *symtab, *extsym;
1843 const char *strtab, *name;
1844 struct arch_symbol *intsym;
1845
1846 for (i = 0; i < f->header.e_shnum; ++i) {
1847 relsec = f->sections[i];
1848 if (relsec->header.sh_type != SHT_RELM)
1849 continue;
1850
1851 symsec = f->sections[relsec->header.sh_link];
1852 strsec = f->sections[symsec->header.sh_link];
1853
1854 rel = (ElfW(RelM) *) relsec->contents;
1855 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1856 symtab = (ElfW(Sym) *) symsec->contents;
1857 strtab = (const char *) strsec->contents;
1858
1859 for (; rel < relend; ++rel) {
1860 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1861
1862#if defined(CONFIG_USE_GOT_ENTRIES)
1863 got_allocate = 0;
1864#endif
1865#if defined(CONFIG_USE_PLT_ENTRIES)
1866 plt_allocate = 0;
1867#endif
1868
1869 switch (ELF_R_TYPE(rel->r_info)) {
1870#if defined(__arm__)
1871 case R_ARM_PC24:
1872 case R_ARM_PLT32:
1873 plt_allocate = 1;
1874 break;
1875
1876 case R_ARM_GOTOFF:
1877 case R_ARM_GOTPC:
1878 got_needed = 1;
1879 continue;
1880
1881 case R_ARM_GOT32:
1882 got_allocate = 1;
1883 break;
1884
1885#elif defined(__i386__)
1886 case R_386_GOTPC:
1887 case R_386_GOTOFF:
1888 got_needed = 1;
1889 continue;
1890
1891 case R_386_GOT32:
1892 got_allocate = 1;
1893 break;
1894
1895#elif defined(__powerpc__)
1896 case R_PPC_REL24:
1897 plt_allocate = 1;
1898 break;
1899
1900#elif defined(__mc68000__)
1901 case R_68K_GOT32:
1902 got_allocate = 1;
1903 break;
1904
1905#ifdef R_68K_GOTOFF
1906 case R_68K_GOTOFF:
1907 got_needed = 1;
1908 continue;
1909#endif
1910
1911#elif defined(__sh__)
1912 case R_SH_GOT32:
1913 got_allocate = 1;
1914 break;
1915
1916 case R_SH_GOTPC:
1917 case R_SH_GOTOFF:
1918 got_needed = 1;
1919 continue;
1920
1921#elif defined (__v850e__)
1922 case R_V850_22_PCREL:
1923 plt_needed = 1;
1924 break;
1925
1926#endif
1927 default:
1928 continue;
1929 }
1930
1931 if (extsym->st_name != 0) {
1932 name = strtab + extsym->st_name;
1933 } else {
1934 name = f->sections[extsym->st_shndx]->name;
1935 }
1936 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1937#if defined(CONFIG_USE_GOT_ENTRIES)
1938 if (got_allocate) {
1939 got_offset += arch_single_init(
1940 rel, &intsym->gotent,
1941 got_offset, CONFIG_GOT_ENTRY_SIZE);
1942
1943 got_needed = 1;
1944 }
1945#endif
1946#if defined(CONFIG_USE_PLT_ENTRIES)
1947 if (plt_allocate) {
1948#if defined(CONFIG_USE_PLT_LIST)
1949 plt_offset += arch_list_add(
1950 rel, &intsym->pltent,
1951 plt_offset, CONFIG_PLT_ENTRY_SIZE);
1952#else
1953 plt_offset += arch_single_init(
1954 rel, &intsym->pltent,
1955 plt_offset, CONFIG_PLT_ENTRY_SIZE);
1956#endif
1957 plt_needed = 1;
1958 }
1959#endif
1960 }
1961 }
1962
1963#if defined(CONFIG_USE_GOT_ENTRIES)
1964 if (got_needed) {
1965 ifile->got = arch_xsect_init(f, ".got", got_offset,
1966 CONFIG_GOT_ENTRY_SIZE);
1967 }
1968#endif
1969
1970#if defined(CONFIG_USE_PLT_ENTRIES)
1971 if (plt_needed) {
1972 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1973 CONFIG_PLT_ENTRY_SIZE);
1974 }
1975#endif
1976
1977#endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */
1978}
1979
1980/*======================================================================*/
1981
1982/* Standard ELF hash function. */
1983static inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1984{
1985 unsigned long h = 0;
1986 unsigned long g;
1987 unsigned char ch;
1988
1989 while (n > 0) {
1990 ch = *name++;
1991 h = (h << 4) + ch;
1992 if ((g = (h & 0xf0000000)) != 0) {
1993 h ^= g >> 24;
1994 h &= ~g;
1995 }
1996 n--;
1997 }
1998 return h;
1999}
2000
2001static unsigned long obj_elf_hash(const char *name)
2002{
2003 return obj_elf_hash_n(name, strlen(name));
2004}
2005
2006#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
2007/* String comparison for non-co-versioned kernel and module. */
2008
2009static int ncv_strcmp(const char *a, const char *b)
2010{
2011 size_t alen = strlen(a), blen = strlen(b);
2012
2013 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
2014 return strncmp(a, b, alen);
2015 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
2016 return strncmp(a, b, blen);
2017 else
2018 return strcmp(a, b);
2019}
2020
2021/* String hashing for non-co-versioned kernel and module. Here
2022 we are simply forced to drop the crc from the hash. */
2023
2024static unsigned long ncv_symbol_hash(const char *str)
2025{
2026 size_t len = strlen(str);
2027 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
2028 len -= 10;
2029 return obj_elf_hash_n(str, len);
2030}
2031
2032static void
2033obj_set_symbol_compare(struct obj_file *f,
2034 int (*cmp) (const char *, const char *),
2035 unsigned long (*hash) (const char *))
2036{
2037 if (cmp)
2038 f->symbol_cmp = cmp;
2039 if (hash) {
2040 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
2041 int i;
2042
2043 f->symbol_hash = hash;
2044
2045 memcpy(tmptab, f->symtab, sizeof(tmptab));
2046 memset(f->symtab, 0, sizeof(f->symtab));
2047
2048 for (i = 0; i < HASH_BUCKETS; ++i)
2049 for (sym = tmptab[i]; sym; sym = next) {
2050 unsigned long h = hash(sym->name) % HASH_BUCKETS;
2051 next = sym->next;
2052 sym->next = f->symtab[h];
2053 f->symtab[h] = sym;
2054 }
2055 }
2056}
2057
2058#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
2059
2060static struct obj_symbol *
2061obj_add_symbol(struct obj_file *f, const char *name,
2062 unsigned long symidx, int info,
2063 int secidx, ElfW(Addr) value,
2064 unsigned long size)
2065{
2066 struct obj_symbol *sym;
2067 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2068 int n_type = ELF_ST_TYPE(info);
2069 int n_binding = ELF_ST_BIND(info);
2070
2071 for (sym = f->symtab[hash]; sym; sym = sym->next)
2072 if (f->symbol_cmp(sym->name, name) == 0) {
2073 int o_secidx = sym->secidx;
2074 int o_info = sym->info;
2075 int o_type = ELF_ST_TYPE(o_info);
2076 int o_binding = ELF_ST_BIND(o_info);
2077
2078 /* A redefinition! Is it legal? */
2079
2080 if (secidx == SHN_UNDEF)
2081 return sym;
2082 else if (o_secidx == SHN_UNDEF)
2083 goto found;
2084 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2085 /* Cope with local and global symbols of the same name
2086 in the same object file, as might have been created
2087 by ld -r. The only reason locals are now seen at this
2088 level at all is so that we can do semi-sensible things
2089 with parameters. */
2090
2091 struct obj_symbol *nsym, **p;
2092
2093 nsym = arch_new_symbol();
2094 nsym->next = sym->next;
2095 nsym->ksymidx = -1;
2096
2097 /* Excise the old (local) symbol from the hash chain. */
2098 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2099 continue;
2100 *p = sym = nsym;
2101 goto found;
2102 } else if (n_binding == STB_LOCAL) {
2103 /* Another symbol of the same name has already been defined.
2104 Just add this to the local table. */
2105 sym = arch_new_symbol();
2106 sym->next = NULL;
2107 sym->ksymidx = -1;
2108 f->local_symtab[symidx] = sym;
2109 goto found;
2110 } else if (n_binding == STB_WEAK)
2111 return sym;
2112 else if (o_binding == STB_WEAK)
2113 goto found;
2114 /* Don't unify COMMON symbols with object types the programmer
2115 doesn't expect. */
2116 else if (secidx == SHN_COMMON
2117 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2118 return sym;
2119 else if (o_secidx == SHN_COMMON
2120 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2121 goto found;
2122 else {
2123 /* Don't report an error if the symbol is coming from
2124 the kernel or some external module. */
2125 if (secidx <= SHN_HIRESERVE)
2126 bb_error_msg("%s multiply defined", name);
2127 return sym;
2128 }
2129 }
2130
2131 /* Completely new symbol. */
2132 sym = arch_new_symbol();
2133 sym->next = f->symtab[hash];
2134 f->symtab[hash] = sym;
2135 sym->ksymidx = -1;
2136
2137 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) {
2138 if (symidx >= f->local_symtab_size)
2139 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2140 name, (long) symidx, (long) f->local_symtab_size);
2141 else
2142 f->local_symtab[symidx] = sym;
2143 }
2144
2145found:
2146 sym->name = name;
2147 sym->value = value;
2148 sym->size = size;
2149 sym->secidx = secidx;
2150 sym->info = info;
2151
2152 return sym;
2153}
2154
2155static struct obj_symbol *
2156obj_find_symbol(struct obj_file *f, const char *name)
2157{
2158 struct obj_symbol *sym;
2159 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2160
2161 for (sym = f->symtab[hash]; sym; sym = sym->next)
2162 if (f->symbol_cmp(sym->name, name) == 0)
2163 return sym;
2164
2165 return NULL;
2166}
2167
2168static ElfW(Addr)
2169 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2170{
2171 if (sym) {
2172 if (sym->secidx >= SHN_LORESERVE)
2173 return sym->value;
2174
2175 return sym->value + f->sections[sym->secidx]->header.sh_addr;
2176 } else {
2177 /* As a special case, a NULL sym has value zero. */
2178 return 0;
2179 }
2180}
2181
2182static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2183{
2184 int i, n = f->header.e_shnum;
2185
2186 for (i = 0; i < n; ++i)
2187 if (strcmp(f->sections[i]->name, name) == 0)
2188 return f->sections[i];
2189
2190 return NULL;
2191}
2192
2193static int obj_load_order_prio(struct obj_section *a)
2194{
2195 unsigned long af, ac;
2196
2197 af = a->header.sh_flags;
2198
2199 ac = 0;
2200 if (a->name[0] != '.' || strlen(a->name) != 10 ||
2201 strcmp(a->name + 5, ".init"))
2202 ac |= 32;
2203 if (af & SHF_ALLOC)
2204 ac |= 16;
2205 if (!(af & SHF_WRITE))
2206 ac |= 8;
2207 if (af & SHF_EXECINSTR)
2208 ac |= 4;
2209 if (a->header.sh_type != SHT_NOBITS)
2210 ac |= 2;
2211
2212 return ac;
2213}
2214
2215static void
2216obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2217{
2218 struct obj_section **p;
2219 int prio = obj_load_order_prio(sec);
2220 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2221 if (obj_load_order_prio(*p) < prio)
2222 break;
2223 sec->load_next = *p;
2224 *p = sec;
2225}
2226
2227static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2228 const char *name,
2229 unsigned long align,
2230 unsigned long size)
2231{
2232 int newidx = f->header.e_shnum++;
2233 struct obj_section *sec;
2234
2235 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2236 f->sections[newidx] = sec = arch_new_section();
2237
2238 memset(sec, 0, sizeof(*sec));
2239 sec->header.sh_type = SHT_PROGBITS;
2240 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2241 sec->header.sh_size = size;
2242 sec->header.sh_addralign = align;
2243 sec->name = name;
2244 sec->idx = newidx;
2245 if (size)
2246 sec->contents = xmalloc(size);
2247
2248 obj_insert_section_load_order(f, sec);
2249
2250 return sec;
2251}
2252
2253static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2254 const char *name,
2255 unsigned long align,
2256 unsigned long size)
2257{
2258 int newidx = f->header.e_shnum++;
2259 struct obj_section *sec;
2260
2261 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2262 f->sections[newidx] = sec = arch_new_section();
2263
2264 memset(sec, 0, sizeof(*sec));
2265 sec->header.sh_type = SHT_PROGBITS;
2266 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2267 sec->header.sh_size = size;
2268 sec->header.sh_addralign = align;
2269 sec->name = name;
2270 sec->idx = newidx;
2271 if (size)
2272 sec->contents = xmalloc(size);
2273
2274 sec->load_next = f->load_order;
2275 f->load_order = sec;
2276 if (f->load_order_search_start == &f->load_order)
2277 f->load_order_search_start = &sec->load_next;
2278
2279 return sec;
2280}
2281
2282static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2283{
2284 unsigned long oldsize = sec->header.sh_size;
2285 if (more) {
2286 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
2287 }
2288 return sec->contents + oldsize;
2289}
2290
2291
2292/* Conditionally add the symbols from the given symbol set to the
2293 new module. */
2294
2295static int
2296add_symbols_from( struct obj_file *f,
2297 int idx, struct new_module_symbol *syms, size_t nsyms)
2298{
2299 struct new_module_symbol *s;
2300 size_t i;
2301 int used = 0;
2302#ifdef SYMBOL_PREFIX
2303 char *name_buf = 0;
2304 size_t name_alloced_size = 0;
2305#endif
2306#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
2307 int gpl;
2308
2309 gpl = obj_gpl_license(f, NULL) == 0;
2310#endif
2311 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2312 /* Only add symbols that are already marked external.
2313 If we override locals we may cause problems for
2314 argument initialization. We will also create a false
2315 dependency on the module. */
2316 struct obj_symbol *sym;
2317 char *name;
2318
2319 /* GPL licensed modules can use symbols exported with
2320 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2321 * exported names. Non-GPL modules never see any GPLONLY_
2322 * symbols so they cannot fudge it by adding the prefix on
2323 * their references.
2324 */
2325 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2326#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
2327 if (gpl)
2328 s->name += 8;
2329 else
2330#endif
2331 continue;
2332 }
2333 name = (char *)s->name;
2334
2335#ifdef SYMBOL_PREFIX
2336 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2337 kernel exports `C names', but module object files
2338 reference `linker names'). */
2339 size_t extra = sizeof SYMBOL_PREFIX;
2340 size_t name_size = strlen (name) + extra;
2341 if (name_size > name_alloced_size) {
2342 name_alloced_size = name_size * 2;
2343 name_buf = alloca (name_alloced_size);
2344 }
2345 strcpy (name_buf, SYMBOL_PREFIX);
2346 strcpy (name_buf + extra - 1, name);
2347 name = name_buf;
2348#endif /* SYMBOL_PREFIX */
2349
2350 sym = obj_find_symbol(f, name);
2351 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2352#ifdef SYMBOL_PREFIX
2353 /* Put NAME_BUF into more permanent storage. */
2354 name = xmalloc (name_size);
2355 strcpy (name, name_buf);
2356#endif
2357 sym = obj_add_symbol(f, name, -1,
2358 ELF_ST_INFO(STB_GLOBAL,
2359 STT_NOTYPE),
2360 idx, s->value, 0);
2361 /* Did our symbol just get installed? If so, mark the
2362 module as "used". */
2363 if (sym->secidx == idx)
2364 used = 1;
2365 }
2366 }
2367
2368 return used;
2369}
2370
2371static void add_kernel_symbols(struct obj_file *f)
2372{
2373 struct external_module *m;
2374 int i, nused = 0;
2375
2376 /* Add module symbols first. */
2377
2378 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
2379 if (m->nsyms
2380 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
2381 m->nsyms)) m->used = 1, ++nused;
2382
2383 n_ext_modules_used = nused;
2384
2385 /* And finally the symbols from the kernel proper. */
2386
2387 if (nksyms)
2388 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2389}
2390
2391static char *get_modinfo_value(struct obj_file *f, const char *key)
2392{
2393 struct obj_section *sec;
2394 char *p, *v, *n, *ep;
2395 size_t klen = strlen(key);
2396
2397 sec = obj_find_section(f, ".modinfo");
2398 if (sec == NULL)
2399 return NULL;
2400 p = sec->contents;
2401 ep = p + sec->header.sh_size;
2402 while (p < ep) {
2403 v = strchr(p, '=');
2404 n = strchr(p, '\0');
2405 if (v) {
2406 if (p + klen == v && strncmp(p, key, klen) == 0)
2407 return v + 1;
2408 } else {
2409 if (p + klen == n && strcmp(p, key) == 0)
2410 return n;
2411 }
2412 p = n + 1;
2413 }
2414
2415 return NULL;
2416}
2417
2418
2419/*======================================================================*/
2420/* Functions relating to module loading after 2.1.18. */
2421
2422static int
2423new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2424{
2425 while (argc > 0) {
2426 char *p, *q, *key, *sym_name;
2427 struct obj_symbol *sym;
2428 char *contents, *loc;
2429 int min, max, n;
2430
2431 p = *argv;
2432 if ((q = strchr(p, '=')) == NULL) {
2433 argc--;
2434 continue;
2435 }
2436
2437 key = alloca(q - p + 6);
2438 memcpy(key, "parm_", 5);
2439 memcpy(key + 5, p, q - p);
2440 key[q - p + 5] = 0;
2441
2442 p = get_modinfo_value(f, key);
2443 key += 5;
2444 if (p == NULL) {
2445 bb_error_msg("invalid parameter %s", key);
2446 return 0;
2447 }
2448
2449#ifdef SYMBOL_PREFIX
2450 sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);
2451 strcpy (sym_name, SYMBOL_PREFIX);
2452 strcat (sym_name, key);
2453#else
2454 sym_name = key;
2455#endif
2456 sym = obj_find_symbol(f, sym_name);
2457
2458 /* Also check that the parameter was not resolved from the kernel. */
2459 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
2460 bb_error_msg("symbol for parameter %s not found", key);
2461 return 0;
2462 }
2463
2464 if (isdigit(*p)) {
2465 min = strtoul(p, &p, 10);
2466 if (*p == '-')
2467 max = strtoul(p + 1, &p, 10);
2468 else
2469 max = min;
2470 } else
2471 min = max = 1;
2472
2473 contents = f->sections[sym->secidx]->contents;
2474 loc = contents + sym->value;
2475 n = (*++q != '\0');
2476
2477 while (1) {
2478 if ((*p == 's') || (*p == 'c')) {
2479 char *str;
2480
2481 /* Do C quoting if we begin with a ", else slurp the lot. */
2482 if (*q == '"') {
2483 char *r;
2484
2485 str = alloca(strlen(q));
2486 for (r = str, q++; *q != '"'; ++q, ++r) {
2487 if (*q == '\0') {
2488 bb_error_msg("improperly terminated string argument for %s",
2489 key);
2490 return 0;
2491 } else if (*q == '\\')
2492 switch (*++q) {
2493 case 'a':
2494 *r = '\a';
2495 break;
2496 case 'b':
2497 *r = '\b';
2498 break;
2499 case 'e':
2500 *r = '\033';
2501 break;
2502 case 'f':
2503 *r = '\f';
2504 break;
2505 case 'n':
2506 *r = '\n';
2507 break;
2508 case 'r':
2509 *r = '\r';
2510 break;
2511 case 't':
2512 *r = '\t';
2513 break;
2514
2515 case '0':
2516 case '1':
2517 case '2':
2518 case '3':
2519 case '4':
2520 case '5':
2521 case '6':
2522 case '7':
2523 {
2524 int c = *q - '0';
2525 if (q[1] >= '0' && q[1] <= '7') {
2526 c = (c * 8) + *++q - '0';
2527 if (q[1] >= '0' && q[1] <= '7')
2528 c = (c * 8) + *++q - '0';
2529 }
2530 *r = c;
2531 }
2532 break;
2533
2534 default:
2535 *r = *q;
2536 break;
2537 } else
2538 *r = *q;
2539 }
2540 *r = '\0';
2541 ++q;
2542 } else {
2543 char *r;
2544
2545 /* In this case, the string is not quoted. We will break
2546 it using the coma (like for ints). If the user wants to
2547 include comas in a string, he just has to quote it */
2548
2549 /* Search the next coma */
2550 r = strchr(q, ',');
2551
2552 /* Found ? */
2553 if (r != (char *) NULL) {
2554 /* Recopy the current field */
2555 str = alloca(r - q + 1);
2556 memcpy(str, q, r - q);
2557
2558 /* I don't know if it is useful, as the previous case
2559 doesn't nul terminate the string ??? */
2560 str[r - q] = '\0';
2561
2562 /* Keep next fields */
2563 q = r;
2564 } else {
2565 /* last string */
2566 str = q;
2567 q = "";
2568 }
2569 }
2570
2571 if (*p == 's') {
2572 /* Normal string */
2573 obj_string_patch(f, sym->secidx, loc - contents, str);
2574 loc += tgt_sizeof_char_p;
2575 } else {
2576 /* Array of chars (in fact, matrix !) */
2577 unsigned long charssize; /* size of each member */
2578
2579 /* Get the size of each member */
2580 /* Probably we should do that outside the loop ? */
2581 if (!isdigit(*(p + 1))) {
2582 bb_error_msg("parameter type 'c' for %s must be followed by"
2583 " the maximum size", key);
2584 return 0;
2585 }
2586 charssize = strtoul(p + 1, (char **) NULL, 10);
2587
2588 /* Check length */
2589 if (strlen(str) >= charssize) {
2590 bb_error_msg("string too long for %s (max %ld)", key,
2591 charssize - 1);
2592 return 0;
2593 }
2594
2595 /* Copy to location */
2596 strcpy((char *) loc, str);
2597 loc += charssize;
2598 }
2599 } else {
2600 long v = strtoul(q, &q, 0);
2601 switch (*p) {
2602 case 'b':
2603 *loc++ = v;
2604 break;
2605 case 'h':
2606 *(short *) loc = v;
2607 loc += tgt_sizeof_short;
2608 break;
2609 case 'i':
2610 *(int *) loc = v;
2611 loc += tgt_sizeof_int;
2612 break;
2613 case 'l':
2614 *(long *) loc = v;
2615 loc += tgt_sizeof_long;
2616 break;
2617
2618 default:
2619 bb_error_msg("unknown parameter type '%c' for %s", *p, key);
2620 return 0;
2621 }
2622 }
2623
2624retry_end_of_value:
2625 switch (*q) {
2626 case '\0':
2627 goto end_of_arg;
2628
2629 case ' ':
2630 case '\t':
2631 case '\n':
2632 case '\r':
2633 ++q;
2634 goto retry_end_of_value;
2635
2636 case ',':
2637 if (++n > max) {
2638 bb_error_msg("too many values for %s (max %d)", key, max);
2639 return 0;
2640 }
2641 ++q;
2642 break;
2643
2644 default:
2645 bb_error_msg("invalid argument syntax for %s", key);
2646 return 0;
2647 }
2648 }
2649
2650end_of_arg:
2651 if (n < min) {
2652 bb_error_msg("too few values for %s (min %d)", key, min);
2653 return 0;
2654 }
2655
2656 argc--, argv++;
2657 }
2658
2659 return 1;
2660}
2661
2662#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
2663static int new_is_module_checksummed(struct obj_file *f)
2664{
2665 const char *p = get_modinfo_value(f, "using_checksums");
2666 if (p)
2667 return atoi(p);
2668 else
2669 return 0;
2670}
2671
2672/* Get the module's kernel version in the canonical integer form. */
2673
2674static int
2675new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2676{
2677 char *p, *q;
2678 int a, b, c;
2679
2680 p = get_modinfo_value(f, "kernel_version");
2681 if (p == NULL)
2682 return -1;
2683 safe_strncpy(str, p, STRVERSIONLEN);
2684
2685 a = strtoul(p, &p, 10);
2686 if (*p != '.')
2687 return -1;
2688 b = strtoul(p + 1, &p, 10);
2689 if (*p != '.')
2690 return -1;
2691 c = strtoul(p + 1, &q, 10);
2692 if (p + 1 == q)
2693 return -1;
2694
2695 return a << 16 | b << 8 | c;
2696}
2697
2698#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
2699
2700
2701/* Fetch the loaded modules, and all currently exported symbols. */
2702
2703static int new_get_kernel_symbols(void)
2704{
2705 char *module_names, *mn;
2706 struct external_module *modules, *m;
2707 struct new_module_symbol *syms, *s;
2708 size_t ret, bufsize, nmod, nsyms, i, j;
2709
2710 /* Collect the loaded modules. */
2711
2712 module_names = xmalloc(bufsize = 256);
2713retry_modules_load:
2714 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2715 if (errno == ENOSPC && bufsize < ret) {
2716 module_names = xrealloc(module_names, bufsize = ret);
2717 goto retry_modules_load;
2718 }
2719 bb_perror_msg("QM_MODULES");
2720 return 0;
2721 }
2722
2723 n_ext_modules = nmod = ret;
2724
2725 /* Collect the modules' symbols. */
2726
2727 if (nmod){
2728 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2729 memset(modules, 0, nmod * sizeof(*modules));
2730 for (i = 0, mn = module_names, m = modules;
2731 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2732 struct new_module_info info;
2733
2734 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2735 if (errno == ENOENT) {
2736 /* The module was removed out from underneath us. */
2737 continue;
2738 }
2739 bb_perror_msg("query_module: QM_INFO: %s", mn);
2740 return 0;
2741 }
2742
2743 syms = xmalloc(bufsize = 1024);
2744retry_mod_sym_load:
2745 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2746 switch (errno) {
2747 case ENOSPC:
2748 syms = xrealloc(syms, bufsize = ret);
2749 goto retry_mod_sym_load;
2750 case ENOENT:
2751 /* The module was removed out from underneath us. */
2752 continue;
2753 default:
2754 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn);
2755 return 0;
2756 }
2757 }
2758 nsyms = ret;
2759
2760 m->name = mn;
2761 m->addr = info.addr;
2762 m->nsyms = nsyms;
2763 m->syms = syms;
2764
2765 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2766 s->name += (unsigned long) syms;
2767 }
2768 }
2769 }
2770
2771 /* Collect the kernel's symbols. */
2772
2773 syms = xmalloc(bufsize = 16 * 1024);
2774retry_kern_sym_load:
2775 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2776 if (errno == ENOSPC && bufsize < ret) {
2777 syms = xrealloc(syms, bufsize = ret);
2778 goto retry_kern_sym_load;
2779 }
2780 bb_perror_msg("kernel: QM_SYMBOLS");
2781 return 0;
2782 }
2783 nksyms = nsyms = ret;
2784 ksyms = syms;
2785
2786 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2787 s->name += (unsigned long) syms;
2788 }
2789 return 1;
2790}
2791
2792
2793/* Return the kernel symbol checksum version, or zero if not used. */
2794
2795static int new_is_kernel_checksummed(void)
2796{
2797 struct new_module_symbol *s;
2798 size_t i;
2799
2800 /* Using_Versions is not the first symbol, but it should be in there. */
2801
2802 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2803 if (strcmp((char *) s->name, "Using_Versions") == 0)
2804 return s->value;
2805
2806 return 0;
2807}
2808
2809
2810static int new_create_this_module(struct obj_file *f, const char *m_name)
2811{
2812 struct obj_section *sec;
2813
2814 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2815 sizeof(struct new_module));
2816 memset(sec->contents, 0, sizeof(struct new_module));
2817
2818 obj_add_symbol(f, SPFX "__this_module", -1,
2819 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2820 sizeof(struct new_module));
2821
2822 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2823 m_name);
2824
2825 return 1;
2826}
2827
2828#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2829/* add an entry to the __ksymtab section, creating it if necessary */
2830static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2831{
2832 struct obj_section *sec;
2833 ElfW(Addr) ofs;
2834
2835 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2836 * If __ksymtab is defined but not marked alloc, x out the first character
2837 * (no obj_delete routine) and create a new __ksymtab with the correct
2838 * characteristics.
2839 */
2840 sec = obj_find_section(f, "__ksymtab");
2841 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2842 *((char *)(sec->name)) = 'x'; /* override const */
2843 sec = NULL;
2844 }
2845 if (!sec)
2846 sec = obj_create_alloced_section(f, "__ksymtab",
2847 tgt_sizeof_void_p, 0);
2848 if (!sec)
2849 return;
2850 sec->header.sh_flags |= SHF_ALLOC;
2851 sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might
2852 be byte-aligned */
2853 ofs = sec->header.sh_size;
2854 obj_symbol_patch(f, sec->idx, ofs, sym);
2855 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2856 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2857}
2858#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
2859
2860static int new_create_module_ksymtab(struct obj_file *f)
2861{
2862 struct obj_section *sec;
2863 int i;
2864
2865 /* We must always add the module references. */
2866
2867 if (n_ext_modules_used) {
2868 struct new_module_ref *dep;
2869 struct obj_symbol *tm;
2870
2871 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2872 (sizeof(struct new_module_ref)
2873 * n_ext_modules_used));
2874 if (!sec)
2875 return 0;
2876
2877 tm = obj_find_symbol(f, SPFX "__this_module");
2878 dep = (struct new_module_ref *) sec->contents;
2879 for (i = 0; i < n_ext_modules; ++i)
2880 if (ext_modules[i].used) {
2881 dep->dep = ext_modules[i].addr;
2882 obj_symbol_patch(f, sec->idx,
2883 (char *) &dep->ref - sec->contents, tm);
2884 dep->next_ref = 0;
2885 ++dep;
2886 }
2887 }
2888
2889 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2890 size_t nsyms;
2891 int *loaded;
2892
2893 sec =
2894 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2895 0);
2896
2897 /* We don't want to export symbols residing in sections that
2898 aren't loaded. There are a number of these created so that
2899 we make sure certain module options don't appear twice. */
2900
2901 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2902 while (--i >= 0)
2903 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2904
2905 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2906 struct obj_symbol *sym;
2907 for (sym = f->symtab[i]; sym; sym = sym->next)
2908 if (ELF_ST_BIND(sym->info) != STB_LOCAL
2909 && sym->secidx <= SHN_HIRESERVE
2910 && (sym->secidx >= SHN_LORESERVE
2911 || loaded[sym->secidx])) {
2912 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2913
2914 obj_symbol_patch(f, sec->idx, ofs, sym);
2915 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2916 sym->name);
2917
2918 nsyms++;
2919 }
2920 }
2921
2922 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2923 }
2924
2925 return 1;
2926}
2927
2928
2929static int
2930new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2931{
2932 struct new_module *module;
2933 struct obj_section *sec;
2934 void *image;
2935 int ret;
2936 tgt_long m_addr;
2937
2938 sec = obj_find_section(f, ".this");
2939 if (!sec || !sec->contents) {
2940 bb_perror_msg_and_die("corrupt module %s?",m_name);
2941 }
2942 module = (struct new_module *) sec->contents;
2943 m_addr = sec->header.sh_addr;
2944
2945 module->size_of_struct = sizeof(*module);
2946 module->size = m_size;
2947 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2948
2949 sec = obj_find_section(f, "__ksymtab");
2950 if (sec && sec->header.sh_size) {
2951 module->syms = sec->header.sh_addr;
2952 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2953 }
2954
2955 if (n_ext_modules_used) {
2956 sec = obj_find_section(f, ".kmodtab");
2957 module->deps = sec->header.sh_addr;
2958 module->ndeps = n_ext_modules_used;
2959 }
2960
2961 module->init =
2962 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2963 module->cleanup =
2964 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
2965
2966 sec = obj_find_section(f, "__ex_table");
2967 if (sec) {
2968 module->ex_table_start = sec->header.sh_addr;
2969 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2970 }
2971
2972 sec = obj_find_section(f, ".text.init");
2973 if (sec) {
2974 module->runsize = sec->header.sh_addr - m_addr;
2975 }
2976 sec = obj_find_section(f, ".data.init");
2977 if (sec) {
2978 if (!module->runsize ||
2979 module->runsize > sec->header.sh_addr - m_addr)
2980 module->runsize = sec->header.sh_addr - m_addr;
2981 }
2982 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2983 if (sec && sec->header.sh_size) {
2984 module->archdata_start = (void*)sec->header.sh_addr;
2985 module->archdata_end = module->archdata_start + sec->header.sh_size;
2986 }
2987 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2988 if (sec && sec->header.sh_size) {
2989 module->kallsyms_start = (void*)sec->header.sh_addr;
2990 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2991 }
2992
2993 /* Whew! All of the initialization is complete. Collect the final
2994 module image and give it to the kernel. */
2995
2996 image = xmalloc(m_size);
2997 obj_create_image(f, image);
2998
2999 ret = init_module(m_name, (struct new_module *) image);
3000 if (ret)
3001 bb_perror_msg("init_module: %s", m_name);
3002
3003 free(image);
3004
3005 return ret == 0;
3006}
3007
3008
3009/*======================================================================*/
3010
3011static int
3012obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3013 const char *string)
3014{
3015 struct obj_string_patch *p;
3016 struct obj_section *strsec;
3017 size_t len = strlen(string) + 1;
3018 char *loc;
3019
3020 p = xmalloc(sizeof(*p));
3021 p->next = f->string_patches;
3022 p->reloc_secidx = secidx;
3023 p->reloc_offset = offset;
3024 f->string_patches = p;
3025
3026 strsec = obj_find_section(f, ".kstrtab");
3027 if (strsec == NULL) {
3028 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
3029 p->string_offset = 0;
3030 loc = strsec->contents;
3031 } else {
3032 p->string_offset = strsec->header.sh_size;
3033 loc = obj_extend_section(strsec, len);
3034 }
3035 memcpy(loc, string, len);
3036
3037 return 1;
3038}
3039
3040static int
3041obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3042 struct obj_symbol *sym)
3043{
3044 struct obj_symbol_patch *p;
3045
3046 p = xmalloc(sizeof(*p));
3047 p->next = f->symbol_patches;
3048 p->reloc_secidx = secidx;
3049 p->reloc_offset = offset;
3050 p->sym = sym;
3051 f->symbol_patches = p;
3052
3053 return 1;
3054}
3055
3056static int obj_check_undefineds(struct obj_file *f)
3057{
3058 unsigned long i;
3059 int ret = 1;
3060
3061 for (i = 0; i < HASH_BUCKETS; ++i) {
3062 struct obj_symbol *sym;
3063 for (sym = f->symtab[i]; sym; sym = sym->next)
3064 if (sym->secidx == SHN_UNDEF) {
3065 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
3066 sym->secidx = SHN_ABS;
3067 sym->value = 0;
3068 } else {
3069 if (!flag_quiet) {
3070 bb_error_msg("unresolved symbol %s", sym->name);
3071 }
3072 ret = 0;
3073 }
3074 }
3075 }
3076
3077 return ret;
3078}
3079
3080static void obj_allocate_commons(struct obj_file *f)
3081{
3082 struct common_entry {
3083 struct common_entry *next;
3084 struct obj_symbol *sym;
3085 } *common_head = NULL;
3086
3087 unsigned long i;
3088
3089 for (i = 0; i < HASH_BUCKETS; ++i) {
3090 struct obj_symbol *sym;
3091 for (sym = f->symtab[i]; sym; sym = sym->next)
3092 if (sym->secidx == SHN_COMMON) {
3093 /* Collect all COMMON symbols and sort them by size so as to
3094 minimize space wasted by alignment requirements. */
3095 {
3096 struct common_entry **p, *n;
3097 for (p = &common_head; *p; p = &(*p)->next)
3098 if (sym->size <= (*p)->sym->size)
3099 break;
3100
3101 n = alloca(sizeof(*n));
3102 n->next = *p;
3103 n->sym = sym;
3104 *p = n;
3105 }
3106 }
3107 }
3108
3109 for (i = 1; i < f->local_symtab_size; ++i) {
3110 struct obj_symbol *sym = f->local_symtab[i];
3111 if (sym && sym->secidx == SHN_COMMON) {
3112 struct common_entry **p, *n;
3113 for (p = &common_head; *p; p = &(*p)->next)
3114 if (sym == (*p)->sym)
3115 break;
3116 else if (sym->size < (*p)->sym->size) {
3117 n = alloca(sizeof(*n));
3118 n->next = *p;
3119 n->sym = sym;
3120 *p = n;
3121 break;
3122 }
3123 }
3124 }
3125
3126 if (common_head) {
3127 /* Find the bss section. */
3128 for (i = 0; i < f->header.e_shnum; ++i)
3129 if (f->sections[i]->header.sh_type == SHT_NOBITS)
3130 break;
3131
3132 /* If for some reason there hadn't been one, create one. */
3133 if (i == f->header.e_shnum) {
3134 struct obj_section *sec;
3135
3136 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
3137 f->sections[i] = sec = arch_new_section();
3138 f->header.e_shnum = i + 1;
3139
3140 memset(sec, 0, sizeof(*sec));
3141 sec->header.sh_type = SHT_PROGBITS;
3142 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
3143 sec->name = ".bss";
3144 sec->idx = i;
3145 }
3146
3147 /* Allocate the COMMONS. */
3148 {
3149 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
3150 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
3151 struct common_entry *c;
3152
3153 for (c = common_head; c; c = c->next) {
3154 ElfW(Addr) align = c->sym->value;
3155
3156 if (align > max_align)
3157 max_align = align;
3158 if (bss_size & (align - 1))
3159 bss_size = (bss_size | (align - 1)) + 1;
3160
3161 c->sym->secidx = i;
3162 c->sym->value = bss_size;
3163
3164 bss_size += c->sym->size;
3165 }
3166
3167 f->sections[i]->header.sh_size = bss_size;
3168 f->sections[i]->header.sh_addralign = max_align;
3169 }
3170 }
3171
3172 /* For the sake of patch relocation and parameter initialization,
3173 allocate zeroed data for NOBITS sections now. Note that after
3174 this we cannot assume NOBITS are really empty. */
3175 for (i = 0; i < f->header.e_shnum; ++i) {
3176 struct obj_section *s = f->sections[i];
3177 if (s->header.sh_type == SHT_NOBITS) {
3178 if (s->header.sh_size != 0)
3179 s->contents = memset(xmalloc(s->header.sh_size),
3180 0, s->header.sh_size);
3181 else
3182 s->contents = NULL;
3183
3184 s->header.sh_type = SHT_PROGBITS;
3185 }
3186 }
3187}
3188
3189static unsigned long obj_load_size(struct obj_file *f)
3190{
3191 unsigned long dot = 0;
3192 struct obj_section *sec;
3193
3194 /* Finalize the positions of the sections relative to one another. */
3195
3196 for (sec = f->load_order; sec; sec = sec->load_next) {
3197 ElfW(Addr) align;
3198
3199 align = sec->header.sh_addralign;
3200 if (align && (dot & (align - 1)))
3201 dot = (dot | (align - 1)) + 1;
3202
3203 sec->header.sh_addr = dot;
3204 dot += sec->header.sh_size;
3205 }
3206
3207 return dot;
3208}
3209
3210static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3211{
3212 int i, n = f->header.e_shnum;
3213 int ret = 1;
3214
3215 /* Finalize the addresses of the sections. */
3216
3217 f->baseaddr = base;
3218 for (i = 0; i < n; ++i)
3219 f->sections[i]->header.sh_addr += base;
3220
3221 /* And iterate over all of the relocations. */
3222
3223 for (i = 0; i < n; ++i) {
3224 struct obj_section *relsec, *symsec, *targsec, *strsec;
3225 ElfW(RelM) * rel, *relend;
3226 ElfW(Sym) * symtab;
3227 const char *strtab;
3228
3229 relsec = f->sections[i];
3230 if (relsec->header.sh_type != SHT_RELM)
3231 continue;
3232
3233 symsec = f->sections[relsec->header.sh_link];
3234 targsec = f->sections[relsec->header.sh_info];
3235 strsec = f->sections[symsec->header.sh_link];
3236
3237 rel = (ElfW(RelM) *) relsec->contents;
3238 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3239 symtab = (ElfW(Sym) *) symsec->contents;
3240 strtab = (const char *) strsec->contents;
3241
3242 for (; rel < relend; ++rel) {
3243 ElfW(Addr) value = 0;
3244 struct obj_symbol *intsym = NULL;
3245 unsigned long symndx;
3246 ElfW(Sym) * extsym = 0;
3247 const char *errmsg;
3248
3249 /* Attempt to find a value to use for this relocation. */
3250
3251 symndx = ELF_R_SYM(rel->r_info);
3252 if (symndx) {
3253 /* Note we've already checked for undefined symbols. */
3254
3255 extsym = &symtab[symndx];
3256 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3257 /* Local symbols we look up in the local table to be sure
3258 we get the one that is really intended. */
3259 intsym = f->local_symtab[symndx];
3260 } else {
3261 /* Others we look up in the hash table. */
3262 const char *name;
3263 if (extsym->st_name)
3264 name = strtab + extsym->st_name;
3265 else
3266 name = f->sections[extsym->st_shndx]->name;
3267 intsym = obj_find_symbol(f, name);
3268 }
3269
3270 value = obj_symbol_final_value(f, intsym);
3271 intsym->referenced = 1;
3272 }
3273#if SHT_RELM == SHT_RELA
3274#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3275 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
3276 if (!extsym || !extsym->st_name ||
3277 ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
3278#endif
3279 value += rel->r_addend;
3280#endif
3281
3282 /* Do it! */
3283 switch (arch_apply_relocation
3284 (f, targsec, symsec, intsym, rel, value)) {
3285 case obj_reloc_ok:
3286 break;
3287
3288 case obj_reloc_overflow:
3289 errmsg = "Relocation overflow";
3290 goto bad_reloc;
3291 case obj_reloc_dangerous:
3292 errmsg = "Dangerous relocation";
3293 goto bad_reloc;
3294 case obj_reloc_unhandled:
3295 errmsg = "Unhandled relocation";
3296bad_reloc:
3297 if (extsym) {
3298 bb_error_msg("%s of type %ld for %s", errmsg,
3299 (long) ELF_R_TYPE(rel->r_info),
3300 strtab + extsym->st_name);
3301 } else {
3302 bb_error_msg("%s of type %ld", errmsg,
3303 (long) ELF_R_TYPE(rel->r_info));
3304 }
3305 ret = 0;
3306 break;
3307 }
3308 }
3309 }
3310
3311 /* Finally, take care of the patches. */
3312
3313 if (f->string_patches) {
3314 struct obj_string_patch *p;
3315 struct obj_section *strsec;
3316 ElfW(Addr) strsec_base;
3317 strsec = obj_find_section(f, ".kstrtab");
3318 strsec_base = strsec->header.sh_addr;
3319
3320 for (p = f->string_patches; p; p = p->next) {
3321 struct obj_section *targsec = f->sections[p->reloc_secidx];
3322 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3323 = strsec_base + p->string_offset;
3324 }
3325 }
3326
3327 if (f->symbol_patches) {
3328 struct obj_symbol_patch *p;
3329
3330 for (p = f->symbol_patches; p; p = p->next) {
3331 struct obj_section *targsec = f->sections[p->reloc_secidx];
3332 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3333 = obj_symbol_final_value(f, p->sym);
3334 }
3335 }
3336
3337 return ret;
3338}
3339
3340static int obj_create_image(struct obj_file *f, char *image)
3341{
3342 struct obj_section *sec;
3343 ElfW(Addr) base = f->baseaddr;
3344
3345 for (sec = f->load_order; sec; sec = sec->load_next) {
3346 char *secimg;
3347
3348 if (sec->contents == 0 || sec->header.sh_size == 0)
3349 continue;
3350
3351 secimg = image + (sec->header.sh_addr - base);
3352
3353 /* Note that we allocated data for NOBITS sections earlier. */
3354 memcpy(secimg, sec->contents, sec->header.sh_size);
3355 }
3356
3357 return 1;
3358}
3359
3360/*======================================================================*/
3361
3362static struct obj_file *obj_load(FILE * fp, int loadprogbits)
3363{
3364 struct obj_file *f;
3365 ElfW(Shdr) * section_headers;
3366 int shnum, i;
3367 char *shstrtab;
3368
3369 /* Read the file header. */
3370
3371 f = arch_new_file();
3372 memset(f, 0, sizeof(*f));
3373 f->symbol_cmp = strcmp;
3374 f->symbol_hash = obj_elf_hash;
3375 f->load_order_search_start = &f->load_order;
3376
3377 fseek(fp, 0, SEEK_SET);
3378 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
3379 bb_perror_msg("error reading ELF header");
3380 return NULL;
3381 }
3382
3383 if (f->header.e_ident[EI_MAG0] != ELFMAG0
3384 || f->header.e_ident[EI_MAG1] != ELFMAG1
3385 || f->header.e_ident[EI_MAG2] != ELFMAG2
3386 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
3387 bb_error_msg("not an ELF file");
3388 return NULL;
3389 }
3390 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3391 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN
3392 ? ELFDATA2MSB : ELFDATA2LSB)
3393 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3394 || !MATCH_MACHINE(f->header.e_machine)) {
3395 bb_error_msg("ELF file not for this architecture");
3396 return NULL;
3397 }
3398 if (f->header.e_type != ET_REL) {
3399 bb_error_msg("ELF file not a relocatable object");
3400 return NULL;
3401 }
3402
3403 /* Read the section headers. */
3404
3405 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3406 bb_error_msg("section header size mismatch: %lu != %lu",
3407 (unsigned long) f->header.e_shentsize,
3408 (unsigned long) sizeof(ElfW(Shdr)));
3409 return NULL;
3410 }
3411
3412 shnum = f->header.e_shnum;
3413 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3414 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3415
3416 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3417 fseek(fp, f->header.e_shoff, SEEK_SET);
3418 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
3419 bb_perror_msg("error reading ELF section headers");
3420 return NULL;
3421 }
3422
3423 /* Read the section data. */
3424
3425 for (i = 0; i < shnum; ++i) {
3426 struct obj_section *sec;
3427
3428 f->sections[i] = sec = arch_new_section();
3429 memset(sec, 0, sizeof(*sec));
3430
3431 sec->header = section_headers[i];
3432 sec->idx = i;
3433
3434 if(sec->header.sh_size) switch (sec->header.sh_type) {
3435 case SHT_NULL:
3436 case SHT_NOTE:
3437 case SHT_NOBITS:
3438 /* ignore */
3439 break;
3440
3441 case SHT_PROGBITS:
3442#if LOADBITS
3443 if (!loadprogbits) {
3444 sec->contents = NULL;
3445 break;
3446 }
3447#endif
3448 case SHT_SYMTAB:
3449 case SHT_STRTAB:
3450 case SHT_RELM:
3451 if (sec->header.sh_size > 0) {
3452 sec->contents = xmalloc(sec->header.sh_size);
3453 fseek(fp, sec->header.sh_offset, SEEK_SET);
3454 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3455 bb_perror_msg("error reading ELF section data");
3456 return NULL;
3457 }
3458 } else {
3459 sec->contents = NULL;
3460 }
3461 break;
3462
3463#if SHT_RELM == SHT_REL
3464 case SHT_RELA:
3465 bb_error_msg("RELA relocations not supported on this architecture");
3466 return NULL;
3467#else
3468 case SHT_REL:
3469 bb_error_msg("REL relocations not supported on this architecture");
3470 return NULL;
3471#endif
3472
3473 default:
3474 if (sec->header.sh_type >= SHT_LOPROC) {
3475 /* Assume processor specific section types are debug
3476 info and can safely be ignored. If this is ever not
3477 the case (Hello MIPS?), don't put ifdefs here but
3478 create an arch_load_proc_section(). */
3479 break;
3480 }
3481
3482 bb_error_msg("can't handle sections of type %ld",
3483 (long) sec->header.sh_type);
3484 return NULL;
3485 }
3486 }
3487
3488 /* Do what sort of interpretation as needed by each section. */
3489
3490 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3491
3492 for (i = 0; i < shnum; ++i) {
3493 struct obj_section *sec = f->sections[i];
3494 sec->name = shstrtab + sec->header.sh_name;
3495 }
3496
3497 for (i = 0; i < shnum; ++i) {
3498 struct obj_section *sec = f->sections[i];
3499
3500 /* .modinfo should be contents only but gcc has no attribute for that.
3501 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3502 */
3503 if (strcmp(sec->name, ".modinfo") == 0)
3504 sec->header.sh_flags &= ~SHF_ALLOC;
3505
3506 if (sec->header.sh_flags & SHF_ALLOC)
3507 obj_insert_section_load_order(f, sec);
3508
3509 switch (sec->header.sh_type) {
3510 case SHT_SYMTAB:
3511 {
3512 unsigned long nsym, j;
3513 char *strtab;
3514 ElfW(Sym) * sym;
3515
3516 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3517 bb_error_msg("symbol size mismatch: %lu != %lu",
3518 (unsigned long) sec->header.sh_entsize,
3519 (unsigned long) sizeof(ElfW(Sym)));
3520 return NULL;
3521 }
3522
3523 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3524 strtab = f->sections[sec->header.sh_link]->contents;
3525 sym = (ElfW(Sym) *) sec->contents;
3526
3527 /* Allocate space for a table of local symbols. */
3528 j = f->local_symtab_size = sec->header.sh_info;
3529 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
3530
3531 /* Insert all symbols into the hash table. */
3532 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3533 ElfW(Addr) val = sym->st_value;
3534 const char *name;
3535 if (sym->st_name)
3536 name = strtab + sym->st_name;
3537 else if (sym->st_shndx < shnum)
3538 name = f->sections[sym->st_shndx]->name;
3539 else
3540 continue;
3541
3542#if defined(__SH5__)
3543 /*
3544 * For sh64 it is possible that the target of a branch
3545 * requires a mode switch (32 to 16 and back again).
3546 *
3547 * This is implied by the lsb being set in the target
3548 * address for SHmedia mode and clear for SHcompact.
3549 */
3550 val |= sym->st_other & 4;
3551#endif
3552
3553 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3554 val, sym->st_size);
3555 }
3556 }
3557 break;
3558
3559 case SHT_RELM:
3560 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3561 bb_error_msg("relocation entry size mismatch: %lu != %lu",
3562 (unsigned long) sec->header.sh_entsize,
3563 (unsigned long) sizeof(ElfW(RelM)));
3564 return NULL;
3565 }
3566 break;
3567 /* XXX Relocation code from modutils-2.3.19 is not here.
3568 * Why? That's about 20 lines of code from obj/obj_load.c,
3569 * which gets done in a second pass through the sections.
3570 * This BusyBox insmod does similar work in obj_relocate(). */
3571 }
3572 }
3573
3574 return f;
3575}
3576
3577#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
3578/*
3579 * load the unloaded sections directly into the memory allocated by
3580 * kernel for the module
3581 */
3582
3583static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase)
3584{
3585 ElfW(Addr) base = f->baseaddr;
3586 struct obj_section* sec;
3587
3588 for (sec = f->load_order; sec; sec = sec->load_next) {
3589
3590 /* section already loaded? */
3591 if (sec->contents != NULL)
3592 continue;
3593
3594 if (sec->header.sh_size == 0)
3595 continue;
3596
3597 sec->contents = imagebase + (sec->header.sh_addr - base);
3598 fseek(fp, sec->header.sh_offset, SEEK_SET);
3599 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3600 bb_error_msg("error reading ELF section data: %s\n", strerror(errno));
3601 return 0;
3602 }
3603
3604 }
3605 return 1;
3606}
3607#endif
3608
3609static void hide_special_symbols(struct obj_file *f)
3610{
3611 static const char *const specials[] = {
3612 SPFX "cleanup_module",
3613 SPFX "init_module",
3614 SPFX "kernel_version",
3615 NULL
3616 };
3617
3618 struct obj_symbol *sym;
3619 const char *const *p;
3620
3621 for (p = specials; *p; ++p)
3622 if ((sym = obj_find_symbol(f, *p)) != NULL)
3623 sym->info =
3624 ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3625}
3626
3627
3628#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
3629static int obj_gpl_license(struct obj_file *f, const char **license)
3630{
3631 struct obj_section *sec;
3632 /* This list must match *exactly* the list of allowable licenses in
3633 * linux/include/linux/module.h. Checking for leading "GPL" will not
3634 * work, somebody will use "GPL sucks, this is proprietary".
3635 */
3636 static const char * const gpl_licenses[] = {
3637 "GPL",
3638 "GPL v2",
3639 "GPL and additional rights",
3640 "Dual BSD/GPL",
3641 "Dual MPL/GPL",
3642 };
3643
3644 if ((sec = obj_find_section(f, ".modinfo"))) {
3645 const char *value, *ptr, *endptr;
3646 ptr = sec->contents;
3647 endptr = ptr + sec->header.sh_size;
3648 while (ptr < endptr) {
3649 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) {
3650 int i;
3651 if (license)
3652 *license = value+1;
3653 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3654 if (strcmp(value+1, gpl_licenses[i]) == 0)
3655 return(0);
3656 }
3657 return(2);
3658 }
3659 if (strchr(ptr, '\0'))
3660 ptr = strchr(ptr, '\0') + 1;
3661 else
3662 ptr = endptr;
3663 }
3664 }
3665 return(1);
3666}
3667
3668#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3669#define TAINT_PROPRIETORY_MODULE (1<<0)
3670#define TAINT_FORCED_MODULE (1<<1)
3671#define TAINT_UNSAFE_SMP (1<<2)
3672#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3673
3674static void set_tainted(struct obj_file *f, int fd, char *m_name,
3675 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3676{
3677 char buf[80];
3678 int oldval;
3679 static int first = 1;
3680 if (fd < 0 && !kernel_has_tainted)
3681 return; /* New modutils on old kernel */
3682 printf("Warning: loading %s will taint the kernel: %s%s\n",
3683 m_name, text1, text2);
3684 if (first) {
3685 printf(" See %s for information about tainted modules\n", TAINT_URL);
3686 first = 0;
3687 }
3688 if (fd >= 0) {
3689 read(fd, buf, sizeof(buf)-1);
3690 buf[sizeof(buf)-1] = '\0';
3691 oldval = strtoul(buf, NULL, 10);
3692 sprintf(buf, "%d\n", oldval | taint);
3693 write(fd, buf, strlen(buf));
3694 }
3695}
3696
3697/* Check if loading this module will taint the kernel. */
3698static void check_tainted_module(struct obj_file *f, char *m_name)
3699{
3700 static const char tainted_file[] = TAINT_FILENAME;
3701 int fd, kernel_has_tainted;
3702 const char *ptr;
3703
3704 kernel_has_tainted = 1;
3705 if ((fd = open(tainted_file, O_RDWR)) < 0) {
3706 if (errno == ENOENT)
3707 kernel_has_tainted = 0;
3708 else if (errno == EACCES)
3709 kernel_has_tainted = 1;
3710 else {
3711 perror(tainted_file);
3712 kernel_has_tainted = 0;
3713 }
3714 }
3715
3716 switch (obj_gpl_license(f, &ptr)) {
3717 case 0:
3718 break;
3719 case 1:
3720 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3721 break;
3722 case 2:
3723 /* The module has a non-GPL license so we pretend that the
3724 * kernel always has a taint flag to get a warning even on
3725 * kernels without the proc flag.
3726 */
3727 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3728 break;
3729 default:
3730 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3731 break;
3732 }
3733
3734 if (flag_force_load)
3735 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3736
3737 if (fd >= 0)
3738 close(fd);
3739}
3740#else /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
3741#define check_tainted_module(x, y) do { } while(0);
3742#endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
3743
3744#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3745/* add module source, timestamp, kernel version and a symbol for the
3746 * start of some sections. this info is used by ksymoops to do better
3747 * debugging.
3748 */
3749static int
3750get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3751{
3752#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
3753 return new_get_module_version(f, str);
3754#else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
3755 strncpy(str, "???", sizeof(str));
3756 return -1;
3757#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
3758}
3759
3760/* add module source, timestamp, kernel version and a symbol for the
3761 * start of some sections. this info is used by ksymoops to do better
3762 * debugging.
3763 */
3764static void
3765add_ksymoops_symbols(struct obj_file *f, const char *filename,
3766 const char *m_name)
3767{
3768 static const char symprefix[] = "__insmod_";
3769 struct obj_section *sec;
3770 struct obj_symbol *sym;
3771 char *name, *absolute_filename;
3772 char str[STRVERSIONLEN], real[PATH_MAX];
3773 int i, l, lm_name, lfilename, use_ksymtab, version;
3774 struct stat statbuf;
3775
3776 static const char *section_names[] = {
3777 ".text",
3778 ".rodata",
3779 ".data",
3780 ".bss",
3781 ".sbss"
3782 };
3783
3784 if (realpath(filename, real)) {
3785 absolute_filename = bb_xstrdup(real);
3786 }
3787 else {
3788 int save_errno = errno;
3789 bb_error_msg("cannot get realpath for %s", filename);
3790 errno = save_errno;
3791 perror("");
3792 absolute_filename = bb_xstrdup(filename);
3793 }
3794
3795 lm_name = strlen(m_name);
3796 lfilename = strlen(absolute_filename);
3797
3798 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3799 * are not to be exported. otherwise leave ksymtab alone for now, the
3800 * "export all symbols" compatibility code will export these symbols later.
3801 */
3802 use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export;
3803
3804 if ((sec = obj_find_section(f, ".this"))) {
3805 /* tag the module header with the object name, last modified
3806 * timestamp and module version. worst case for module version
3807 * is 0xffffff, decimal 16777215. putting all three fields in
3808 * one symbol is less readable but saves kernel space.
3809 */
3810 l = sizeof(symprefix)+ /* "__insmod_" */
3811 lm_name+ /* module name */
3812 2+ /* "_O" */
3813 lfilename+ /* object filename */
3814 2+ /* "_M" */
3815 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */
3816 2+ /* "_V" */
3817 8+ /* version in dec */
3818 1; /* nul */
3819 name = xmalloc(l);
3820 if (stat(absolute_filename, &statbuf) != 0)
3821 statbuf.st_mtime = 0;
3822 version = get_module_version(f, str); /* -1 if not found */
3823 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
3824 symprefix, m_name, absolute_filename,
3825 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3826 version);
3827 sym = obj_add_symbol(f, name, -1,
3828 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3829 sec->idx, sec->header.sh_addr, 0);
3830 if (use_ksymtab)
3831 new_add_ksymtab(f, sym);
3832 }
3833 free(absolute_filename);
3834#ifdef _NOT_SUPPORTED_
3835 /* record where the persistent data is going, same address as previous symbol */
3836
3837 if (f->persist) {
3838 l = sizeof(symprefix)+ /* "__insmod_" */
3839 lm_name+ /* module name */
3840 2+ /* "_P" */
3841 strlen(f->persist)+ /* data store */
3842 1; /* nul */
3843 name = xmalloc(l);
3844 snprintf(name, l, "%s%s_P%s",
3845 symprefix, m_name, f->persist);
3846 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3847 sec->idx, sec->header.sh_addr, 0);
3848 if (use_ksymtab)
3849 new_add_ksymtab(f, sym);
3850 }
3851#endif /* _NOT_SUPPORTED_ */
3852 /* tag the desired sections if size is non-zero */
3853
3854 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
3855 if ((sec = obj_find_section(f, section_names[i])) &&
3856 sec->header.sh_size) {
3857 l = sizeof(symprefix)+ /* "__insmod_" */
3858 lm_name+ /* module name */
3859 2+ /* "_S" */
3860 strlen(sec->name)+ /* section name */
3861 2+ /* "_L" */
3862 8+ /* length in dec */
3863 1; /* nul */
3864 name = xmalloc(l);
3865 snprintf(name, l, "%s%s_S%s_L%ld",
3866 symprefix, m_name, sec->name,
3867 (long)sec->header.sh_size);
3868 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3869 sec->idx, sec->header.sh_addr, 0);
3870 if (use_ksymtab)
3871 new_add_ksymtab(f, sym);
3872 }
3873 }
3874}
3875#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3876
3877#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3878static void print_load_map(struct obj_file *f)
3879{
3880 struct obj_symbol *sym;
3881 struct obj_symbol **all, **p;
3882 struct obj_section *sec;
3883 int i, nsyms, *loaded;
3884
3885 /* Report on the section layout. */
3886
3887 printf("Sections: Size %-*s Align\n",
3888 (int) (2 * sizeof(void *)), "Address");
3889
3890 for (sec = f->load_order; sec; sec = sec->load_next) {
3891 int a;
3892 unsigned long tmp;
3893
3894 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3895 tmp >>= 1;
3896 if (a == -1)
3897 a = 0;
3898
3899 printf("%-15s %08lx %0*lx 2**%d\n",
3900 sec->name,
3901 (long)sec->header.sh_size,
3902 (int) (2 * sizeof(void *)),
3903 (long)sec->header.sh_addr,
3904 a);
3905 }
3906#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
3907 /* Quick reference which section indicies are loaded. */
3908
3909 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3910 while (--i >= 0)
3911 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3912
3913 /* Collect the symbols we'll be listing. */
3914
3915 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3916 for (sym = f->symtab[i]; sym; sym = sym->next)
3917 if (sym->secidx <= SHN_HIRESERVE
3918 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3919 ++nsyms;
3920
3921 all = alloca(nsyms * sizeof(struct obj_symbol *));
3922
3923 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3924 for (sym = f->symtab[i]; sym; sym = sym->next)
3925 if (sym->secidx <= SHN_HIRESERVE
3926 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3927 *p++ = sym;
3928
3929 /* And list them. */
3930 printf("\nSymbols:\n");
3931 for (p = all; p < all + nsyms; ++p) {
3932 char type = '?';
3933 unsigned long value;
3934
3935 sym = *p;
3936 if (sym->secidx == SHN_ABS) {
3937 type = 'A';
3938 value = sym->value;
3939 } else if (sym->secidx == SHN_UNDEF) {
3940 type = 'U';
3941 value = 0;
3942 } else {
3943 sec = f->sections[sym->secidx];
3944
3945 if (sec->header.sh_type == SHT_NOBITS)
3946 type = 'B';
3947 else if (sec->header.sh_flags & SHF_ALLOC) {
3948 if (sec->header.sh_flags & SHF_EXECINSTR)
3949 type = 'T';
3950 else if (sec->header.sh_flags & SHF_WRITE)
3951 type = 'D';
3952 else
3953 type = 'R';
3954 }
3955 value = sym->value + sec->header.sh_addr;
3956 }
3957
3958 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
3959 type = tolower(type);
3960
3961 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3962 type, sym->name);
3963 }
3964#endif
3965}
3966
3967#endif
3968
3969int insmod_main( int argc, char **argv)
3970{
3971 int opt;
3972 int len;
3973 int k_crcs;
3974 char *tmp, *tmp1;
3975 unsigned long m_size;
3976 ElfW(Addr) m_addr;
3977 struct obj_file *f;
3978 struct stat st;
3979 char *m_name = 0;
3980 int exit_status = EXIT_FAILURE;
3981 int m_has_modinfo;
3982#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
3983 struct utsname uts_info;
3984 char m_strversion[STRVERSIONLEN];
3985 int m_version, m_crcs;
3986#endif
3987#ifdef CONFIG_FEATURE_CLEAN_UP
3988 FILE *fp = 0;
3989#else
3990 FILE *fp;
3991#endif
3992#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3993 int flag_print_load_map = 0;
3994#endif
3995 int k_version = 0;
3996 struct utsname myuname;
3997
3998 /* Parse any options */
3999#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
4000 while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0)
4001#else
4002 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0)
4003#endif
4004 {
4005 switch (opt) {
4006 case 'f': /* force loading */
4007 flag_force_load = 1;
4008 break;
4009 case 'k': /* module loaded by kerneld, auto-cleanable */
4010 flag_autoclean = 1;
4011 break;
4012 case 's': /* log to syslog */
4013 /* log to syslog -- not supported */
4014 /* but kernel needs this for request_module(), */
4015 /* as this calls: modprobe -k -s -- <module> */
4016 /* so silently ignore this flag */
4017 break;
4018 case 'v': /* verbose output */
4019 flag_verbose = 1;
4020 break;
4021 case 'q': /* silent */
4022 flag_quiet = 1;
4023 break;
4024 case 'x': /* do not export externs */
4025 flag_export = 0;
4026 break;
4027 case 'o': /* name the output module */
4028 free(m_name);
4029 m_name = bb_xstrdup(optarg);
4030 break;
4031 case 'L': /* Stub warning */
4032 /* This is needed for compatibility with modprobe.
4033 * In theory, this does locking, but we don't do
4034 * that. So be careful and plan your life around not
4035 * loading the same module 50 times concurrently. */
4036 break;
4037#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
4038 case 'm': /* print module load map */
4039 flag_print_load_map = 1;
4040 break;
4041#endif
4042 default:
4043 bb_show_usage();
4044 }
4045 }
4046
4047 if (argv[optind] == NULL) {
4048 bb_show_usage();
4049 }
4050
4051 /* Grab the module name */
4052 tmp1 = bb_xstrdup(argv[optind]);
4053 tmp = basename(tmp1);
4054 len = strlen(tmp);
4055
4056 if (uname(&myuname) == 0) {
4057 if (myuname.release[0] == '2') {
4058 k_version = myuname.release[2] - '0';
4059 }
4060 }
4061
4062#if defined(CONFIG_FEATURE_2_6_MODULES)
4063 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' &&
4064 tmp[len - 2] == 'k' && tmp[len - 1] == 'o') {
4065 len-=3;
4066 tmp[len] = '\0';
4067 }
4068 else
4069#endif
4070 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
4071 len-=2;
4072 tmp[len] = '\0';
4073 }
4074
4075
4076#if defined(CONFIG_FEATURE_2_6_MODULES)
4077 if (k_version > 4)
4078 m_fullName = bb_xasprintf("%s.ko", tmp);
4079 else
4080#endif
4081 m_fullName = bb_xasprintf("%s.o", tmp);
4082
4083 if (!m_name) {
4084 m_name = tmp;
4085 } else {
4086 free(tmp1);
4087 tmp1 = 0; /* flag for free(m_name) before exit() */
4088 }
4089
4090 /* Get a filedesc for the module. Check we we have a complete path */
4091 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
4092 (fp = fopen(argv[optind], "r")) == NULL) {
4093 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
4094 * but do not error out yet if we fail to find it... */
4095 if (k_version) { /* uname succeedd */
4096 char *module_dir;
4097 char *tmdn;
4098 char real_module_dir[FILENAME_MAX];
4099
4100 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
4101 /* Jump through hoops in case /lib/modules/`uname -r`
4102 * is a symlink. We do not want recursive_action to
4103 * follow symlinks, but we do want to follow the
4104 * /lib/modules/`uname -r` dir, So resolve it ourselves
4105 * if it is a link... */
4106 if (realpath (tmdn, real_module_dir) == NULL)
4107 module_dir = tmdn;
4108 else
4109 module_dir = real_module_dir;
4110 recursive_action(module_dir, TRUE, FALSE, FALSE,
4111 check_module_name_match, 0, m_fullName);
4112 free(tmdn);
4113 }
4114
4115 /* Check if we have found anything yet */
4116 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL))
4117 {
4118 char module_dir[FILENAME_MAX];
4119
4120 free(m_filename);
4121 m_filename = 0;
4122 if (realpath (_PATH_MODULES, module_dir) == NULL)
4123 strcpy(module_dir, _PATH_MODULES);
4124 /* No module found under /lib/modules/`uname -r`, this
4125 * time cast the net a bit wider. Search /lib/modules/ */
4126 if (! recursive_action(module_dir, TRUE, FALSE, FALSE,
4127 check_module_name_match, 0, m_fullName))
4128 {
4129 if (m_filename == 0
4130 || ((fp = fopen(m_filename, "r")) == NULL))
4131 {
4132 bb_error_msg("%s: no module by that name found", m_fullName);
4133 goto out;
4134 }
4135 } else
4136 bb_error_msg_and_die("%s: no module by that name found", m_fullName);
4137 }
4138 } else
4139 m_filename = bb_xstrdup(argv[optind]);
4140
4141 if (flag_verbose)
4142 printf("Using %s\n", m_filename);
4143
4144#ifdef CONFIG_FEATURE_2_6_MODULES
4145 if (k_version > 4)
4146 {
4147 optind--;
4148 argv[optind + 1] = m_filename;
4149 return insmod_ng_main(argc - optind, argv + optind);
4150 }
4151#endif
4152
4153 if ((f = obj_load(fp, LOADBITS)) == NULL)
4154 bb_perror_msg_and_die("Could not load the module");
4155
4156 if (get_modinfo_value(f, "kernel_version") == NULL)
4157 m_has_modinfo = 0;
4158 else
4159 m_has_modinfo = 1;
4160
4161#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
4162 /* Version correspondence? */
4163 if (!flag_quiet) {
4164 if (uname(&uts_info) < 0)
4165 uts_info.release[0] = '\0';
4166 if (m_has_modinfo) {
4167 m_version = new_get_module_version(f, m_strversion);
4168 if (m_version == -1) {
4169 bb_error_msg("couldn't find the kernel version the module was "
4170 "compiled for");
4171 goto out;
4172 }
4173 }
4174
4175 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
4176 if (flag_force_load) {
4177 bb_error_msg("Warning: kernel-module version mismatch\n"
4178 "\t%s was compiled for kernel version %s\n"
4179 "\twhile this kernel is version %s",
4180 m_filename, m_strversion, uts_info.release);
4181 } else {
4182 bb_error_msg("kernel-module version mismatch\n"
4183 "\t%s was compiled for kernel version %s\n"
4184 "\twhile this kernel is version %s.",
4185 m_filename, m_strversion, uts_info.release);
4186 goto out;
4187 }
4188 }
4189 }
4190 k_crcs = 0;
4191#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
4192
4193 if (!query_module(NULL, 0, NULL, 0, NULL)) {
4194 if (!new_get_kernel_symbols())
4195 goto out;
4196 k_crcs = new_is_kernel_checksummed();
4197 } else {
4198 bb_error_msg("Not configured to support old kernels");
4199 goto out;
4200 }
4201
4202#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
4203 m_crcs = 0;
4204 if (m_has_modinfo)
4205 m_crcs = new_is_module_checksummed(f);
4206
4207 if (m_crcs != k_crcs)
4208 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
4209#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
4210
4211 /* Let the module know about the kernel symbols. */
4212 add_kernel_symbols(f);
4213
4214 /* Allocate common symbols, symbol tables, and string tables. */
4215
4216 if (!new_create_this_module(f, m_name))
4217 {
4218 goto out;
4219 }
4220
4221 if (!obj_check_undefineds(f)) {
4222 goto out;
4223 }
4224 obj_allocate_commons(f);
4225 check_tainted_module(f, m_name);
4226
4227 /* done with the module name, on to the optional var=value arguments */
4228 ++optind;
4229
4230 if (optind < argc) {
4231 if (!new_process_module_arguments(f, argc - optind, argv + optind))
4232 {
4233 goto out;
4234 }
4235 }
4236
4237 arch_create_got(f);
4238 hide_special_symbols(f);
4239
4240#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
4241 add_ksymoops_symbols(f, m_filename, m_name);
4242#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
4243
4244 new_create_module_ksymtab(f);
4245
4246 /* Find current size of the module */
4247 m_size = obj_load_size(f);
4248
4249
4250 m_addr = create_module(m_name, m_size);
4251 if (m_addr == -1) switch (errno) {
4252 case EEXIST:
4253 bb_error_msg("A module named %s already exists", m_name);
4254 goto out;
4255 case ENOMEM:
4256 bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes",
4257 m_size);
4258 goto out;
4259 default:
4260 bb_perror_msg("create_module: %s", m_name);
4261 goto out;
4262 }
4263
4264#if !LOADBITS
4265 /*
4266 * the PROGBITS section was not loaded by the obj_load
4267 * now we can load them directly into the kernel memory
4268 */
4269 if (!obj_load_progbits(fp, f, (char*)m_addr)) {
4270 delete_module(m_name);
4271 goto out;
4272 }
4273#endif
4274
4275 if (!obj_relocate(f, m_addr)) {
4276 delete_module(m_name);
4277 goto out;
4278 }
4279
4280 if (!new_init_module(m_name, f, m_size))
4281 {
4282 delete_module(m_name);
4283 goto out;
4284 }
4285
4286#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
4287 if(flag_print_load_map)
4288 print_load_map(f);
4289#endif
4290
4291 exit_status = EXIT_SUCCESS;
4292
4293out:
4294#ifdef CONFIG_FEATURE_CLEAN_UP
4295 if(fp)
4296 fclose(fp);
4297 free(tmp1);
4298 if(!tmp1) {
4299 free(m_name);
4300 }
4301 free(m_filename);
4302#endif
4303 return(exit_status);
4304}
4305
4306
4307#endif
4308
4309
4310#ifdef CONFIG_FEATURE_2_6_MODULES
4311
4312#include <sys/mman.h>
4313#include <asm/unistd.h>
4314#include <sys/syscall.h>
4315
4316/* We use error numbers in a loose translation... */
4317static const char *moderror(int err)
4318{
4319 switch (err) {
4320 case ENOEXEC:
4321 return "Invalid module format";
4322 case ENOENT:
4323 return "Unknown symbol in module";
4324 case ESRCH:
4325 return "Module has wrong symbol version";
4326 case EINVAL:
4327 return "Invalid parameters";
4328 default:
4329 return strerror(err);
4330 }
4331}
4332
4333int insmod_ng_main( int argc, char **argv)
4334{
4335 int i;
4336 int fd;
4337 long int ret;
4338 struct stat st;
4339 unsigned long len;
4340 void *map;
4341 char *filename, *options = bb_xstrdup("");
4342
4343 filename = argv[1];
4344 if (!filename) {
4345 bb_show_usage();
4346 return -1;
4347 }
4348
4349 /* Rest is options */
4350 for (i = 2; i < argc; i++) {
4351 options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2);
4352 /* Spaces handled by "" pairs, but no way of escaping quotes */
4353 if (strchr(argv[i], ' ')) {
4354 strcat(options, "\"");
4355 strcat(options, argv[i]);
4356 strcat(options, "\"");
4357 } else {
4358 strcat(options, argv[i]);
4359 }
4360 strcat(options, " ");
4361 }
4362
4363 fd = bb_xopen3(filename, O_RDONLY, 0);
4364
4365 fstat(fd, &st);
4366 len = st.st_size;
4367 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
4368 if (map == MAP_FAILED) {
4369 bb_perror_msg_and_die("cannot mmap `%s'", filename);
4370 }
4371
4372 ret = syscall(__NR_init_module, map, len, options);
4373 if (ret != 0) {
4374 bb_perror_msg_and_die("cannot insert `%s': %s (%li)",
4375 filename, moderror(errno), ret);
4376 }
4377
4378 return 0;
4379}
4380
4381#endif
Note: See TracBrowser for help on using the repository browser.