blob: a16cb1bbe39328b34d1151facb117a8d3035d70c [file] [log] [blame]
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001/* 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 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 "libbb.h"
62#include "modutils.h"
63#include <libgen.h>
64#include <sys/utsname.h>
65
66#if ENABLE_FEATURE_INSMOD_LOADINKMEM
67#define LOADBITS 0
68#else
69#define LOADBITS 1
70#endif
71
72/* Alpha */
73#if defined(__alpha__)
74#define MATCH_MACHINE(x) (x == EM_ALPHA)
75#define SHT_RELM SHT_RELA
76#define Elf64_RelM Elf64_Rela
77#define ELFCLASSM ELFCLASS64
78#endif
79
80/* ARM support */
81#if defined(__arm__)
82#define MATCH_MACHINE(x) (x == EM_ARM)
83#define SHT_RELM SHT_REL
84#define Elf32_RelM Elf32_Rel
85#define ELFCLASSM ELFCLASS32
86#define USE_PLT_ENTRIES
87#define PLT_ENTRY_SIZE 8
88#define USE_GOT_ENTRIES
89#define GOT_ENTRY_SIZE 8
90#define USE_SINGLE
91#endif
92
93/* blackfin */
94#if defined(BFIN)
95#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
96#define SHT_RELM SHT_RELA
97#define Elf32_RelM Elf32_Rela
98#define ELFCLASSM ELFCLASS32
99#endif
100
101/* CRIS */
102#if defined(__cris__)
103#define MATCH_MACHINE(x) (x == EM_CRIS)
104#define SHT_RELM SHT_RELA
105#define Elf32_RelM Elf32_Rela
106#define ELFCLASSM ELFCLASS32
107#ifndef EM_CRIS
108#define EM_CRIS 76
109#define R_CRIS_NONE 0
110#define R_CRIS_32 3
111#endif
112#endif
113
114/* H8/300 */
115#if defined(__H8300H__) || defined(__H8300S__)
116#define MATCH_MACHINE(x) (x == EM_H8_300)
117#define SHT_RELM SHT_RELA
118#define Elf32_RelM Elf32_Rela
119#define ELFCLASSM ELFCLASS32
120#define USE_SINGLE
121#define SYMBOL_PREFIX "_"
122#endif
123
124/* PA-RISC / HP-PA */
125#if defined(__hppa__)
126#define MATCH_MACHINE(x) (x == EM_PARISC)
127#define SHT_RELM SHT_RELA
128#if defined(__LP64__)
129#define Elf64_RelM Elf64_Rela
130#define ELFCLASSM ELFCLASS64
131#else
132#define Elf32_RelM Elf32_Rela
133#define ELFCLASSM ELFCLASS32
134#endif
135#endif
136
137/* x86 */
138#if defined(__i386__)
139#ifndef EM_486
140#define MATCH_MACHINE(x) (x == EM_386)
141#else
142#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
143#endif
144#define SHT_RELM SHT_REL
145#define Elf32_RelM Elf32_Rel
146#define ELFCLASSM ELFCLASS32
147#define USE_GOT_ENTRIES
148#define GOT_ENTRY_SIZE 4
149#define USE_SINGLE
150#endif
151
152/* IA64, aka Itanium */
153#if defined(__ia64__)
154#define MATCH_MACHINE(x) (x == EM_IA_64)
155#define SHT_RELM SHT_RELA
156#define Elf64_RelM Elf64_Rela
157#define ELFCLASSM ELFCLASS64
158#endif
159
160/* m68k */
161#if defined(__mc68000__)
162#define MATCH_MACHINE(x) (x == EM_68K)
163#define SHT_RELM SHT_RELA
164#define Elf32_RelM Elf32_Rela
165#define ELFCLASSM ELFCLASS32
166#define USE_GOT_ENTRIES
167#define GOT_ENTRY_SIZE 4
168#define USE_SINGLE
169#endif
170
171/* Microblaze */
172#if defined(__microblaze__)
173#define USE_SINGLE
174#include <linux/elf-em.h>
175#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
176#define SHT_RELM SHT_RELA
177#define Elf32_RelM Elf32_Rela
178#define ELFCLASSM ELFCLASS32
179#endif
180
181/* MIPS */
182#if defined(__mips__)
183#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
184#define SHT_RELM SHT_REL
185#define Elf32_RelM Elf32_Rel
186#define ELFCLASSM ELFCLASS32
187/* Account for ELF spec changes. */
188#ifndef EM_MIPS_RS3_LE
189#ifdef EM_MIPS_RS4_BE
190#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
191#else
192#define EM_MIPS_RS3_LE 10
193#endif
194#endif /* !EM_MIPS_RS3_LE */
195#define ARCHDATAM "__dbe_table"
196#endif
197
198/* Nios II */
199#if defined(__nios2__)
200#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
201#define SHT_RELM SHT_RELA
202#define Elf32_RelM Elf32_Rela
203#define ELFCLASSM ELFCLASS32
204#endif
205
206/* PowerPC */
207#if defined(__powerpc64__)
208#define MATCH_MACHINE(x) (x == EM_PPC64)
209#define SHT_RELM SHT_RELA
210#define Elf64_RelM Elf64_Rela
211#define ELFCLASSM ELFCLASS64
212#elif defined(__powerpc__)
213#define MATCH_MACHINE(x) (x == EM_PPC)
214#define SHT_RELM SHT_RELA
215#define Elf32_RelM Elf32_Rela
216#define ELFCLASSM ELFCLASS32
217#define USE_PLT_ENTRIES
218#define PLT_ENTRY_SIZE 16
219#define USE_PLT_LIST
220#define LIST_ARCHTYPE ElfW(Addr)
221#define USE_LIST
222#define ARCHDATAM "__ftr_fixup"
223#endif
224
225/* S390 */
226#if defined(__s390__)
227#define MATCH_MACHINE(x) (x == EM_S390)
228#define SHT_RELM SHT_RELA
229#define Elf32_RelM Elf32_Rela
230#define ELFCLASSM ELFCLASS32
231#define USE_PLT_ENTRIES
232#define PLT_ENTRY_SIZE 8
233#define USE_GOT_ENTRIES
234#define GOT_ENTRY_SIZE 8
235#define USE_SINGLE
236#endif
237
238/* SuperH */
239#if defined(__sh__)
240#define MATCH_MACHINE(x) (x == EM_SH)
241#define SHT_RELM SHT_RELA
242#define Elf32_RelM Elf32_Rela
243#define ELFCLASSM ELFCLASS32
244#define USE_GOT_ENTRIES
245#define GOT_ENTRY_SIZE 4
246#define USE_SINGLE
247/* the SH changes have only been tested in =little endian= mode */
248/* I'm not sure about big endian, so let's warn: */
249#if defined(__sh__) && BB_BIG_ENDIAN
250# error insmod.c may require changes for use on big endian SH
251#endif
252/* it may or may not work on the SH1/SH2... Error on those also */
253#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
254#error insmod.c may require changes for SH1 or SH2 use
255#endif
256#endif
257
258/* Sparc */
259#if defined(__sparc__)
260#define MATCH_MACHINE(x) (x == EM_SPARC)
261#define SHT_RELM SHT_RELA
262#define Elf32_RelM Elf32_Rela
263#define ELFCLASSM ELFCLASS32
264#endif
265
266/* v850e */
267#if defined(__v850e__)
268#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
269#define SHT_RELM SHT_RELA
270#define Elf32_RelM Elf32_Rela
271#define ELFCLASSM ELFCLASS32
272#define USE_PLT_ENTRIES
273#define PLT_ENTRY_SIZE 8
274#define USE_SINGLE
275#ifndef EM_CYGNUS_V850 /* grumble */
276#define EM_CYGNUS_V850 0x9080
277#endif
278#define SYMBOL_PREFIX "_"
279#endif
280
281/* X86_64 */
282#if defined(__x86_64__)
283#define MATCH_MACHINE(x) (x == EM_X86_64)
284#define SHT_RELM SHT_RELA
285#define USE_GOT_ENTRIES
286#define GOT_ENTRY_SIZE 8
287#define USE_SINGLE
288#define Elf64_RelM Elf64_Rela
289#define ELFCLASSM ELFCLASS64
290#endif
291
292#ifndef SHT_RELM
293#error Sorry, but insmod.c does not yet support this architecture...
294#endif
295
296
297//----------------------------------------------------------------------------
298//--------modutils module.h, lines 45-242
299//----------------------------------------------------------------------------
300
301/* Definitions for the Linux module syscall interface.
302 Copyright 1996, 1997 Linux International.
303
304 Contributed by Richard Henderson <rth@tamu.edu>
305
306 This file is part of the Linux modutils.
307
308 This program is free software; you can redistribute it and/or modify it
309 under the terms of the GNU General Public License as published by the
310 Free Software Foundation; either version 2 of the License, or (at your
311 option) any later version.
312
313 This program is distributed in the hope that it will be useful, but
314 WITHOUT ANY WARRANTY; without even the implied warranty of
315 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
316 General Public License for more details.
317
318 You should have received a copy of the GNU General Public License
319 along with this program; if not, write to the Free Software Foundation,
320 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
321
322
323#ifndef MODUTILS_MODULE_H
324
325/*======================================================================*/
326/* For sizeof() which are related to the module platform and not to the
327 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
328
329#define tgt_sizeof_char sizeof(char)
330#define tgt_sizeof_short sizeof(short)
331#define tgt_sizeof_int sizeof(int)
332#define tgt_sizeof_long sizeof(long)
333#define tgt_sizeof_char_p sizeof(char *)
334#define tgt_sizeof_void_p sizeof(void *)
335#define tgt_long long
336
337#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
338#undef tgt_sizeof_long
339#undef tgt_sizeof_char_p
340#undef tgt_sizeof_void_p
341#undef tgt_long
342enum {
343 tgt_sizeof_long = 8,
344 tgt_sizeof_char_p = 8,
345 tgt_sizeof_void_p = 8
346};
347#define tgt_long long long
348#endif
349
350/*======================================================================*/
351/* The structures used in Linux 2.1. */
352
353/* Note: new_module_symbol does not use tgt_long intentionally */
354struct new_module_symbol {
355 unsigned long value;
356 unsigned long name;
357};
358
359struct new_module_persist;
360
361struct new_module_ref {
362 unsigned tgt_long dep; /* kernel addresses */
363 unsigned tgt_long ref;
364 unsigned tgt_long next_ref;
365};
366
367struct new_module {
368 unsigned tgt_long size_of_struct; /* == sizeof(module) */
369 unsigned tgt_long next;
370 unsigned tgt_long name;
371 unsigned tgt_long size;
372
373 tgt_long usecount;
374 unsigned tgt_long flags; /* AUTOCLEAN et al */
375
376 unsigned nsyms;
377 unsigned ndeps;
378
379 unsigned tgt_long syms;
380 unsigned tgt_long deps;
381 unsigned tgt_long refs;
382 unsigned tgt_long init;
383 unsigned tgt_long cleanup;
384 unsigned tgt_long ex_table_start;
385 unsigned tgt_long ex_table_end;
386#ifdef __alpha__
387 unsigned tgt_long gp;
388#endif
389 /* Everything after here is extension. */
390 unsigned tgt_long persist_start;
391 unsigned tgt_long persist_end;
392 unsigned tgt_long can_unload;
393 unsigned tgt_long runsize;
394 const char *kallsyms_start; /* All symbols for kernel debugging */
395 const char *kallsyms_end;
396 const char *archdata_start; /* arch specific data for module */
397 const char *archdata_end;
398 const char *kernel_data; /* Reserved for kernel internal use */
399};
400
401#ifdef ARCHDATAM
402#define ARCHDATA_SEC_NAME ARCHDATAM
403#else
404#define ARCHDATA_SEC_NAME "__archdata"
405#endif
406#define KALLSYMS_SEC_NAME "__kallsyms"
407
408
409struct new_module_info {
410 unsigned long addr;
411 unsigned long size;
412 unsigned long flags;
413 long usecount;
414};
415
416/* Bits of module.flags. */
417enum {
418 NEW_MOD_RUNNING = 1,
419 NEW_MOD_DELETED = 2,
420 NEW_MOD_AUTOCLEAN = 4,
421 NEW_MOD_VISITED = 8,
422 NEW_MOD_USED_ONCE = 16
423};
424
425int init_module(const char *name, const struct new_module *);
426int query_module(const char *name, int which, void *buf,
427 size_t bufsize, size_t *ret);
428
429/* Values for query_module's which. */
430enum {
431 QM_MODULES = 1,
432 QM_DEPS = 2,
433 QM_REFS = 3,
434 QM_SYMBOLS = 4,
435 QM_INFO = 5
436};
437
438/*======================================================================*/
439/* The system calls unchanged between 2.0 and 2.1. */
440
441unsigned long create_module(const char *, size_t);
442int delete_module(const char *module, unsigned int flags);
443
444
445#endif /* module.h */
446
447//----------------------------------------------------------------------------
448//--------end of modutils module.h
449//----------------------------------------------------------------------------
450
451
452
453//----------------------------------------------------------------------------
454//--------modutils obj.h, lines 253-462
455//----------------------------------------------------------------------------
456
457/* Elf object file loading and relocation routines.
458 Copyright 1996, 1997 Linux International.
459
460 Contributed by Richard Henderson <rth@tamu.edu>
461
462 This file is part of the Linux modutils.
463
464 This program is free software; you can redistribute it and/or modify it
465 under the terms of the GNU General Public License as published by the
466 Free Software Foundation; either version 2 of the License, or (at your
467 option) any later version.
468
469 This program is distributed in the hope that it will be useful, but
470 WITHOUT ANY WARRANTY; without even the implied warranty of
471 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
472 General Public License for more details.
473
474 You should have received a copy of the GNU General Public License
475 along with this program; if not, write to the Free Software Foundation,
476 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
477
478
479#ifndef MODUTILS_OBJ_H
480
481/* The relocatable object is manipulated using elfin types. */
482
483#include <elf.h>
484#include <endian.h>
485
486#ifndef ElfW
487# if ELFCLASSM == ELFCLASS32
488# define ElfW(x) Elf32_ ## x
489# define ELFW(x) ELF32_ ## x
490# else
491# define ElfW(x) Elf64_ ## x
492# define ELFW(x) ELF64_ ## x
493# endif
494#endif
495
496/* For some reason this is missing from some ancient C libraries.... */
497#ifndef ELF32_ST_INFO
498# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
499#endif
500
501#ifndef ELF64_ST_INFO
502# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
503#endif
504
505#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
506#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
507#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
508#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
509#define ELF_R_SYM(val) ELFW(R_SYM)(val)
510
511struct obj_string_patch;
512struct obj_symbol_patch;
513
514struct obj_section
515{
516 ElfW(Shdr) header;
517 const char *name;
518 char *contents;
519 struct obj_section *load_next;
520 int idx;
521};
522
523struct obj_symbol
524{
525 struct obj_symbol *next; /* hash table link */
526 const char *name;
527 unsigned long value;
528 unsigned long size;
529 int secidx; /* the defining section index/module */
530 int info;
531 int ksymidx; /* for export to the kernel symtab */
532 int referenced; /* actually used in the link */
533};
534
535/* Hardcode the hash table size. We shouldn't be needing so many
536 symbols that we begin to degrade performance, and we get a big win
537 by giving the compiler a constant divisor. */
538
539#define HASH_BUCKETS 521
540
541struct obj_file {
542 ElfW(Ehdr) header;
543 ElfW(Addr) baseaddr;
544 struct obj_section **sections;
545 struct obj_section *load_order;
546 struct obj_section **load_order_search_start;
547 struct obj_string_patch *string_patches;
548 struct obj_symbol_patch *symbol_patches;
549 int (*symbol_cmp)(const char *, const char *);
550 unsigned long (*symbol_hash)(const char *);
551 unsigned long local_symtab_size;
552 struct obj_symbol **local_symtab;
553 struct obj_symbol *symtab[HASH_BUCKETS];
554};
555
556enum obj_reloc {
557 obj_reloc_ok,
558 obj_reloc_overflow,
559 obj_reloc_dangerous,
560 obj_reloc_unhandled
561};
562
563struct obj_string_patch {
564 struct obj_string_patch *next;
565 int reloc_secidx;
566 ElfW(Addr) reloc_offset;
567 ElfW(Addr) string_offset;
568};
569
570struct obj_symbol_patch {
571 struct obj_symbol_patch *next;
572 int reloc_secidx;
573 ElfW(Addr) reloc_offset;
574 struct obj_symbol *sym;
575};
576
577
578/* Generic object manipulation routines. */
579
580static unsigned long obj_elf_hash(const char *);
581
582static unsigned long obj_elf_hash_n(const char *, unsigned long len);
583
584static struct obj_symbol *obj_find_symbol(struct obj_file *f,
585 const char *name);
586
587static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
588 struct obj_symbol *sym);
589
590#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
591static void obj_set_symbol_compare(struct obj_file *f,
592 int (*cmp)(const char *, const char *),
593 unsigned long (*hash)(const char *));
594#endif
595
596static struct obj_section *obj_find_section(struct obj_file *f,
597 const char *name);
598
599static void obj_insert_section_load_order(struct obj_file *f,
600 struct obj_section *sec);
601
602static struct obj_section *obj_create_alloced_section(struct obj_file *f,
603 const char *name,
604 unsigned long align,
605 unsigned long size);
606
607static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
608 const char *name,
609 unsigned long align,
610 unsigned long size);
611
612static void *obj_extend_section(struct obj_section *sec, unsigned long more);
613
614static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
615 const char *string);
616
617static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
618 struct obj_symbol *sym);
619
620static void obj_check_undefineds(struct obj_file *f);
621
622static void obj_allocate_commons(struct obj_file *f);
623
624static unsigned long obj_load_size(struct obj_file *f);
625
626static int obj_relocate(struct obj_file *f, ElfW(Addr) base);
627
Denis Vlasenkof4393042009-04-05 23:25:09 +0000628#if !LOADBITS
629#define obj_load(image, image_size, loadprogbits) \
630 obj_load(image, image_size)
631#endif
632static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000633
634static int obj_create_image(struct obj_file *f, char *image);
635
636/* Architecture specific manipulation routines. */
637
638static struct obj_file *arch_new_file(void);
639
640static struct obj_section *arch_new_section(void);
641
642static struct obj_symbol *arch_new_symbol(void);
643
644static enum obj_reloc arch_apply_relocation(struct obj_file *f,
645 struct obj_section *targsec,
646 /*struct obj_section *symsec,*/
647 struct obj_symbol *sym,
648 ElfW(RelM) *rel, ElfW(Addr) value);
649
650static void arch_create_got(struct obj_file *f);
651#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
652static int obj_gpl_license(struct obj_file *f, const char **license);
Denis Vlasenkoe35af562009-01-31 14:22:24 +0000653#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000654#endif /* obj.h */
655//----------------------------------------------------------------------------
656//--------end of modutils obj.h
657//----------------------------------------------------------------------------
658
659
660/* SPFX is always a string, so it can be concatenated to string constants. */
661#ifdef SYMBOL_PREFIX
662#define SPFX SYMBOL_PREFIX
663#else
664#define SPFX ""
665#endif
666
667enum { STRVERSIONLEN = 64 };
668
669/*======================================================================*/
670
671#define flag_force_load (option_mask32 & INSMOD_OPT_FORCE)
672#define flag_autoclean (option_mask32 & INSMOD_OPT_KERNELD)
673#define flag_verbose (option_mask32 & INSMOD_OPT_VERBOSE)
674#define flag_quiet (option_mask32 & INSMOD_OPT_SILENT)
675#define flag_noexport (option_mask32 & INSMOD_OPT_NO_EXPORT)
676#define flag_print_load_map (option_mask32 & INSMOD_OPT_PRINT_MAP)
677
678/*======================================================================*/
679
680#if defined(USE_LIST)
681
682struct arch_list_entry
683{
684 struct arch_list_entry *next;
685 LIST_ARCHTYPE addend;
686 int offset;
687 int inited : 1;
688};
689
690#endif
691
692#if defined(USE_SINGLE)
693
694struct arch_single_entry
695{
696 int offset;
697 int inited : 1;
698 int allocated : 1;
699};
700
701#endif
702
703#if defined(__mips__)
704struct mips_hi16
705{
706 struct mips_hi16 *next;
707 ElfW(Addr) *addr;
708 ElfW(Addr) value;
709};
710#endif
711
712struct arch_file {
713 struct obj_file root;
714#if defined(USE_PLT_ENTRIES)
715 struct obj_section *plt;
716#endif
717#if defined(USE_GOT_ENTRIES)
718 struct obj_section *got;
719#endif
720#if defined(__mips__)
721 struct mips_hi16 *mips_hi16_list;
722#endif
723};
724
725struct arch_symbol {
726 struct obj_symbol root;
727#if defined(USE_PLT_ENTRIES)
728#if defined(USE_PLT_LIST)
729 struct arch_list_entry *pltent;
730#else
731 struct arch_single_entry pltent;
732#endif
733#endif
734#if defined(USE_GOT_ENTRIES)
735 struct arch_single_entry gotent;
736#endif
737};
738
739
740struct external_module {
741 const char *name;
742 ElfW(Addr) addr;
743 int used;
744 size_t nsyms;
745 struct new_module_symbol *syms;
746};
747
748static struct new_module_symbol *ksyms;
749static size_t nksyms;
750
751static struct external_module *ext_modules;
752static int n_ext_modules;
753static int n_ext_modules_used;
754
755/*======================================================================*/
756
757
758static struct obj_file *arch_new_file(void)
759{
760 struct arch_file *f;
761 f = xzalloc(sizeof(*f));
762 return &f->root; /* it's a first member */
763}
764
765static struct obj_section *arch_new_section(void)
766{
767 return xzalloc(sizeof(struct obj_section));
768}
769
770static struct obj_symbol *arch_new_symbol(void)
771{
772 struct arch_symbol *sym;
773 sym = xzalloc(sizeof(*sym));
774 return &sym->root;
775}
776
777static enum obj_reloc
778arch_apply_relocation(struct obj_file *f,
779 struct obj_section *targsec,
780 /*struct obj_section *symsec,*/
781 struct obj_symbol *sym,
782 ElfW(RelM) *rel, ElfW(Addr) v)
783{
784#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
785 || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
786 || defined(__powerpc__) || defined(__mips__)
787 struct arch_file *ifile = (struct arch_file *) f;
788#endif
789 enum obj_reloc ret = obj_reloc_ok;
790 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
791#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
792 || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
793 || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
794 || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
795 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
796#endif
797#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
798 struct arch_symbol *isym = (struct arch_symbol *) sym;
799#endif
800#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
801 || defined(__sh__) || defined(__s390__)
802#if defined(USE_GOT_ENTRIES)
803 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
804#endif
805#endif
806#if defined(USE_PLT_ENTRIES)
807 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
808 unsigned long *ip;
809# if defined(USE_PLT_LIST)
810 struct arch_list_entry *pe;
811# else
812 struct arch_single_entry *pe;
813# endif
814#endif
815
816 switch (ELF_R_TYPE(rel->r_info)) {
817
818#if defined(__arm__)
819
820 case R_ARM_NONE:
821 break;
822
823 case R_ARM_ABS32:
824 *loc += v;
825 break;
826
827 case R_ARM_GOT32:
828 goto bb_use_got;
829
830 case R_ARM_GOTPC:
831 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
832 * (which is .got) similar to branch,
833 * but is full 32 bits relative */
834
835 *loc += got - dot;
836 break;
837
838 case R_ARM_PC24:
839 case R_ARM_PLT32:
840 goto bb_use_plt;
841
842 case R_ARM_GOTOFF: /* address relative to the got */
843 *loc += v - got;
844 break;
845
846#elif defined(__cris__)
847
848 case R_CRIS_NONE:
849 break;
850
851 case R_CRIS_32:
852 /* CRIS keeps the relocation value in the r_addend field and
853 * should not use whats in *loc at all
854 */
855 *loc = v;
856 break;
857
858#elif defined(__H8300H__) || defined(__H8300S__)
859
860 case R_H8_DIR24R8:
861 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
862 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
863 break;
864 case R_H8_DIR24A8:
865 *loc += v;
866 break;
867 case R_H8_DIR32:
868 case R_H8_DIR32A16:
869 *loc += v;
870 break;
871 case R_H8_PCREL16:
872 v -= dot + 2;
873 if ((ElfW(Sword))v > 0x7fff ||
874 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
875 ret = obj_reloc_overflow;
876 else
877 *(unsigned short *)loc = v;
878 break;
879 case R_H8_PCREL8:
880 v -= dot + 1;
881 if ((ElfW(Sword))v > 0x7f ||
882 (ElfW(Sword))v < -(ElfW(Sword))0x80)
883 ret = obj_reloc_overflow;
884 else
885 *(unsigned char *)loc = v;
886 break;
887
888#elif defined(__i386__)
889
890 case R_386_NONE:
891 break;
892
893 case R_386_32:
894 *loc += v;
895 break;
896
897 case R_386_PLT32:
898 case R_386_PC32:
899 case R_386_GOTOFF:
900 *loc += v - dot;
901 break;
902
903 case R_386_GLOB_DAT:
904 case R_386_JMP_SLOT:
905 *loc = v;
906 break;
907
908 case R_386_RELATIVE:
909 *loc += f->baseaddr;
910 break;
911
912 case R_386_GOTPC:
913 *loc += got - dot;
914 break;
915
916 case R_386_GOT32:
917 goto bb_use_got;
918 break;
919
920#elif defined(__microblaze__)
921 case R_MICROBLAZE_NONE:
922 case R_MICROBLAZE_64_NONE:
923 case R_MICROBLAZE_32_SYM_OP_SYM:
924 case R_MICROBLAZE_32_PCREL:
925 break;
926
927 case R_MICROBLAZE_64_PCREL: {
928 /* dot is the address of the current instruction.
929 * v is the target symbol address.
930 * So we need to extract the offset in the code,
931 * adding v, then subtrating the current address
932 * of this instruction.
933 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
934 */
935
936 /* Get split offset stored in code */
937 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
938 (loc[1] & 0xFFFF);
939
940 /* Adjust relative offset. -4 adjustment required
941 * because dot points to the IMM insn, but branch
942 * is computed relative to the branch instruction itself.
943 */
944 temp += v - dot - 4;
945
946 /* Store back into code */
947 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
948 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
949
950 break;
951 }
952
953 case R_MICROBLAZE_32:
954 *loc += v;
955 break;
956
957 case R_MICROBLAZE_64: {
958 /* Get split pointer stored in code */
959 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
960 (loc[1] & 0xFFFF);
961
962 /* Add reloc offset */
963 temp1+=v;
964
965 /* Store back into code */
966 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
967 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
968
969 break;
970 }
971
972 case R_MICROBLAZE_32_PCREL_LO:
973 case R_MICROBLAZE_32_LO:
974 case R_MICROBLAZE_SRO32:
975 case R_MICROBLAZE_SRW32:
976 ret = obj_reloc_unhandled;
977 break;
978
979#elif defined(__mc68000__)
980
981 case R_68K_NONE:
982 break;
983
984 case R_68K_32:
985 *loc += v;
986 break;
987
988 case R_68K_8:
989 if (v > 0xff) {
990 ret = obj_reloc_overflow;
991 }
992 *(char *)loc = v;
993 break;
994
995 case R_68K_16:
996 if (v > 0xffff) {
997 ret = obj_reloc_overflow;
998 }
999 *(short *)loc = v;
1000 break;
1001
1002 case R_68K_PC8:
1003 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001004 if ((ElfW(Sword))v > 0x7f
1005 || (ElfW(Sword))v < -(ElfW(Sword))0x80
1006 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001007 ret = obj_reloc_overflow;
1008 }
1009 *(char *)loc = v;
1010 break;
1011
1012 case R_68K_PC16:
1013 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001014 if ((ElfW(Sword))v > 0x7fff
1015 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
1016 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001017 ret = obj_reloc_overflow;
1018 }
1019 *(short *)loc = v;
1020 break;
1021
1022 case R_68K_PC32:
1023 *(int *)loc = v - dot;
1024 break;
1025
1026 case R_68K_GLOB_DAT:
1027 case R_68K_JMP_SLOT:
1028 *loc = v;
1029 break;
1030
1031 case R_68K_RELATIVE:
1032 *(int *)loc += f->baseaddr;
1033 break;
1034
1035 case R_68K_GOT32:
1036 goto bb_use_got;
1037
1038# ifdef R_68K_GOTOFF
1039 case R_68K_GOTOFF:
1040 *loc += v - got;
1041 break;
1042# endif
1043
1044#elif defined(__mips__)
1045
1046 case R_MIPS_NONE:
1047 break;
1048
1049 case R_MIPS_32:
1050 *loc += v;
1051 break;
1052
1053 case R_MIPS_26:
1054 if (v % 4)
1055 ret = obj_reloc_dangerous;
1056 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1057 ret = obj_reloc_overflow;
1058 *loc =
1059 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1060 0x03ffffff);
1061 break;
1062
1063 case R_MIPS_HI16:
1064 {
1065 struct mips_hi16 *n;
1066
1067 /* We cannot relocate this one now because we don't know the value
1068 of the carry we need to add. Save the information, and let LO16
1069 do the actual relocation. */
1070 n = xmalloc(sizeof *n);
1071 n->addr = loc;
1072 n->value = v;
1073 n->next = ifile->mips_hi16_list;
1074 ifile->mips_hi16_list = n;
1075 break;
1076 }
1077
1078 case R_MIPS_LO16:
1079 {
1080 unsigned long insnlo = *loc;
1081 ElfW(Addr) val, vallo;
1082
1083 /* Sign extend the addend we extract from the lo insn. */
1084 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1085
1086 if (ifile->mips_hi16_list != NULL) {
1087 struct mips_hi16 *l;
1088
1089 l = ifile->mips_hi16_list;
1090 while (l != NULL) {
1091 struct mips_hi16 *next;
1092 unsigned long insn;
1093
1094 /* Do the HI16 relocation. Note that we actually don't
1095 need to know anything about the LO16 itself, except where
1096 to find the low 16 bits of the addend needed by the LO16. */
1097 insn = *l->addr;
1098 val =
1099 ((insn & 0xffff) << 16) +
1100 vallo;
1101 val += v;
1102
1103 /* Account for the sign extension that will happen in the
1104 low bits. */
1105 val =
1106 ((val >> 16) +
1107 ((val & 0x8000) !=
1108 0)) & 0xffff;
1109
1110 insn = (insn & ~0xffff) | val;
1111 *l->addr = insn;
1112
1113 next = l->next;
1114 free(l);
1115 l = next;
1116 }
1117
1118 ifile->mips_hi16_list = NULL;
1119 }
1120
1121 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1122 val = v + vallo;
1123 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1124 *loc = insnlo;
1125 break;
1126 }
1127
1128#elif defined(__nios2__)
1129
1130 case R_NIOS2_NONE:
1131 break;
1132
1133 case R_NIOS2_BFD_RELOC_32:
1134 *loc += v;
1135 break;
1136
1137 case R_NIOS2_BFD_RELOC_16:
1138 if (v > 0xffff) {
1139 ret = obj_reloc_overflow;
1140 }
1141 *(short *)loc = v;
1142 break;
1143
1144 case R_NIOS2_BFD_RELOC_8:
1145 if (v > 0xff) {
1146 ret = obj_reloc_overflow;
1147 }
1148 *(char *)loc = v;
1149 break;
1150
1151 case R_NIOS2_S16:
1152 {
1153 Elf32_Addr word;
1154
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001155 if ((Elf32_Sword)v > 0x7fff
1156 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1157 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001158 ret = obj_reloc_overflow;
1159 }
1160
1161 word = *loc;
1162 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1163 (word & 0x3f);
1164 }
1165 break;
1166
1167 case R_NIOS2_U16:
1168 {
1169 Elf32_Addr word;
1170
1171 if (v > 0xffff) {
1172 ret = obj_reloc_overflow;
1173 }
1174
1175 word = *loc;
1176 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1177 (word & 0x3f);
1178 }
1179 break;
1180
1181 case R_NIOS2_PCREL16:
1182 {
1183 Elf32_Addr word;
1184
1185 v -= dot + 4;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001186 if ((Elf32_Sword)v > 0x7fff
1187 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1188 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001189 ret = obj_reloc_overflow;
1190 }
1191
1192 word = *loc;
1193 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1194 }
1195 break;
1196
1197 case R_NIOS2_GPREL:
1198 {
1199 Elf32_Addr word, gp;
1200 /* get _gp */
1201 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001202 v -= gp;
1203 if ((Elf32_Sword)v > 0x7fff
1204 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1205 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001206 ret = obj_reloc_overflow;
1207 }
1208
1209 word = *loc;
1210 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1211 }
1212 break;
1213
1214 case R_NIOS2_CALL26:
1215 if (v & 3)
1216 ret = obj_reloc_dangerous;
1217 if ((v >> 28) != (dot >> 28))
1218 ret = obj_reloc_overflow;
1219 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1220 break;
1221
1222 case R_NIOS2_IMM5:
1223 {
1224 Elf32_Addr word;
1225
1226 if (v > 0x1f) {
1227 ret = obj_reloc_overflow;
1228 }
1229
1230 word = *loc & ~0x7c0;
1231 *loc = word | ((v & 0x1f) << 6);
1232 }
1233 break;
1234
1235 case R_NIOS2_IMM6:
1236 {
1237 Elf32_Addr word;
1238
1239 if (v > 0x3f) {
1240 ret = obj_reloc_overflow;
1241 }
1242
1243 word = *loc & ~0xfc0;
1244 *loc = word | ((v & 0x3f) << 6);
1245 }
1246 break;
1247
1248 case R_NIOS2_IMM8:
1249 {
1250 Elf32_Addr word;
1251
1252 if (v > 0xff) {
1253 ret = obj_reloc_overflow;
1254 }
1255
1256 word = *loc & ~0x3fc0;
1257 *loc = word | ((v & 0xff) << 6);
1258 }
1259 break;
1260
1261 case R_NIOS2_HI16:
1262 {
1263 Elf32_Addr word;
1264
1265 word = *loc;
1266 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1267 (word & 0x3f);
1268 }
1269 break;
1270
1271 case R_NIOS2_LO16:
1272 {
1273 Elf32_Addr word;
1274
1275 word = *loc;
1276 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1277 (word & 0x3f);
1278 }
1279 break;
1280
1281 case R_NIOS2_HIADJ16:
1282 {
1283 Elf32_Addr word1, word2;
1284
1285 word1 = *loc;
1286 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1287 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1288 (word1 & 0x3f);
1289 }
1290 break;
1291
1292#elif defined(__powerpc64__)
1293 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
1294
1295#elif defined(__powerpc__)
1296
1297 case R_PPC_ADDR16_HA:
1298 *(unsigned short *)loc = (v + 0x8000) >> 16;
1299 break;
1300
1301 case R_PPC_ADDR16_HI:
1302 *(unsigned short *)loc = v >> 16;
1303 break;
1304
1305 case R_PPC_ADDR16_LO:
1306 *(unsigned short *)loc = v;
1307 break;
1308
1309 case R_PPC_REL24:
1310 goto bb_use_plt;
1311
1312 case R_PPC_REL32:
1313 *loc = v - dot;
1314 break;
1315
1316 case R_PPC_ADDR32:
1317 *loc = v;
1318 break;
1319
1320#elif defined(__s390__)
1321
1322 case R_390_32:
1323 *(unsigned int *) loc += v;
1324 break;
1325 case R_390_16:
1326 *(unsigned short *) loc += v;
1327 break;
1328 case R_390_8:
1329 *(unsigned char *) loc += v;
1330 break;
1331
1332 case R_390_PC32:
1333 *(unsigned int *) loc += v - dot;
1334 break;
1335 case R_390_PC16DBL:
1336 *(unsigned short *) loc += (v - dot) >> 1;
1337 break;
1338 case R_390_PC16:
1339 *(unsigned short *) loc += v - dot;
1340 break;
1341
1342 case R_390_PLT32:
1343 case R_390_PLT16DBL:
1344 /* find the plt entry and initialize it. */
1345 pe = (struct arch_single_entry *) &isym->pltent;
1346 if (pe->inited == 0) {
1347 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1348 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1349 ip[1] = 0x100607f1;
1350 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1351 ip[2] = v - 2;
1352 else
1353 ip[2] = v;
1354 pe->inited = 1;
1355 }
1356
1357 /* Insert relative distance to target. */
1358 v = plt + pe->offset - dot;
1359 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1360 *(unsigned int *) loc = (unsigned int) v;
1361 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1362 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1363 break;
1364
1365 case R_390_GLOB_DAT:
1366 case R_390_JMP_SLOT:
1367 *loc = v;
1368 break;
1369
1370 case R_390_RELATIVE:
1371 *loc += f->baseaddr;
1372 break;
1373
1374 case R_390_GOTPC:
1375 *(unsigned long *) loc += got - dot;
1376 break;
1377
1378 case R_390_GOT12:
1379 case R_390_GOT16:
1380 case R_390_GOT32:
1381 if (!isym->gotent.inited)
1382 {
1383 isym->gotent.inited = 1;
1384 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1385 }
1386 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1387 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1388 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1389 *(unsigned short *) loc += isym->gotent.offset;
1390 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1391 *(unsigned int *) loc += isym->gotent.offset;
1392 break;
1393
1394# ifndef R_390_GOTOFF32
1395# define R_390_GOTOFF32 R_390_GOTOFF
1396# endif
1397 case R_390_GOTOFF32:
1398 *loc += v - got;
1399 break;
1400
1401#elif defined(__sh__)
1402
1403 case R_SH_NONE:
1404 break;
1405
1406 case R_SH_DIR32:
1407 *loc += v;
1408 break;
1409
1410 case R_SH_REL32:
1411 *loc += v - dot;
1412 break;
1413
1414 case R_SH_PLT32:
1415 *loc = v - dot;
1416 break;
1417
1418 case R_SH_GLOB_DAT:
1419 case R_SH_JMP_SLOT:
1420 *loc = v;
1421 break;
1422
1423 case R_SH_RELATIVE:
1424 *loc = f->baseaddr + rel->r_addend;
1425 break;
1426
1427 case R_SH_GOTPC:
1428 *loc = got - dot + rel->r_addend;
1429 break;
1430
1431 case R_SH_GOT32:
1432 goto bb_use_got;
1433
1434 case R_SH_GOTOFF:
1435 *loc = v - got;
1436 break;
1437
1438# if defined(__SH5__)
1439 case R_SH_IMM_MEDLOW16:
1440 case R_SH_IMM_LOW16:
1441 {
1442 ElfW(Addr) word;
1443
1444 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1445 v >>= 16;
1446
1447 /*
1448 * movi and shori have the format:
1449 *
1450 * | op | imm | reg | reserved |
1451 * 31..26 25..10 9.. 4 3 .. 0
1452 *
1453 * so we simply mask and or in imm.
1454 */
1455 word = *loc & ~0x3fffc00;
1456 word |= (v & 0xffff) << 10;
1457
1458 *loc = word;
1459
1460 break;
1461 }
1462
1463 case R_SH_IMM_MEDLOW16_PCREL:
1464 case R_SH_IMM_LOW16_PCREL:
1465 {
1466 ElfW(Addr) word;
1467
1468 word = *loc & ~0x3fffc00;
1469
1470 v -= dot;
1471
1472 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1473 v >>= 16;
1474
1475 word |= (v & 0xffff) << 10;
1476
1477 *loc = word;
1478
1479 break;
1480 }
1481# endif /* __SH5__ */
1482
1483#elif defined(__v850e__)
1484
1485 case R_V850_NONE:
1486 break;
1487
1488 case R_V850_32:
1489 /* We write two shorts instead of a long because even
1490 32-bit insns only need half-word alignment, but
1491 32-bit data needs to be long-word aligned. */
1492 v += ((unsigned short *)loc)[0];
1493 v += ((unsigned short *)loc)[1] << 16;
1494 ((unsigned short *)loc)[0] = v & 0xffff;
1495 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1496 break;
1497
1498 case R_V850_22_PCREL:
1499 goto bb_use_plt;
1500
1501#elif defined(__x86_64__)
1502
1503 case R_X86_64_NONE:
1504 break;
1505
1506 case R_X86_64_64:
1507 *loc += v;
1508 break;
1509
1510 case R_X86_64_32:
1511 *(unsigned int *) loc += v;
1512 if (v > 0xffffffff)
1513 {
1514 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1515 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1516 }
1517 break;
1518
1519 case R_X86_64_32S:
1520 *(signed int *) loc += v;
1521 break;
1522
1523 case R_X86_64_16:
1524 *(unsigned short *) loc += v;
1525 break;
1526
1527 case R_X86_64_8:
1528 *(unsigned char *) loc += v;
1529 break;
1530
1531 case R_X86_64_PC32:
1532 *(unsigned int *) loc += v - dot;
1533 break;
1534
1535 case R_X86_64_PC16:
1536 *(unsigned short *) loc += v - dot;
1537 break;
1538
1539 case R_X86_64_PC8:
1540 *(unsigned char *) loc += v - dot;
1541 break;
1542
1543 case R_X86_64_GLOB_DAT:
1544 case R_X86_64_JUMP_SLOT:
1545 *loc = v;
1546 break;
1547
1548 case R_X86_64_RELATIVE:
1549 *loc += f->baseaddr;
1550 break;
1551
1552 case R_X86_64_GOT32:
1553 case R_X86_64_GOTPCREL:
1554 goto bb_use_got;
1555# if 0
1556 if (!isym->gotent.reloc_done)
1557 {
1558 isym->gotent.reloc_done = 1;
1559 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1560 }
1561 /* XXX are these really correct? */
1562 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1563 *(unsigned int *) loc += v + isym->gotent.offset;
1564 else
1565 *loc += isym->gotent.offset;
1566 break;
1567# endif
1568
1569#else
1570# warning "no idea how to handle relocations on your arch"
1571#endif
1572
1573 default:
1574 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1575 ret = obj_reloc_unhandled;
1576 break;
1577
1578#if defined(USE_PLT_ENTRIES)
1579
1580bb_use_plt:
1581
1582 /* find the plt entry and initialize it if necessary */
1583
1584#if defined(USE_PLT_LIST)
1585 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1586 pe = pe->next;
1587#else
1588 pe = &isym->pltent;
1589#endif
1590
1591 if (! pe->inited) {
1592 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1593
1594 /* generate some machine code */
1595
1596#if defined(__arm__)
1597 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1598 ip[1] = v; /* sym@ */
1599#endif
1600#if defined(__powerpc__)
1601 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1602 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1603 ip[2] = 0x7d6903a6; /* mtctr r11 */
1604 ip[3] = 0x4e800420; /* bctr */
1605#endif
1606#if defined(__v850e__)
1607 /* We have to trash a register, so we assume that any control
1608 transfer more than 21-bits away must be a function call
1609 (so we can use a call-clobbered register). */
1610 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1611 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
1612#endif
1613 pe->inited = 1;
1614 }
1615
1616 /* relative distance to target */
1617 v -= dot;
1618 /* if the target is too far away.... */
1619#if defined(__arm__) || defined(__powerpc__)
1620 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1621#elif defined(__v850e__)
1622 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1623#endif
1624 /* go via the plt */
1625 v = plt + pe->offset - dot;
1626
1627#if defined(__v850e__)
1628 if (v & 1)
1629#else
1630 if (v & 3)
1631#endif
1632 ret = obj_reloc_dangerous;
1633
1634 /* merge the offset into the instruction. */
1635#if defined(__arm__)
1636 /* Convert to words. */
1637 v >>= 2;
1638
1639 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1640#endif
1641#if defined(__powerpc__)
1642 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1643#endif
1644#if defined(__v850e__)
1645 /* We write two shorts instead of a long because even 32-bit insns
1646 only need half-word alignment, but the 32-bit data write needs
1647 to be long-word aligned. */
1648 ((unsigned short *)loc)[0] =
1649 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1650 | ((v >> 16) & 0x3f); /* offs high part */
1651 ((unsigned short *)loc)[1] =
1652 (v & 0xffff); /* offs low part */
1653#endif
1654 break;
1655#endif /* USE_PLT_ENTRIES */
1656
1657#if defined(USE_GOT_ENTRIES)
1658bb_use_got:
1659
1660 /* needs an entry in the .got: set it, once */
1661 if (!isym->gotent.inited) {
1662 isym->gotent.inited = 1;
1663 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1664 }
1665 /* make the reloc with_respect_to_.got */
1666#if defined(__sh__)
1667 *loc += isym->gotent.offset + rel->r_addend;
1668#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1669 *loc += isym->gotent.offset;
1670#endif
1671 break;
1672
1673#endif /* USE_GOT_ENTRIES */
1674 }
1675
1676 return ret;
1677}
1678
1679
1680#if defined(USE_LIST)
1681
1682static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1683 int offset, int size)
1684{
1685 struct arch_list_entry *pe;
1686
1687 for (pe = *list; pe != NULL; pe = pe->next) {
1688 if (pe->addend == rel->r_addend) {
1689 break;
1690 }
1691 }
1692
1693 if (pe == NULL) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001694 pe = xzalloc(sizeof(struct arch_list_entry));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001695 pe->next = *list;
1696 pe->addend = rel->r_addend;
1697 pe->offset = offset;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001698 /*pe->inited = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001699 *list = pe;
1700 return size;
1701 }
1702 return 0;
1703}
1704
1705#endif
1706
1707#if defined(USE_SINGLE)
1708
1709static int arch_single_init(/*ElfW(RelM) *rel,*/ struct arch_single_entry *single,
1710 int offset, int size)
1711{
1712 if (single->allocated == 0) {
1713 single->allocated = 1;
1714 single->offset = offset;
1715 single->inited = 0;
1716 return size;
1717 }
1718 return 0;
1719}
1720
1721#endif
1722
1723#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1724
1725static struct obj_section *arch_xsect_init(struct obj_file *f, const char *name,
1726 int offset, int size)
1727{
1728 struct obj_section *myrelsec = obj_find_section(f, name);
1729
1730 if (offset == 0) {
1731 offset += size;
1732 }
1733
1734 if (myrelsec) {
1735 obj_extend_section(myrelsec, offset);
1736 } else {
1737 myrelsec = obj_create_alloced_section(f, name,
1738 size, offset);
1739 }
1740
1741 return myrelsec;
1742}
1743
1744#endif
1745
1746static void arch_create_got(struct obj_file *f)
1747{
1748#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1749 struct arch_file *ifile = (struct arch_file *) f;
1750 int i;
1751#if defined(USE_GOT_ENTRIES)
1752 int got_offset = 0, got_needed = 0, got_allocate;
1753#endif
1754#if defined(USE_PLT_ENTRIES)
1755 int plt_offset = 0, plt_needed = 0, plt_allocate;
1756#endif
1757 struct obj_section *relsec, *symsec, *strsec;
1758 ElfW(RelM) *rel, *relend;
1759 ElfW(Sym) *symtab, *extsym;
1760 const char *strtab, *name;
1761 struct arch_symbol *intsym;
1762
1763 for (i = 0; i < f->header.e_shnum; ++i) {
1764 relsec = f->sections[i];
1765 if (relsec->header.sh_type != SHT_RELM)
1766 continue;
1767
1768 symsec = f->sections[relsec->header.sh_link];
1769 strsec = f->sections[symsec->header.sh_link];
1770
1771 rel = (ElfW(RelM) *) relsec->contents;
1772 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1773 symtab = (ElfW(Sym) *) symsec->contents;
1774 strtab = (const char *) strsec->contents;
1775
1776 for (; rel < relend; ++rel) {
1777 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1778
1779#if defined(USE_GOT_ENTRIES)
1780 got_allocate = 0;
1781#endif
1782#if defined(USE_PLT_ENTRIES)
1783 plt_allocate = 0;
1784#endif
1785
1786 switch (ELF_R_TYPE(rel->r_info)) {
1787#if defined(__arm__)
1788 case R_ARM_PC24:
1789 case R_ARM_PLT32:
1790 plt_allocate = 1;
1791 break;
1792
1793 case R_ARM_GOTOFF:
1794 case R_ARM_GOTPC:
1795 got_needed = 1;
1796 continue;
1797
1798 case R_ARM_GOT32:
1799 got_allocate = 1;
1800 break;
1801
1802#elif defined(__i386__)
1803 case R_386_GOTPC:
1804 case R_386_GOTOFF:
1805 got_needed = 1;
1806 continue;
1807
1808 case R_386_GOT32:
1809 got_allocate = 1;
1810 break;
1811
1812#elif defined(__powerpc__)
1813 case R_PPC_REL24:
1814 plt_allocate = 1;
1815 break;
1816
1817#elif defined(__mc68000__)
1818 case R_68K_GOT32:
1819 got_allocate = 1;
1820 break;
1821
1822#ifdef R_68K_GOTOFF
1823 case R_68K_GOTOFF:
1824 got_needed = 1;
1825 continue;
1826#endif
1827
1828#elif defined(__sh__)
1829 case R_SH_GOT32:
1830 got_allocate = 1;
1831 break;
1832
1833 case R_SH_GOTPC:
1834 case R_SH_GOTOFF:
1835 got_needed = 1;
1836 continue;
1837
1838#elif defined(__v850e__)
1839 case R_V850_22_PCREL:
1840 plt_needed = 1;
1841 break;
1842
1843#endif
1844 default:
1845 continue;
1846 }
1847
1848 if (extsym->st_name != 0) {
1849 name = strtab + extsym->st_name;
1850 } else {
1851 name = f->sections[extsym->st_shndx]->name;
1852 }
1853 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1854#if defined(USE_GOT_ENTRIES)
1855 if (got_allocate) {
1856 got_offset += arch_single_init(
1857 /*rel,*/ &intsym->gotent,
1858 got_offset, GOT_ENTRY_SIZE);
1859
1860 got_needed = 1;
1861 }
1862#endif
1863#if defined(USE_PLT_ENTRIES)
1864 if (plt_allocate) {
1865#if defined(USE_PLT_LIST)
1866 plt_offset += arch_list_add(
1867 rel, &intsym->pltent,
1868 plt_offset, PLT_ENTRY_SIZE);
1869#else
1870 plt_offset += arch_single_init(
1871 /*rel,*/ &intsym->pltent,
1872 plt_offset, PLT_ENTRY_SIZE);
1873#endif
1874 plt_needed = 1;
1875 }
1876#endif
1877 }
1878 }
1879
1880#if defined(USE_GOT_ENTRIES)
1881 if (got_needed) {
1882 ifile->got = arch_xsect_init(f, ".got", got_offset,
1883 GOT_ENTRY_SIZE);
1884 }
1885#endif
1886
1887#if defined(USE_PLT_ENTRIES)
1888 if (plt_needed) {
1889 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1890 PLT_ENTRY_SIZE);
1891 }
1892#endif
1893
1894#endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */
1895}
1896
1897/*======================================================================*/
1898
1899/* Standard ELF hash function. */
1900static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1901{
1902 unsigned long h = 0;
1903 unsigned long g;
1904 unsigned char ch;
1905
1906 while (n > 0) {
1907 ch = *name++;
1908 h = (h << 4) + ch;
1909 g = (h & 0xf0000000);
1910 if (g != 0) {
1911 h ^= g >> 24;
1912 h &= ~g;
1913 }
1914 n--;
1915 }
1916 return h;
1917}
1918
1919static unsigned long obj_elf_hash(const char *name)
1920{
1921 return obj_elf_hash_n(name, strlen(name));
1922}
1923
1924#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
1925/* String comparison for non-co-versioned kernel and module. */
1926
1927static int ncv_strcmp(const char *a, const char *b)
1928{
1929 size_t alen = strlen(a), blen = strlen(b);
1930
1931 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1932 return strncmp(a, b, alen);
1933 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1934 return strncmp(a, b, blen);
1935 else
1936 return strcmp(a, b);
1937}
1938
1939/* String hashing for non-co-versioned kernel and module. Here
1940 we are simply forced to drop the crc from the hash. */
1941
1942static unsigned long ncv_symbol_hash(const char *str)
1943{
1944 size_t len = strlen(str);
1945 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1946 len -= 10;
1947 return obj_elf_hash_n(str, len);
1948}
1949
1950static void
1951obj_set_symbol_compare(struct obj_file *f,
1952 int (*cmp) (const char *, const char *),
1953 unsigned long (*hash) (const char *))
1954{
1955 if (cmp)
1956 f->symbol_cmp = cmp;
1957 if (hash) {
1958 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1959 int i;
1960
1961 f->symbol_hash = hash;
1962
1963 memcpy(tmptab, f->symtab, sizeof(tmptab));
1964 memset(f->symtab, 0, sizeof(f->symtab));
1965
1966 for (i = 0; i < HASH_BUCKETS; ++i)
1967 for (sym = tmptab[i]; sym; sym = next) {
1968 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1969 next = sym->next;
1970 sym->next = f->symtab[h];
1971 f->symtab[h] = sym;
1972 }
1973 }
1974}
1975
1976#endif /* FEATURE_INSMOD_VERSION_CHECKING */
1977
1978static struct obj_symbol *
1979obj_add_symbol(struct obj_file *f, const char *name,
1980 unsigned long symidx, int info,
1981 int secidx, ElfW(Addr) value,
1982 unsigned long size)
1983{
1984 struct obj_symbol *sym;
1985 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1986 int n_type = ELF_ST_TYPE(info);
1987 int n_binding = ELF_ST_BIND(info);
1988
1989 for (sym = f->symtab[hash]; sym; sym = sym->next) {
1990 if (f->symbol_cmp(sym->name, name) == 0) {
1991 int o_secidx = sym->secidx;
1992 int o_info = sym->info;
1993 int o_type = ELF_ST_TYPE(o_info);
1994 int o_binding = ELF_ST_BIND(o_info);
1995
1996 /* A redefinition! Is it legal? */
1997
1998 if (secidx == SHN_UNDEF)
1999 return sym;
2000 else if (o_secidx == SHN_UNDEF)
2001 goto found;
2002 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2003 /* Cope with local and global symbols of the same name
2004 in the same object file, as might have been created
2005 by ld -r. The only reason locals are now seen at this
2006 level at all is so that we can do semi-sensible things
2007 with parameters. */
2008
2009 struct obj_symbol *nsym, **p;
2010
2011 nsym = arch_new_symbol();
2012 nsym->next = sym->next;
2013 nsym->ksymidx = -1;
2014
2015 /* Excise the old (local) symbol from the hash chain. */
2016 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2017 continue;
2018 *p = sym = nsym;
2019 goto found;
2020 } else if (n_binding == STB_LOCAL) {
2021 /* Another symbol of the same name has already been defined.
2022 Just add this to the local table. */
2023 sym = arch_new_symbol();
2024 sym->next = NULL;
2025 sym->ksymidx = -1;
2026 f->local_symtab[symidx] = sym;
2027 goto found;
2028 } else if (n_binding == STB_WEAK)
2029 return sym;
2030 else if (o_binding == STB_WEAK)
2031 goto found;
2032 /* Don't unify COMMON symbols with object types the programmer
2033 doesn't expect. */
2034 else if (secidx == SHN_COMMON
2035 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2036 return sym;
2037 else if (o_secidx == SHN_COMMON
2038 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2039 goto found;
2040 else {
2041 /* Don't report an error if the symbol is coming from
2042 the kernel or some external module. */
2043 if (secidx <= SHN_HIRESERVE)
2044 bb_error_msg("%s multiply defined", name);
2045 return sym;
2046 }
2047 }
2048 }
2049
2050 /* Completely new symbol. */
2051 sym = arch_new_symbol();
2052 sym->next = f->symtab[hash];
2053 f->symtab[hash] = sym;
2054 sym->ksymidx = -1;
2055 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
2056 if (symidx >= f->local_symtab_size)
2057 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2058 name, (long) symidx, (long) f->local_symtab_size);
2059 else
2060 f->local_symtab[symidx] = sym;
2061 }
2062
2063found:
2064 sym->name = name;
2065 sym->value = value;
2066 sym->size = size;
2067 sym->secidx = secidx;
2068 sym->info = info;
2069
2070 return sym;
2071}
2072
2073static struct obj_symbol *
2074obj_find_symbol(struct obj_file *f, const char *name)
2075{
2076 struct obj_symbol *sym;
2077 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2078
2079 for (sym = f->symtab[hash]; sym; sym = sym->next)
2080 if (f->symbol_cmp(sym->name, name) == 0)
2081 return sym;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002082 return NULL;
2083}
2084
2085static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2086{
2087 if (sym) {
2088 if (sym->secidx >= SHN_LORESERVE)
2089 return sym->value;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002090 return sym->value + f->sections[sym->secidx]->header.sh_addr;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002091 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002092 /* As a special case, a NULL sym has value zero. */
2093 return 0;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002094}
2095
2096static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2097{
2098 int i, n = f->header.e_shnum;
2099
2100 for (i = 0; i < n; ++i)
2101 if (strcmp(f->sections[i]->name, name) == 0)
2102 return f->sections[i];
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002103 return NULL;
2104}
2105
2106static int obj_load_order_prio(struct obj_section *a)
2107{
2108 unsigned long af, ac;
2109
2110 af = a->header.sh_flags;
2111
2112 ac = 0;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002113 if (a->name[0] != '.' || strlen(a->name) != 10
2114 || strcmp(a->name + 5, ".init") != 0
2115 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002116 ac |= 32;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002117 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002118 if (af & SHF_ALLOC)
2119 ac |= 16;
2120 if (!(af & SHF_WRITE))
2121 ac |= 8;
2122 if (af & SHF_EXECINSTR)
2123 ac |= 4;
2124 if (a->header.sh_type != SHT_NOBITS)
2125 ac |= 2;
2126
2127 return ac;
2128}
2129
2130static void
2131obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2132{
2133 struct obj_section **p;
2134 int prio = obj_load_order_prio(sec);
2135 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2136 if (obj_load_order_prio(*p) < prio)
2137 break;
2138 sec->load_next = *p;
2139 *p = sec;
2140}
2141
Denis Vlasenko49325962009-01-31 23:33:54 +00002142static struct obj_section *helper_create_alloced_section(struct obj_file *f,
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002143 const char *name,
2144 unsigned long align,
2145 unsigned long size)
2146{
2147 int newidx = f->header.e_shnum++;
2148 struct obj_section *sec;
2149
2150 f->sections = xrealloc_vector(f->sections, 2, newidx);
2151 f->sections[newidx] = sec = arch_new_section();
2152
2153 sec->header.sh_type = SHT_PROGBITS;
2154 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2155 sec->header.sh_size = size;
2156 sec->header.sh_addralign = align;
2157 sec->name = name;
2158 sec->idx = newidx;
2159 if (size)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002160 sec->contents = xzalloc(size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002161
Denis Vlasenko49325962009-01-31 23:33:54 +00002162 return sec;
2163}
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002164
Denis Vlasenko49325962009-01-31 23:33:54 +00002165static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2166 const char *name,
2167 unsigned long align,
2168 unsigned long size)
2169{
2170 struct obj_section *sec;
2171
2172 sec = helper_create_alloced_section(f, name, align, size);
2173 obj_insert_section_load_order(f, sec);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002174 return sec;
2175}
2176
2177static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2178 const char *name,
2179 unsigned long align,
2180 unsigned long size)
2181{
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002182 struct obj_section *sec;
2183
Denis Vlasenko49325962009-01-31 23:33:54 +00002184 sec = helper_create_alloced_section(f, name, align, size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002185 sec->load_next = f->load_order;
2186 f->load_order = sec;
2187 if (f->load_order_search_start == &f->load_order)
2188 f->load_order_search_start = &sec->load_next;
2189
2190 return sec;
2191}
2192
2193static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2194{
2195 unsigned long oldsize = sec->header.sh_size;
2196 if (more) {
2197 sec->header.sh_size += more;
2198 sec->contents = xrealloc(sec->contents, sec->header.sh_size);
2199 }
2200 return sec->contents + oldsize;
2201}
2202
2203
2204/* Conditionally add the symbols from the given symbol set to the
2205 new module. */
2206
Denis Vlasenko49325962009-01-31 23:33:54 +00002207static int add_symbols_from(struct obj_file *f,
2208 int idx,
2209 struct new_module_symbol *syms,
2210 size_t nsyms)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002211{
2212 struct new_module_symbol *s;
2213 size_t i;
2214 int used = 0;
2215#ifdef SYMBOL_PREFIX
Denis Vlasenko49325962009-01-31 23:33:54 +00002216 char *name_buf = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002217 size_t name_alloced_size = 0;
2218#endif
2219#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2220 int gpl;
2221
2222 gpl = obj_gpl_license(f, NULL) == 0;
2223#endif
2224 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2225 /* Only add symbols that are already marked external.
2226 If we override locals we may cause problems for
2227 argument initialization. We will also create a false
2228 dependency on the module. */
2229 struct obj_symbol *sym;
2230 char *name;
2231
2232 /* GPL licensed modules can use symbols exported with
2233 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2234 * exported names. Non-GPL modules never see any GPLONLY_
2235 * symbols so they cannot fudge it by adding the prefix on
2236 * their references.
2237 */
2238 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2239#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2240 if (gpl)
2241 s->name += 8;
2242 else
2243#endif
2244 continue;
2245 }
2246 name = (char *)s->name;
2247
2248#ifdef SYMBOL_PREFIX
2249 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2250 kernel exports `C names', but module object files
2251 reference `linker names'). */
2252 size_t extra = sizeof SYMBOL_PREFIX;
2253 size_t name_size = strlen(name) + extra;
2254 if (name_size > name_alloced_size) {
2255 name_alloced_size = name_size * 2;
2256 name_buf = alloca(name_alloced_size);
2257 }
2258 strcpy(name_buf, SYMBOL_PREFIX);
2259 strcpy(name_buf + extra - 1, name);
2260 name = name_buf;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002261#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002262
2263 sym = obj_find_symbol(f, name);
2264 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2265#ifdef SYMBOL_PREFIX
2266 /* Put NAME_BUF into more permanent storage. */
2267 name = xmalloc(name_size);
2268 strcpy(name, name_buf);
2269#endif
2270 sym = obj_add_symbol(f, name, -1,
2271 ELF_ST_INFO(STB_GLOBAL,
2272 STT_NOTYPE),
2273 idx, s->value, 0);
2274 /* Did our symbol just get installed? If so, mark the
2275 module as "used". */
2276 if (sym->secidx == idx)
2277 used = 1;
2278 }
2279 }
2280
2281 return used;
2282}
2283
2284static void add_kernel_symbols(struct obj_file *f)
2285{
2286 struct external_module *m;
2287 int i, nused = 0;
2288
2289 /* Add module symbols first. */
2290
2291 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) {
2292 if (m->nsyms
2293 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms)
2294 ) {
2295 m->used = 1;
2296 ++nused;
2297 }
2298 }
2299
2300 n_ext_modules_used = nused;
2301
2302 /* And finally the symbols from the kernel proper. */
2303
2304 if (nksyms)
2305 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2306}
2307
2308static char *get_modinfo_value(struct obj_file *f, const char *key)
2309{
2310 struct obj_section *sec;
2311 char *p, *v, *n, *ep;
2312 size_t klen = strlen(key);
2313
2314 sec = obj_find_section(f, ".modinfo");
2315 if (sec == NULL)
2316 return NULL;
2317 p = sec->contents;
2318 ep = p + sec->header.sh_size;
2319 while (p < ep) {
2320 v = strchr(p, '=');
2321 n = strchr(p, '\0');
2322 if (v) {
2323 if (p + klen == v && strncmp(p, key, klen) == 0)
2324 return v + 1;
2325 } else {
2326 if (p + klen == n && strcmp(p, key) == 0)
2327 return n;
2328 }
2329 p = n + 1;
2330 }
2331
2332 return NULL;
2333}
2334
2335
2336/*======================================================================*/
2337/* Functions relating to module loading after 2.1.18. */
2338
2339/* From Linux-2.6 sources */
2340/* You can use " around spaces, but can't escape ". */
2341/* Hyphens and underscores equivalent in parameter names. */
2342static char *next_arg(char *args, char **param, char **val)
2343{
2344 unsigned int i, equals = 0;
2345 int in_quote = 0, quoted = 0;
2346 char *next;
2347
2348 if (*args == '"') {
2349 args++;
2350 in_quote = 1;
2351 quoted = 1;
2352 }
2353
2354 for (i = 0; args[i]; i++) {
2355 if (args[i] == ' ' && !in_quote)
2356 break;
2357 if (equals == 0) {
2358 if (args[i] == '=')
2359 equals = i;
2360 }
2361 if (args[i] == '"')
2362 in_quote = !in_quote;
2363 }
2364
2365 *param = args;
2366 if (!equals)
2367 *val = NULL;
2368 else {
2369 args[equals] = '\0';
2370 *val = args + equals + 1;
2371
2372 /* Don't include quotes in value. */
2373 if (**val == '"') {
2374 (*val)++;
2375 if (args[i-1] == '"')
2376 args[i-1] = '\0';
2377 }
2378 if (quoted && args[i-1] == '"')
2379 args[i-1] = '\0';
2380 }
2381
2382 if (args[i]) {
2383 args[i] = '\0';
2384 next = args + i + 1;
2385 } else
2386 next = args + i;
2387
2388 /* Chew up trailing spaces. */
2389 return skip_whitespace(next);
2390}
2391
2392static void
2393new_process_module_arguments(struct obj_file *f, const char *options)
2394{
2395 char *xoptions, *pos;
2396 char *param, *val;
2397
2398 xoptions = pos = xstrdup(skip_whitespace(options));
2399 while (*pos) {
2400 unsigned long charssize = 0;
2401 char *tmp, *contents, *loc, *pinfo, *p;
2402 struct obj_symbol *sym;
2403 int min, max, n, len;
2404
2405 pos = next_arg(pos, &param, &val);
2406
2407 tmp = xasprintf("parm_%s", param);
2408 pinfo = get_modinfo_value(f, tmp);
2409 free(tmp);
2410 if (pinfo == NULL)
2411 bb_error_msg_and_die("invalid parameter %s", param);
2412
2413#ifdef SYMBOL_PREFIX
2414 tmp = xasprintf(SYMBOL_PREFIX "%s", param);
2415 sym = obj_find_symbol(f, tmp);
2416 free(tmp);
2417#else
2418 sym = obj_find_symbol(f, param);
2419#endif
2420
2421 /* Also check that the parameter was not resolved from the kernel. */
2422 if (sym == NULL || sym->secidx > SHN_HIRESERVE)
2423 bb_error_msg_and_die("symbol for parameter %s not found", param);
2424
2425 /* Number of parameters */
2426 if (isdigit(*pinfo)) {
2427 min = strtoul(pinfo, &pinfo, 10);
2428 if (*pinfo == '-')
2429 max = strtoul(pinfo + 1, &pinfo, 10);
2430 else
2431 max = min;
2432 } else
2433 min = max = 1;
2434
2435 contents = f->sections[sym->secidx]->contents;
2436 loc = contents + sym->value;
2437
2438 if (*pinfo == 'c') {
2439 if (!isdigit(*(pinfo + 1))) {
2440 bb_error_msg_and_die("parameter type 'c' for %s must be followed by"
2441 " the maximum size", param);
2442 }
2443 charssize = strtoul(pinfo + 1, (char **) NULL, 10);
2444 }
2445
2446 if (val == NULL) {
2447 if (*pinfo != 'b')
2448 bb_error_msg_and_die("argument expected for parameter %s", param);
2449 val = (char *) "1";
2450 }
2451
2452 /* Parse parameter values */
2453 n = 0;
2454 p = val;
2455 while (*p != 0) {
2456 if (++n > max)
2457 bb_error_msg_and_die("too many values for %s (max %d)", param, max);
2458
2459 switch (*pinfo) {
2460 case 's':
2461 len = strcspn(p, ",");
2462 p[len] = 0;
2463 obj_string_patch(f, sym->secidx,
2464 loc - contents, p);
2465 loc += tgt_sizeof_char_p;
2466 p += len;
2467 break;
2468 case 'c':
2469 len = strcspn(p, ",");
2470 p[len] = 0;
2471 if (len >= charssize)
2472 bb_error_msg_and_die("string too long for %s (max %ld)", param,
2473 charssize - 1);
2474 strcpy((char *) loc, p);
2475 loc += charssize;
2476 p += len;
2477 break;
2478 case 'b':
2479 *loc++ = strtoul(p, &p, 0);
2480 break;
2481 case 'h':
2482 *(short *) loc = strtoul(p, &p, 0);
2483 loc += tgt_sizeof_short;
2484 break;
2485 case 'i':
2486 *(int *) loc = strtoul(p, &p, 0);
2487 loc += tgt_sizeof_int;
2488 break;
2489 case 'l':
2490 *(long *) loc = strtoul(p, &p, 0);
2491 loc += tgt_sizeof_long;
2492 break;
2493 default:
2494 bb_error_msg_and_die("unknown parameter type '%c' for %s",
2495 *pinfo, param);
2496 }
2497
2498 p = skip_whitespace(p);
2499 if (*p != ',')
2500 break;
2501 p = skip_whitespace(p + 1);
2502 }
2503
2504 if (n < min)
2505 bb_error_msg_and_die("parameter %s requires at least %d arguments", param, min);
2506 if (*p != '\0')
2507 bb_error_msg_and_die("invalid argument syntax for %s", param);
2508 }
2509
2510 free(xoptions);
2511}
2512
2513#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
2514static int new_is_module_checksummed(struct obj_file *f)
2515{
2516 const char *p = get_modinfo_value(f, "using_checksums");
2517 if (p)
2518 return xatoi(p);
2519 return 0;
2520}
2521
2522/* Get the module's kernel version in the canonical integer form. */
2523
2524static int
2525new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2526{
2527 char *p, *q;
2528 int a, b, c;
2529
2530 p = get_modinfo_value(f, "kernel_version");
2531 if (p == NULL)
2532 return -1;
2533 safe_strncpy(str, p, STRVERSIONLEN);
2534
2535 a = strtoul(p, &p, 10);
2536 if (*p != '.')
2537 return -1;
2538 b = strtoul(p + 1, &p, 10);
2539 if (*p != '.')
2540 return -1;
2541 c = strtoul(p + 1, &q, 10);
2542 if (p + 1 == q)
2543 return -1;
2544
2545 return a << 16 | b << 8 | c;
2546}
2547
2548#endif /* FEATURE_INSMOD_VERSION_CHECKING */
2549
2550
2551/* Fetch the loaded modules, and all currently exported symbols. */
2552
2553static void new_get_kernel_symbols(void)
2554{
2555 char *module_names, *mn;
2556 struct external_module *modules, *m;
2557 struct new_module_symbol *syms, *s;
2558 size_t ret, bufsize, nmod, nsyms, i, j;
2559
2560 /* Collect the loaded modules. */
2561
2562 bufsize = 256;
2563 module_names = xmalloc(bufsize);
2564
2565 retry_modules_load:
2566 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2567 if (errno == ENOSPC && bufsize < ret) {
2568 bufsize = ret;
2569 module_names = xrealloc(module_names, bufsize);
2570 goto retry_modules_load;
2571 }
2572 bb_perror_msg_and_die("QM_MODULES");
2573 }
2574
2575 n_ext_modules = nmod = ret;
2576
2577 /* Collect the modules' symbols. */
2578
2579 if (nmod) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002580 ext_modules = modules = xzalloc(nmod * sizeof(*modules));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002581 for (i = 0, mn = module_names, m = modules;
2582 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2583 struct new_module_info info;
2584
2585 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2586 if (errno == ENOENT) {
2587 /* The module was removed out from underneath us. */
2588 continue;
2589 }
2590 bb_perror_msg_and_die("query_module: QM_INFO: %s", mn);
2591 }
2592
2593 bufsize = 1024;
2594 syms = xmalloc(bufsize);
2595 retry_mod_sym_load:
2596 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2597 switch (errno) {
2598 case ENOSPC:
2599 bufsize = ret;
2600 syms = xrealloc(syms, bufsize);
2601 goto retry_mod_sym_load;
2602 case ENOENT:
2603 /* The module was removed out from underneath us. */
2604 continue;
2605 default:
2606 bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn);
2607 }
2608 }
2609 nsyms = ret;
2610
2611 m->name = mn;
2612 m->addr = info.addr;
2613 m->nsyms = nsyms;
2614 m->syms = syms;
2615
2616 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2617 s->name += (unsigned long) syms;
2618 }
2619 }
2620 }
2621
2622 /* Collect the kernel's symbols. */
2623
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002624 bufsize = 16 * 1024;
2625 syms = xmalloc(bufsize);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002626 retry_kern_sym_load:
2627 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2628 if (errno == ENOSPC && bufsize < ret) {
2629 bufsize = ret;
2630 syms = xrealloc(syms, bufsize);
2631 goto retry_kern_sym_load;
2632 }
2633 bb_perror_msg_and_die("kernel: QM_SYMBOLS");
2634 }
2635 nksyms = nsyms = ret;
2636 ksyms = syms;
2637
2638 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2639 s->name += (unsigned long) syms;
2640 }
2641}
2642
2643
2644/* Return the kernel symbol checksum version, or zero if not used. */
2645
2646static int new_is_kernel_checksummed(void)
2647{
2648 struct new_module_symbol *s;
2649 size_t i;
2650
2651 /* Using_Versions is not the first symbol, but it should be in there. */
2652
2653 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2654 if (strcmp((char *) s->name, "Using_Versions") == 0)
2655 return s->value;
2656
2657 return 0;
2658}
2659
2660
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002661static void new_create_this_module(struct obj_file *f, const char *m_name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002662{
2663 struct obj_section *sec;
2664
2665 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2666 sizeof(struct new_module));
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002667 /* done by obj_create_alloced_section_first: */
2668 /*memset(sec->contents, 0, sizeof(struct new_module));*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002669
2670 obj_add_symbol(f, SPFX "__this_module", -1,
2671 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2672 sizeof(struct new_module));
2673
2674 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2675 m_name);
2676}
2677
2678#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2679/* add an entry to the __ksymtab section, creating it if necessary */
2680static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2681{
2682 struct obj_section *sec;
2683 ElfW(Addr) ofs;
2684
2685 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2686 * If __ksymtab is defined but not marked alloc, x out the first character
2687 * (no obj_delete routine) and create a new __ksymtab with the correct
2688 * characteristics.
2689 */
2690 sec = obj_find_section(f, "__ksymtab");
2691 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2692 *((char *)(sec->name)) = 'x'; /* override const */
2693 sec = NULL;
2694 }
2695 if (!sec)
2696 sec = obj_create_alloced_section(f, "__ksymtab",
2697 tgt_sizeof_void_p, 0);
2698 if (!sec)
2699 return;
2700 sec->header.sh_flags |= SHF_ALLOC;
2701 /* Empty section might be byte-aligned */
2702 sec->header.sh_addralign = tgt_sizeof_void_p;
2703 ofs = sec->header.sh_size;
2704 obj_symbol_patch(f, sec->idx, ofs, sym);
2705 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2706 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2707}
2708#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
2709
2710static int new_create_module_ksymtab(struct obj_file *f)
2711{
2712 struct obj_section *sec;
2713 int i;
2714
2715 /* We must always add the module references. */
2716
2717 if (n_ext_modules_used) {
2718 struct new_module_ref *dep;
2719 struct obj_symbol *tm;
2720
2721 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2722 (sizeof(struct new_module_ref)
2723 * n_ext_modules_used));
2724 if (!sec)
2725 return 0;
2726
2727 tm = obj_find_symbol(f, SPFX "__this_module");
2728 dep = (struct new_module_ref *) sec->contents;
2729 for (i = 0; i < n_ext_modules; ++i)
2730 if (ext_modules[i].used) {
2731 dep->dep = ext_modules[i].addr;
2732 obj_symbol_patch(f, sec->idx,
2733 (char *) &dep->ref - sec->contents, tm);
2734 dep->next_ref = 0;
2735 ++dep;
2736 }
2737 }
2738
2739 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
2740 size_t nsyms;
2741 int *loaded;
2742
2743 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
2744
2745 /* We don't want to export symbols residing in sections that
2746 aren't loaded. There are a number of these created so that
2747 we make sure certain module options don't appear twice. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002748 i = f->header.e_shnum;
2749 loaded = alloca(sizeof(int) * i);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002750 while (--i >= 0)
2751 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2752
2753 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2754 struct obj_symbol *sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002755 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002756 if (ELF_ST_BIND(sym->info) != STB_LOCAL
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002757 && sym->secidx <= SHN_HIRESERVE
2758 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002759 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002760 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2761
2762 obj_symbol_patch(f, sec->idx, ofs, sym);
2763 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2764 sym->name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002765 nsyms++;
2766 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002767 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002768 }
2769
2770 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2771 }
2772
2773 return 1;
2774}
2775
2776
2777static int
2778new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2779{
2780 struct new_module *module;
2781 struct obj_section *sec;
2782 void *image;
2783 int ret;
2784 tgt_long m_addr;
2785
2786 sec = obj_find_section(f, ".this");
2787 if (!sec || !sec->contents) {
2788 bb_perror_msg_and_die("corrupt module %s?", m_name);
2789 }
2790 module = (struct new_module *) sec->contents;
2791 m_addr = sec->header.sh_addr;
2792
2793 module->size_of_struct = sizeof(*module);
2794 module->size = m_size;
2795 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2796
2797 sec = obj_find_section(f, "__ksymtab");
2798 if (sec && sec->header.sh_size) {
2799 module->syms = sec->header.sh_addr;
2800 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2801 }
2802
2803 if (n_ext_modules_used) {
2804 sec = obj_find_section(f, ".kmodtab");
2805 module->deps = sec->header.sh_addr;
2806 module->ndeps = n_ext_modules_used;
2807 }
2808
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002809 module->init = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2810 module->cleanup = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002811
2812 sec = obj_find_section(f, "__ex_table");
2813 if (sec) {
2814 module->ex_table_start = sec->header.sh_addr;
2815 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2816 }
2817
2818 sec = obj_find_section(f, ".text.init");
2819 if (sec) {
2820 module->runsize = sec->header.sh_addr - m_addr;
2821 }
2822 sec = obj_find_section(f, ".data.init");
2823 if (sec) {
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002824 if (!module->runsize
2825 || module->runsize > sec->header.sh_addr - m_addr
2826 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002827 module->runsize = sec->header.sh_addr - m_addr;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002828 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002829 }
2830 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2831 if (sec && sec->header.sh_size) {
2832 module->archdata_start = (void*)sec->header.sh_addr;
2833 module->archdata_end = module->archdata_start + sec->header.sh_size;
2834 }
2835 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2836 if (sec && sec->header.sh_size) {
2837 module->kallsyms_start = (void*)sec->header.sh_addr;
2838 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2839 }
2840
2841 /* Whew! All of the initialization is complete. Collect the final
2842 module image and give it to the kernel. */
2843
2844 image = xmalloc(m_size);
2845 obj_create_image(f, image);
2846
2847 ret = init_module(m_name, (struct new_module *) image);
2848 if (ret)
2849 bb_perror_msg("init_module: %s", m_name);
2850
2851 free(image);
2852
2853 return ret == 0;
2854}
2855
2856
2857/*======================================================================*/
2858
2859static void
2860obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2861 const char *string)
2862{
2863 struct obj_string_patch *p;
2864 struct obj_section *strsec;
2865 size_t len = strlen(string) + 1;
2866 char *loc;
2867
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002868 p = xzalloc(sizeof(*p));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002869 p->next = f->string_patches;
2870 p->reloc_secidx = secidx;
2871 p->reloc_offset = offset;
2872 f->string_patches = p;
2873
2874 strsec = obj_find_section(f, ".kstrtab");
2875 if (strsec == NULL) {
2876 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002877 /*p->string_offset = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002878 loc = strsec->contents;
2879 } else {
2880 p->string_offset = strsec->header.sh_size;
2881 loc = obj_extend_section(strsec, len);
2882 }
2883 memcpy(loc, string, len);
2884}
2885
2886static void
2887obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2888 struct obj_symbol *sym)
2889{
2890 struct obj_symbol_patch *p;
2891
2892 p = xmalloc(sizeof(*p));
2893 p->next = f->symbol_patches;
2894 p->reloc_secidx = secidx;
2895 p->reloc_offset = offset;
2896 p->sym = sym;
2897 f->symbol_patches = p;
2898}
2899
2900static void obj_check_undefineds(struct obj_file *f)
2901{
2902 unsigned i;
2903
2904 for (i = 0; i < HASH_BUCKETS; ++i) {
2905 struct obj_symbol *sym;
Denis Vlasenko49325962009-01-31 23:33:54 +00002906 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002907 if (sym->secidx == SHN_UNDEF) {
2908 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
2909 sym->secidx = SHN_ABS;
2910 sym->value = 0;
2911 } else {
2912 if (!flag_quiet)
2913 bb_error_msg_and_die("unresolved symbol %s", sym->name);
2914 }
2915 }
Denis Vlasenko49325962009-01-31 23:33:54 +00002916 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002917 }
2918}
2919
2920static void obj_allocate_commons(struct obj_file *f)
2921{
2922 struct common_entry {
2923 struct common_entry *next;
2924 struct obj_symbol *sym;
2925 } *common_head = NULL;
2926
2927 unsigned long i;
2928
2929 for (i = 0; i < HASH_BUCKETS; ++i) {
2930 struct obj_symbol *sym;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002931 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002932 if (sym->secidx == SHN_COMMON) {
2933 /* Collect all COMMON symbols and sort them by size so as to
2934 minimize space wasted by alignment requirements. */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002935 struct common_entry **p, *n;
2936 for (p = &common_head; *p; p = &(*p)->next)
2937 if (sym->size <= (*p)->sym->size)
2938 break;
2939 n = alloca(sizeof(*n));
2940 n->next = *p;
2941 n->sym = sym;
2942 *p = n;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002943 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002944 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002945 }
2946
2947 for (i = 1; i < f->local_symtab_size; ++i) {
2948 struct obj_symbol *sym = f->local_symtab[i];
2949 if (sym && sym->secidx == SHN_COMMON) {
2950 struct common_entry **p, *n;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002951 for (p = &common_head; *p; p = &(*p)->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002952 if (sym == (*p)->sym)
2953 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002954 if (sym->size < (*p)->sym->size) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002955 n = alloca(sizeof(*n));
2956 n->next = *p;
2957 n->sym = sym;
2958 *p = n;
2959 break;
2960 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002961 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002962 }
2963 }
2964
2965 if (common_head) {
2966 /* Find the bss section. */
2967 for (i = 0; i < f->header.e_shnum; ++i)
2968 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2969 break;
2970
2971 /* If for some reason there hadn't been one, create one. */
2972 if (i == f->header.e_shnum) {
2973 struct obj_section *sec;
2974
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002975 f->header.e_shnum++;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002976 f->sections = xrealloc_vector(f->sections, 2, i);
2977 f->sections[i] = sec = arch_new_section();
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002978
2979 sec->header.sh_type = SHT_PROGBITS;
2980 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2981 sec->name = ".bss";
2982 sec->idx = i;
2983 }
2984
2985 /* Allocate the COMMONS. */
2986 {
2987 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2988 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2989 struct common_entry *c;
2990
2991 for (c = common_head; c; c = c->next) {
2992 ElfW(Addr) align = c->sym->value;
2993
2994 if (align > max_align)
2995 max_align = align;
2996 if (bss_size & (align - 1))
2997 bss_size = (bss_size | (align - 1)) + 1;
2998
2999 c->sym->secidx = i;
3000 c->sym->value = bss_size;
3001
3002 bss_size += c->sym->size;
3003 }
3004
3005 f->sections[i]->header.sh_size = bss_size;
3006 f->sections[i]->header.sh_addralign = max_align;
3007 }
3008 }
3009
3010 /* For the sake of patch relocation and parameter initialization,
3011 allocate zeroed data for NOBITS sections now. Note that after
3012 this we cannot assume NOBITS are really empty. */
3013 for (i = 0; i < f->header.e_shnum; ++i) {
3014 struct obj_section *s = f->sections[i];
3015 if (s->header.sh_type == SHT_NOBITS) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003016 s->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003017 if (s->header.sh_size != 0)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003018 s->contents = xzalloc(s->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003019 s->header.sh_type = SHT_PROGBITS;
3020 }
3021 }
3022}
3023
3024static unsigned long obj_load_size(struct obj_file *f)
3025{
3026 unsigned long dot = 0;
3027 struct obj_section *sec;
3028
3029 /* Finalize the positions of the sections relative to one another. */
3030
3031 for (sec = f->load_order; sec; sec = sec->load_next) {
3032 ElfW(Addr) align;
3033
3034 align = sec->header.sh_addralign;
3035 if (align && (dot & (align - 1)))
3036 dot = (dot | (align - 1)) + 1;
3037
3038 sec->header.sh_addr = dot;
3039 dot += sec->header.sh_size;
3040 }
3041
3042 return dot;
3043}
3044
3045static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3046{
3047 int i, n = f->header.e_shnum;
3048 int ret = 1;
3049
3050 /* Finalize the addresses of the sections. */
3051
3052 f->baseaddr = base;
3053 for (i = 0; i < n; ++i)
3054 f->sections[i]->header.sh_addr += base;
3055
3056 /* And iterate over all of the relocations. */
3057
3058 for (i = 0; i < n; ++i) {
3059 struct obj_section *relsec, *symsec, *targsec, *strsec;
3060 ElfW(RelM) * rel, *relend;
3061 ElfW(Sym) * symtab;
3062 const char *strtab;
3063
3064 relsec = f->sections[i];
3065 if (relsec->header.sh_type != SHT_RELM)
3066 continue;
3067
3068 symsec = f->sections[relsec->header.sh_link];
3069 targsec = f->sections[relsec->header.sh_info];
3070 strsec = f->sections[symsec->header.sh_link];
3071
3072 rel = (ElfW(RelM) *) relsec->contents;
3073 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3074 symtab = (ElfW(Sym) *) symsec->contents;
3075 strtab = (const char *) strsec->contents;
3076
3077 for (; rel < relend; ++rel) {
3078 ElfW(Addr) value = 0;
3079 struct obj_symbol *intsym = NULL;
3080 unsigned long symndx;
Denis Vlasenko49325962009-01-31 23:33:54 +00003081 ElfW(Sym) *extsym = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003082 const char *errmsg;
3083
3084 /* Attempt to find a value to use for this relocation. */
3085
3086 symndx = ELF_R_SYM(rel->r_info);
3087 if (symndx) {
3088 /* Note we've already checked for undefined symbols. */
3089
3090 extsym = &symtab[symndx];
3091 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3092 /* Local symbols we look up in the local table to be sure
3093 we get the one that is really intended. */
3094 intsym = f->local_symtab[symndx];
3095 } else {
3096 /* Others we look up in the hash table. */
3097 const char *name;
3098 if (extsym->st_name)
3099 name = strtab + extsym->st_name;
3100 else
3101 name = f->sections[extsym->st_shndx]->name;
3102 intsym = obj_find_symbol(f, name);
3103 }
3104
3105 value = obj_symbol_final_value(f, intsym);
3106 intsym->referenced = 1;
3107 }
3108#if SHT_RELM == SHT_RELA
3109#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3110 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003111 if (!extsym || !extsym->st_name
3112 || ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003113#endif
3114 value += rel->r_addend;
3115#endif
3116
3117 /* Do it! */
3118 switch (arch_apply_relocation
3119 (f, targsec, /*symsec,*/ intsym, rel, value)
3120 ) {
3121 case obj_reloc_ok:
3122 break;
3123
3124 case obj_reloc_overflow:
3125 errmsg = "Relocation overflow";
3126 goto bad_reloc;
3127 case obj_reloc_dangerous:
3128 errmsg = "Dangerous relocation";
3129 goto bad_reloc;
3130 case obj_reloc_unhandled:
3131 errmsg = "Unhandled relocation";
3132bad_reloc:
3133 if (extsym) {
3134 bb_error_msg("%s of type %ld for %s", errmsg,
3135 (long) ELF_R_TYPE(rel->r_info),
3136 strtab + extsym->st_name);
3137 } else {
3138 bb_error_msg("%s of type %ld", errmsg,
3139 (long) ELF_R_TYPE(rel->r_info));
3140 }
3141 ret = 0;
3142 break;
3143 }
3144 }
3145 }
3146
3147 /* Finally, take care of the patches. */
3148
3149 if (f->string_patches) {
3150 struct obj_string_patch *p;
3151 struct obj_section *strsec;
3152 ElfW(Addr) strsec_base;
3153 strsec = obj_find_section(f, ".kstrtab");
3154 strsec_base = strsec->header.sh_addr;
3155
3156 for (p = f->string_patches; p; p = p->next) {
3157 struct obj_section *targsec = f->sections[p->reloc_secidx];
3158 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3159 = strsec_base + p->string_offset;
3160 }
3161 }
3162
3163 if (f->symbol_patches) {
3164 struct obj_symbol_patch *p;
3165
3166 for (p = f->symbol_patches; p; p = p->next) {
3167 struct obj_section *targsec = f->sections[p->reloc_secidx];
3168 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3169 = obj_symbol_final_value(f, p->sym);
3170 }
3171 }
3172
3173 return ret;
3174}
3175
3176static int obj_create_image(struct obj_file *f, char *image)
3177{
3178 struct obj_section *sec;
3179 ElfW(Addr) base = f->baseaddr;
3180
3181 for (sec = f->load_order; sec; sec = sec->load_next) {
3182 char *secimg;
3183
3184 if (sec->contents == 0 || sec->header.sh_size == 0)
3185 continue;
3186
3187 secimg = image + (sec->header.sh_addr - base);
3188
3189 /* Note that we allocated data for NOBITS sections earlier. */
3190 memcpy(secimg, sec->contents, sec->header.sh_size);
3191 }
3192
3193 return 1;
3194}
3195
3196/*======================================================================*/
3197
Denis Vlasenkof4393042009-04-05 23:25:09 +00003198static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003199{
Denis Vlasenkoe1de3af2009-03-29 16:38:59 +00003200#if BB_LITTLE_ENDIAN
3201# define ELFMAG_U32 ((uint32_t)(ELFMAG0 + 0x100 * (ELFMAG1 + (0x100 * (ELFMAG2 + 0x100 * ELFMAG3)))))
3202#else
3203# define ELFMAG_U32 ((uint32_t)((((ELFMAG0 * 0x100) + ELFMAG1) * 0x100 + ELFMAG2) * 0x100 + ELFMAG3))
3204#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003205 struct obj_file *f;
3206 ElfW(Shdr) * section_headers;
3207 size_t shnum, i;
3208 char *shstrtab;
3209
3210 /* Read the file header. */
3211
3212 f = arch_new_file();
3213 f->symbol_cmp = strcmp;
3214 f->symbol_hash = obj_elf_hash;
3215 f->load_order_search_start = &f->load_order;
3216
Denis Vlasenkof4393042009-04-05 23:25:09 +00003217 if (image_size < sizeof(f->header))
3218 bb_error_msg_and_die("error while loading ELF header");
3219 memcpy(&f->header, image, sizeof(f->header));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003220
Denis Vlasenkoe1de3af2009-03-29 16:38:59 +00003221 if (*(uint32_t*)(&f->header.e_ident) != ELFMAG_U32) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003222 bb_error_msg_and_die("not an ELF file");
3223 }
3224 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003225 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3226 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3227 || !MATCH_MACHINE(f->header.e_machine)
3228 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003229 bb_error_msg_and_die("ELF file not for this architecture");
3230 }
3231 if (f->header.e_type != ET_REL) {
3232 bb_error_msg_and_die("ELF file not a relocatable object");
3233 }
3234
3235 /* Read the section headers. */
3236
3237 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3238 bb_error_msg_and_die("section header size mismatch: %lu != %lu",
3239 (unsigned long) f->header.e_shentsize,
3240 (unsigned long) sizeof(ElfW(Shdr)));
3241 }
3242
3243 shnum = f->header.e_shnum;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003244 /* Growth of ->sections vector will be done by
3245 * xrealloc_vector(..., 2, ...), therefore we must allocate
3246 * at least 2^2 = 4 extra elements here. */
3247 f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003248
3249 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003250 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum)
3251 bb_error_msg_and_die("error while loading section headers");
3252 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003253
3254 /* Read the section data. */
3255
3256 for (i = 0; i < shnum; ++i) {
3257 struct obj_section *sec;
3258
3259 f->sections[i] = sec = arch_new_section();
3260
3261 sec->header = section_headers[i];
3262 sec->idx = i;
3263
3264 if (sec->header.sh_size) {
3265 switch (sec->header.sh_type) {
3266 case SHT_NULL:
3267 case SHT_NOTE:
3268 case SHT_NOBITS:
3269 /* ignore */
3270 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003271 case SHT_PROGBITS:
3272#if LOADBITS
3273 if (!loadprogbits) {
3274 sec->contents = NULL;
3275 break;
3276 }
3277#endif
3278 case SHT_SYMTAB:
3279 case SHT_STRTAB:
3280 case SHT_RELM:
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003281 sec->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003282 if (sec->header.sh_size > 0) {
3283 sec->contents = xmalloc(sec->header.sh_size);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003284 if (image_size < (sec->header.sh_offset + sec->header.sh_size))
3285 bb_error_msg_and_die("error while loading section data");
3286 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003287 }
3288 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003289#if SHT_RELM == SHT_REL
3290 case SHT_RELA:
3291 bb_error_msg_and_die("RELA relocations not supported on this architecture");
3292#else
3293 case SHT_REL:
3294 bb_error_msg_and_die("REL relocations not supported on this architecture");
3295#endif
3296 default:
3297 if (sec->header.sh_type >= SHT_LOPROC) {
3298 /* Assume processor specific section types are debug
3299 info and can safely be ignored. If this is ever not
3300 the case (Hello MIPS?), don't put ifdefs here but
3301 create an arch_load_proc_section(). */
3302 break;
3303 }
3304
3305 bb_error_msg_and_die("can't handle sections of type %ld",
3306 (long) sec->header.sh_type);
3307 }
3308 }
3309 }
3310
3311 /* Do what sort of interpretation as needed by each section. */
3312
3313 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3314
3315 for (i = 0; i < shnum; ++i) {
3316 struct obj_section *sec = f->sections[i];
3317 sec->name = shstrtab + sec->header.sh_name;
3318 }
3319
3320 for (i = 0; i < shnum; ++i) {
3321 struct obj_section *sec = f->sections[i];
3322
3323 /* .modinfo should be contents only but gcc has no attribute for that.
3324 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3325 */
3326 if (strcmp(sec->name, ".modinfo") == 0)
3327 sec->header.sh_flags &= ~SHF_ALLOC;
3328
3329 if (sec->header.sh_flags & SHF_ALLOC)
3330 obj_insert_section_load_order(f, sec);
3331
3332 switch (sec->header.sh_type) {
3333 case SHT_SYMTAB:
3334 {
3335 unsigned long nsym, j;
3336 char *strtab;
3337 ElfW(Sym) * sym;
3338
3339 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3340 bb_error_msg_and_die("symbol size mismatch: %lu != %lu",
3341 (unsigned long) sec->header.sh_entsize,
3342 (unsigned long) sizeof(ElfW(Sym)));
3343 }
3344
3345 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3346 strtab = f->sections[sec->header.sh_link]->contents;
3347 sym = (ElfW(Sym) *) sec->contents;
3348
3349 /* Allocate space for a table of local symbols. */
3350 j = f->local_symtab_size = sec->header.sh_info;
3351 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
3352
3353 /* Insert all symbols into the hash table. */
3354 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3355 ElfW(Addr) val = sym->st_value;
3356 const char *name;
3357 if (sym->st_name)
3358 name = strtab + sym->st_name;
3359 else if (sym->st_shndx < shnum)
3360 name = f->sections[sym->st_shndx]->name;
3361 else
3362 continue;
3363#if defined(__SH5__)
3364 /*
3365 * For sh64 it is possible that the target of a branch
3366 * requires a mode switch (32 to 16 and back again).
3367 *
3368 * This is implied by the lsb being set in the target
3369 * address for SHmedia mode and clear for SHcompact.
3370 */
3371 val |= sym->st_other & 4;
3372#endif
3373 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3374 val, sym->st_size);
3375 }
3376 }
3377 break;
3378
3379 case SHT_RELM:
3380 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3381 bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu",
3382 (unsigned long) sec->header.sh_entsize,
3383 (unsigned long) sizeof(ElfW(RelM)));
3384 }
3385 break;
3386 /* XXX Relocation code from modutils-2.3.19 is not here.
3387 * Why? That's about 20 lines of code from obj/obj_load.c,
3388 * which gets done in a second pass through the sections.
3389 * This BusyBox insmod does similar work in obj_relocate(). */
3390 }
3391 }
3392
3393 return f;
3394}
3395
3396#if ENABLE_FEATURE_INSMOD_LOADINKMEM
3397/*
3398 * load the unloaded sections directly into the memory allocated by
3399 * kernel for the module
3400 */
3401
Denis Vlasenkof4393042009-04-05 23:25:09 +00003402static int obj_load_progbits(char *image, size_t image_size, struct obj_file *f, char *imagebase)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003403{
3404 ElfW(Addr) base = f->baseaddr;
3405 struct obj_section* sec;
3406
3407 for (sec = f->load_order; sec; sec = sec->load_next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003408 /* section already loaded? */
3409 if (sec->contents != NULL)
3410 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003411 if (sec->header.sh_size == 0)
3412 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003413 sec->contents = imagebase + (sec->header.sh_addr - base);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003414 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) {
3415 bb_error_msg("error reading ELF section data");
3416 return 0; /* need to delete half-loaded module! */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003417 }
Denis Vlasenkof4393042009-04-05 23:25:09 +00003418 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003419 }
3420 return 1;
3421}
3422#endif
3423
3424static void hide_special_symbols(struct obj_file *f)
3425{
3426 static const char *const specials[] = {
3427 SPFX "cleanup_module",
3428 SPFX "init_module",
3429 SPFX "kernel_version",
3430 NULL
3431 };
3432
3433 struct obj_symbol *sym;
3434 const char *const *p;
3435
3436 for (p = specials; *p; ++p) {
3437 sym = obj_find_symbol(f, *p);
3438 if (sym != NULL)
3439 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3440 }
3441}
3442
3443
3444#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
3445static int obj_gpl_license(struct obj_file *f, const char **license)
3446{
3447 struct obj_section *sec;
3448 /* This list must match *exactly* the list of allowable licenses in
3449 * linux/include/linux/module.h. Checking for leading "GPL" will not
3450 * work, somebody will use "GPL sucks, this is proprietary".
3451 */
3452 static const char *const gpl_licenses[] = {
3453 "GPL",
3454 "GPL v2",
3455 "GPL and additional rights",
3456 "Dual BSD/GPL",
3457 "Dual MPL/GPL"
3458 };
3459
3460 sec = obj_find_section(f, ".modinfo");
3461 if (sec) {
3462 const char *value, *ptr, *endptr;
3463 ptr = sec->contents;
3464 endptr = ptr + sec->header.sh_size;
3465 while (ptr < endptr) {
3466 value = strchr(ptr, '=');
3467 if (value && strncmp(ptr, "license", value-ptr) == 0) {
3468 unsigned i;
3469 if (license)
3470 *license = value+1;
3471 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
3472 if (strcmp(value+1, gpl_licenses[i]) == 0)
3473 return 0;
3474 }
3475 return 2;
3476 }
3477 ptr = strchr(ptr, '\0');
3478 if (ptr)
3479 ptr++;
3480 else
3481 ptr = endptr;
3482 }
3483 }
3484 return 1;
3485}
3486
3487#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3488#define TAINT_PROPRIETORY_MODULE (1 << 0)
3489#define TAINT_FORCED_MODULE (1 << 1)
3490#define TAINT_UNSAFE_SMP (1 << 2)
3491#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3492
3493static void set_tainted(int fd, const char *m_name,
3494 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3495{
3496 static smallint printed_info;
3497
3498 char buf[80];
3499 int oldval;
3500
3501 if (fd < 0 && !kernel_has_tainted)
3502 return; /* New modutils on old kernel */
3503 printf("Warning: loading %s will taint the kernel: %s%s\n",
3504 m_name, text1, text2);
3505 if (!printed_info) {
3506 printf(" See %s for information about tainted modules\n", TAINT_URL);
3507 printed_info = 1;
3508 }
3509 if (fd >= 0) {
3510 read(fd, buf, sizeof(buf)-1);
3511 buf[sizeof(buf)-1] = '\0';
3512 oldval = strtoul(buf, NULL, 10);
3513 sprintf(buf, "%d\n", oldval | taint);
Denis Vlasenko73c571a2009-03-09 00:12:37 +00003514 xwrite_str(fd, buf);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003515 }
3516}
3517
3518/* Check if loading this module will taint the kernel. */
3519static void check_tainted_module(struct obj_file *f, const char *m_name)
3520{
3521 static const char tainted_file[] ALIGN1 = TAINT_FILENAME;
3522
3523 int fd, kernel_has_tainted;
3524 const char *ptr;
3525
3526 kernel_has_tainted = 1;
3527 fd = open(tainted_file, O_RDWR);
3528 if (fd < 0) {
3529 if (errno == ENOENT)
3530 kernel_has_tainted = 0;
3531 else if (errno == EACCES)
3532 kernel_has_tainted = 1;
3533 else {
3534 perror(tainted_file);
3535 kernel_has_tainted = 0;
3536 }
3537 }
3538
3539 switch (obj_gpl_license(f, &ptr)) {
3540 case 0:
3541 break;
3542 case 1:
3543 set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3544 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003545 default: /* case 2: */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003546 /* The module has a non-GPL license so we pretend that the
3547 * kernel always has a taint flag to get a warning even on
3548 * kernels without the proc flag.
3549 */
3550 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3551 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003552 }
3553
3554 if (flag_force_load)
3555 set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3556
3557 if (fd >= 0)
3558 close(fd);
3559}
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003560#else /* !FEATURE_CHECK_TAINTED_MODULE */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003561#define check_tainted_module(x, y) do { } while (0);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003562#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003563
3564#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3565/* add module source, timestamp, kernel version and a symbol for the
3566 * start of some sections. this info is used by ksymoops to do better
3567 * debugging.
3568 */
3569#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3570#define get_module_version(f, str) get_module_version(str)
3571#endif
3572static int
3573get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3574{
3575#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3576 return new_get_module_version(f, str);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003577#else
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003578 strncpy(str, "???", sizeof(str));
3579 return -1;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003580#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003581}
3582
3583/* add module source, timestamp, kernel version and a symbol for the
3584 * start of some sections. this info is used by ksymoops to do better
3585 * debugging.
3586 */
3587static void
3588add_ksymoops_symbols(struct obj_file *f, const char *filename,
3589 const char *m_name)
3590{
3591 static const char symprefix[] ALIGN1 = "__insmod_";
3592 static const char section_names[][8] = {
3593 ".text",
3594 ".rodata",
3595 ".data",
3596 ".bss",
3597 ".sbss"
3598 };
3599
3600 struct obj_section *sec;
3601 struct obj_symbol *sym;
3602 char *name, *absolute_filename;
3603 char str[STRVERSIONLEN];
3604 unsigned i;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003605 int lm_name, lfilename, use_ksymtab, version;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003606 struct stat statbuf;
3607
3608 /* WARNING: was using realpath, but replaced by readlink to stop using
3609 * lots of stack. But here it seems to be able to cause problems? */
3610 absolute_filename = xmalloc_readlink(filename);
3611 if (!absolute_filename)
3612 absolute_filename = xstrdup(filename);
3613
3614 lm_name = strlen(m_name);
3615 lfilename = strlen(absolute_filename);
3616
3617 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3618 * are not to be exported. otherwise leave ksymtab alone for now, the
3619 * "export all symbols" compatibility code will export these symbols later.
3620 */
3621 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
3622
3623 sec = obj_find_section(f, ".this");
3624 if (sec) {
3625 /* tag the module header with the object name, last modified
3626 * timestamp and module version. worst case for module version
3627 * is 0xffffff, decimal 16777215. putting all three fields in
3628 * one symbol is less readable but saves kernel space.
3629 */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003630 if (stat(absolute_filename, &statbuf) != 0)
3631 statbuf.st_mtime = 0;
3632 version = get_module_version(f, str); /* -1 if not found */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003633 name = xasprintf("%s%s_O%s_M%0*lX_V%d",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003634 symprefix, m_name, absolute_filename,
Denis Vlasenko49325962009-01-31 23:33:54 +00003635 (int)(2 * sizeof(statbuf.st_mtime)),
3636 (long)statbuf.st_mtime,
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003637 version);
3638 sym = obj_add_symbol(f, name, -1,
3639 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3640 sec->idx, sec->header.sh_addr, 0);
3641 if (use_ksymtab)
3642 new_add_ksymtab(f, sym);
3643 }
3644 free(absolute_filename);
3645#ifdef _NOT_SUPPORTED_
3646 /* record where the persistent data is going, same address as previous symbol */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003647 if (f->persist) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003648 name = xasprintf("%s%s_P%s",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003649 symprefix, m_name, f->persist);
3650 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3651 sec->idx, sec->header.sh_addr, 0);
3652 if (use_ksymtab)
3653 new_add_ksymtab(f, sym);
3654 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003655#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003656 /* tag the desired sections if size is non-zero */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003657 for (i = 0; i < ARRAY_SIZE(section_names); ++i) {
3658 sec = obj_find_section(f, section_names[i]);
3659 if (sec && sec->header.sh_size) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003660 name = xasprintf("%s%s_S%s_L%ld",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003661 symprefix, m_name, sec->name,
3662 (long)sec->header.sh_size);
3663 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3664 sec->idx, sec->header.sh_addr, 0);
3665 if (use_ksymtab)
3666 new_add_ksymtab(f, sym);
3667 }
3668 }
3669}
3670#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3671
3672#if ENABLE_FEATURE_INSMOD_LOAD_MAP
3673static void print_load_map(struct obj_file *f)
3674{
3675 struct obj_section *sec;
3676#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3677 struct obj_symbol **all, **p;
Denis Vlasenko49325962009-01-31 23:33:54 +00003678 int i, nsyms;
3679 char *loaded; /* array of booleans */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003680 struct obj_symbol *sym;
3681#endif
3682 /* Report on the section layout. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003683 printf("Sections: Size %-*s Align\n",
3684 (int) (2 * sizeof(void *)), "Address");
3685
3686 for (sec = f->load_order; sec; sec = sec->load_next) {
3687 int a;
3688 unsigned long tmp;
3689
3690 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3691 tmp >>= 1;
3692 if (a == -1)
3693 a = 0;
3694
3695 printf("%-15s %08lx %0*lx 2**%d\n",
3696 sec->name,
3697 (long)sec->header.sh_size,
3698 (int) (2 * sizeof(void *)),
3699 (long)sec->header.sh_addr,
3700 a);
3701 }
3702#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3703 /* Quick reference which section indices are loaded. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003704 i = f->header.e_shnum;
Denis Vlasenko49325962009-01-31 23:33:54 +00003705 loaded = alloca(i * sizeof(loaded[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003706 while (--i >= 0)
3707 loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0);
3708
3709 /* Collect the symbols we'll be listing. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003710 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3711 for (sym = f->symtab[i]; sym; sym = sym->next)
3712 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003713 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3714 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003715 ++nsyms;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003716 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003717
Denis Vlasenko49325962009-01-31 23:33:54 +00003718 all = alloca(nsyms * sizeof(all[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003719
3720 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3721 for (sym = f->symtab[i]; sym; sym = sym->next)
3722 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003723 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3724 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003725 *p++ = sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003726 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003727
3728 /* And list them. */
3729 printf("\nSymbols:\n");
3730 for (p = all; p < all + nsyms; ++p) {
3731 char type = '?';
3732 unsigned long value;
3733
3734 sym = *p;
3735 if (sym->secidx == SHN_ABS) {
3736 type = 'A';
3737 value = sym->value;
3738 } else if (sym->secidx == SHN_UNDEF) {
3739 type = 'U';
3740 value = 0;
3741 } else {
3742 sec = f->sections[sym->secidx];
3743
3744 if (sec->header.sh_type == SHT_NOBITS)
3745 type = 'B';
3746 else if (sec->header.sh_flags & SHF_ALLOC) {
3747 if (sec->header.sh_flags & SHF_EXECINSTR)
3748 type = 'T';
3749 else if (sec->header.sh_flags & SHF_WRITE)
3750 type = 'D';
3751 else
3752 type = 'R';
3753 }
3754 value = sym->value + sec->header.sh_addr;
3755 }
3756
3757 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
Denis Vlasenko49325962009-01-31 23:33:54 +00003758 type |= 0x20; /* tolower. safe for '?' too */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003759
3760 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3761 type, sym->name);
3762 }
3763#endif
3764}
3765#else /* !FEATURE_INSMOD_LOAD_MAP */
3766static void print_load_map(struct obj_file *f UNUSED_PARAM)
3767{
3768}
3769#endif
3770
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003771int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003772{
3773 int k_crcs;
3774 unsigned long m_size;
3775 ElfW(Addr) m_addr;
3776 struct obj_file *f;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003777 int exit_status = EXIT_FAILURE;
Denis Vlasenkof4393042009-04-05 23:25:09 +00003778 char *m_name;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003779#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003780 int m_has_modinfo;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003781#endif
Denis Vlasenkof4393042009-04-05 23:25:09 +00003782 char *image;
3783 size_t image_size = 64 * 1024 * 1024;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003784
Denis Vlasenkof4393042009-04-05 23:25:09 +00003785 /* Load module into memory and unzip if compressed */
3786 image = xmalloc_open_zipped_read_close(m_filename, &image_size);
3787 if (!image)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003788 return EXIT_FAILURE;
3789
3790 m_name = xstrdup(bb_basename(m_filename));
Denis Vlasenkof4393042009-04-05 23:25:09 +00003791 /* "module.o[.gz]" -> "module" */
3792 *strchrnul(m_name, '.') = '\0';
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003793
Denis Vlasenkof4393042009-04-05 23:25:09 +00003794 f = obj_load(image, image_size, LOADBITS);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003795
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003796#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3797 /* Version correspondence? */
Denis Vlasenko51056b32009-04-12 14:21:29 +00003798 m_has_modinfo = (get_modinfo_value(f, "kernel_version") != NULL);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003799 if (!flag_quiet) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003800 char m_strversion[STRVERSIONLEN];
3801 struct utsname uts;
3802
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003803 if (m_has_modinfo) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003804 int m_version = new_get_module_version(f, m_strversion);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003805 if (m_version == -1) {
Denis Vlasenko1f632292009-04-13 02:25:40 +00003806 bb_error_msg_and_die("can't find the kernel version "
Denis Vlasenko51056b32009-04-12 14:21:29 +00003807 "the module was compiled for");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003808 }
3809 }
3810
Denis Vlasenko51056b32009-04-12 14:21:29 +00003811 uname(&uts);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003812 if (strncmp(uts.release, m_strversion, STRVERSIONLEN) != 0) {
3813 bb_error_msg("%skernel-module version mismatch\n"
3814 "\t%s was compiled for kernel version %s\n"
3815 "\twhile this kernel is version %s",
3816 flag_force_load ? "warning: " : "",
3817 m_name, m_strversion, uts.release);
3818 if (!flag_force_load)
3819 goto out;
3820 }
3821 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003822#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003823
3824 if (query_module(NULL, 0, NULL, 0, NULL))
Denis Vlasenkof4393042009-04-05 23:25:09 +00003825 bb_error_msg_and_die("old (unsupported) kernel");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003826 new_get_kernel_symbols();
3827 k_crcs = new_is_kernel_checksummed();
3828
3829#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003830 {
3831 int m_crcs = 0;
3832 if (m_has_modinfo)
3833 m_crcs = new_is_module_checksummed(f);
3834 if (m_crcs != k_crcs)
3835 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3836 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003837#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003838
3839 /* Let the module know about the kernel symbols. */
3840 add_kernel_symbols(f);
3841
3842 /* Allocate common symbols, symbol tables, and string tables. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003843 new_create_this_module(f, m_name);
3844 obj_check_undefineds(f);
3845 obj_allocate_commons(f);
3846 check_tainted_module(f, m_name);
3847
Denis Vlasenko49325962009-01-31 23:33:54 +00003848 /* Done with the module name, on to the optional var=value arguments */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003849 new_process_module_arguments(f, options);
3850
3851 arch_create_got(f);
3852 hide_special_symbols(f);
3853
3854#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3855 add_ksymoops_symbols(f, m_filename, m_name);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003856#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003857
3858 new_create_module_ksymtab(f);
3859
3860 /* Find current size of the module */
3861 m_size = obj_load_size(f);
3862
3863 m_addr = create_module(m_name, m_size);
3864 if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003865 case EEXIST:
3866 bb_error_msg_and_die("a module named %s already exists", m_name);
3867 case ENOMEM:
3868 bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes",
3869 m_size);
3870 default:
3871 bb_perror_msg_and_die("create_module: %s", m_name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003872 }
3873
3874#if !LOADBITS
3875 /*
3876 * the PROGBITS section was not loaded by the obj_load
3877 * now we can load them directly into the kernel memory
3878 */
Denis Vlasenkof4393042009-04-05 23:25:09 +00003879 if (!obj_load_progbits(image, image_size, f, (char*)m_addr)) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003880 delete_module(m_name, 0);
3881 goto out;
3882 }
3883#endif
3884
3885 if (!obj_relocate(f, m_addr)) {
3886 delete_module(m_name, 0);
3887 goto out;
3888 }
3889
3890 if (!new_init_module(m_name, f, m_size)) {
3891 delete_module(m_name, 0);
3892 goto out;
3893 }
3894
3895 if (flag_print_load_map)
3896 print_load_map(f);
3897
3898 exit_status = EXIT_SUCCESS;
3899
3900 out:
Denis Vlasenkof4393042009-04-05 23:25:09 +00003901 free(image);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003902 free(m_name);
3903
3904 return exit_status;
3905}