blob: a878e740c7015dc59dd3278d6aa2c70c5478cbda [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
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200514struct obj_section {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000515 ElfW(Shdr) header;
516 const char *name;
517 char *contents;
518 struct obj_section *load_next;
519 int idx;
520};
521
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200522struct obj_symbol {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000523 struct obj_symbol *next; /* hash table link */
524 const char *name;
525 unsigned long value;
526 unsigned long size;
527 int secidx; /* the defining section index/module */
528 int info;
529 int ksymidx; /* for export to the kernel symtab */
530 int referenced; /* actually used in the link */
531};
532
533/* Hardcode the hash table size. We shouldn't be needing so many
534 symbols that we begin to degrade performance, and we get a big win
535 by giving the compiler a constant divisor. */
536
537#define HASH_BUCKETS 521
538
539struct obj_file {
540 ElfW(Ehdr) header;
541 ElfW(Addr) baseaddr;
542 struct obj_section **sections;
543 struct obj_section *load_order;
544 struct obj_section **load_order_search_start;
545 struct obj_string_patch *string_patches;
546 struct obj_symbol_patch *symbol_patches;
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200547 int (*symbol_cmp)(const char *, const char *); /* cant be FAST_FUNC */
548 unsigned long (*symbol_hash)(const char *) FAST_FUNC;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000549 unsigned long local_symtab_size;
550 struct obj_symbol **local_symtab;
551 struct obj_symbol *symtab[HASH_BUCKETS];
552};
553
554enum obj_reloc {
555 obj_reloc_ok,
556 obj_reloc_overflow,
557 obj_reloc_dangerous,
558 obj_reloc_unhandled
559};
560
561struct obj_string_patch {
562 struct obj_string_patch *next;
563 int reloc_secidx;
564 ElfW(Addr) reloc_offset;
565 ElfW(Addr) string_offset;
566};
567
568struct obj_symbol_patch {
569 struct obj_symbol_patch *next;
570 int reloc_secidx;
571 ElfW(Addr) reloc_offset;
572 struct obj_symbol *sym;
573};
574
575
576/* Generic object manipulation routines. */
577
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200578static unsigned long FAST_FUNC obj_elf_hash(const char *);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000579
580static unsigned long obj_elf_hash_n(const char *, unsigned long len);
581
582static struct obj_symbol *obj_find_symbol(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200583 const char *name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000584
585static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200586 struct obj_symbol *sym);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000587
588#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
589static void obj_set_symbol_compare(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200590 int (*cmp)(const char *, const char *),
591 unsigned long (*hash)(const char *) FAST_FUNC);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000592#endif
593
594static struct obj_section *obj_find_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200595 const char *name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000596
597static void obj_insert_section_load_order(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200598 struct obj_section *sec);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000599
600static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200601 const char *name,
602 unsigned long align,
603 unsigned long size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000604
605static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200606 const char *name,
607 unsigned long align,
608 unsigned long size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000609
610static void *obj_extend_section(struct obj_section *sec, unsigned long more);
611
612static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200613 const char *string);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000614
615static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200616 struct obj_symbol *sym);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000617
618static void obj_check_undefineds(struct obj_file *f);
619
620static void obj_allocate_commons(struct obj_file *f);
621
622static unsigned long obj_load_size(struct obj_file *f);
623
624static int obj_relocate(struct obj_file *f, ElfW(Addr) base);
625
Denis Vlasenkof4393042009-04-05 23:25:09 +0000626#if !LOADBITS
627#define obj_load(image, image_size, loadprogbits) \
628 obj_load(image, image_size)
629#endif
630static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000631
632static int obj_create_image(struct obj_file *f, char *image);
633
634/* Architecture specific manipulation routines. */
635
636static struct obj_file *arch_new_file(void);
637
638static struct obj_section *arch_new_section(void);
639
640static struct obj_symbol *arch_new_symbol(void);
641
642static enum obj_reloc arch_apply_relocation(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200643 struct obj_section *targsec,
644 /*struct obj_section *symsec,*/
645 struct obj_symbol *sym,
646 ElfW(RelM) *rel, ElfW(Addr) value);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000647
648static void arch_create_got(struct obj_file *f);
649#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
650static int obj_gpl_license(struct obj_file *f, const char **license);
Denis Vlasenkoe35af562009-01-31 14:22:24 +0000651#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000652#endif /* obj.h */
653//----------------------------------------------------------------------------
654//--------end of modutils obj.h
655//----------------------------------------------------------------------------
656
657
658/* SPFX is always a string, so it can be concatenated to string constants. */
659#ifdef SYMBOL_PREFIX
660#define SPFX SYMBOL_PREFIX
661#else
662#define SPFX ""
663#endif
664
665enum { STRVERSIONLEN = 64 };
666
667/*======================================================================*/
668
669#define flag_force_load (option_mask32 & INSMOD_OPT_FORCE)
670#define flag_autoclean (option_mask32 & INSMOD_OPT_KERNELD)
671#define flag_verbose (option_mask32 & INSMOD_OPT_VERBOSE)
672#define flag_quiet (option_mask32 & INSMOD_OPT_SILENT)
673#define flag_noexport (option_mask32 & INSMOD_OPT_NO_EXPORT)
674#define flag_print_load_map (option_mask32 & INSMOD_OPT_PRINT_MAP)
675
676/*======================================================================*/
677
678#if defined(USE_LIST)
679
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200680struct arch_list_entry {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000681 struct arch_list_entry *next;
682 LIST_ARCHTYPE addend;
683 int offset;
684 int inited : 1;
685};
686
687#endif
688
689#if defined(USE_SINGLE)
690
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200691struct arch_single_entry {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000692 int offset;
693 int inited : 1;
694 int allocated : 1;
695};
696
697#endif
698
699#if defined(__mips__)
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200700struct mips_hi16 {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000701 struct mips_hi16 *next;
702 ElfW(Addr) *addr;
703 ElfW(Addr) value;
704};
705#endif
706
707struct arch_file {
708 struct obj_file root;
709#if defined(USE_PLT_ENTRIES)
710 struct obj_section *plt;
711#endif
712#if defined(USE_GOT_ENTRIES)
713 struct obj_section *got;
714#endif
715#if defined(__mips__)
716 struct mips_hi16 *mips_hi16_list;
717#endif
718};
719
720struct arch_symbol {
721 struct obj_symbol root;
722#if defined(USE_PLT_ENTRIES)
723#if defined(USE_PLT_LIST)
724 struct arch_list_entry *pltent;
725#else
726 struct arch_single_entry pltent;
727#endif
728#endif
729#if defined(USE_GOT_ENTRIES)
730 struct arch_single_entry gotent;
731#endif
732};
733
734
735struct external_module {
736 const char *name;
737 ElfW(Addr) addr;
738 int used;
739 size_t nsyms;
740 struct new_module_symbol *syms;
741};
742
743static struct new_module_symbol *ksyms;
744static size_t nksyms;
745
746static struct external_module *ext_modules;
747static int n_ext_modules;
748static int n_ext_modules_used;
749
750/*======================================================================*/
751
752
753static struct obj_file *arch_new_file(void)
754{
755 struct arch_file *f;
756 f = xzalloc(sizeof(*f));
757 return &f->root; /* it's a first member */
758}
759
760static struct obj_section *arch_new_section(void)
761{
762 return xzalloc(sizeof(struct obj_section));
763}
764
765static struct obj_symbol *arch_new_symbol(void)
766{
767 struct arch_symbol *sym;
768 sym = xzalloc(sizeof(*sym));
769 return &sym->root;
770}
771
772static enum obj_reloc
773arch_apply_relocation(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +0200774 struct obj_section *targsec,
775 /*struct obj_section *symsec,*/
776 struct obj_symbol *sym,
777 ElfW(RelM) *rel, ElfW(Addr) v)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +0000778{
779#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
780 || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
781 || defined(__powerpc__) || defined(__mips__)
782 struct arch_file *ifile = (struct arch_file *) f;
783#endif
784 enum obj_reloc ret = obj_reloc_ok;
785 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
786#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
787 || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
788 || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
789 || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
790 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
791#endif
792#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
793 struct arch_symbol *isym = (struct arch_symbol *) sym;
794#endif
795#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
796 || defined(__sh__) || defined(__s390__)
797#if defined(USE_GOT_ENTRIES)
798 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
799#endif
800#endif
801#if defined(USE_PLT_ENTRIES)
802 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
803 unsigned long *ip;
804# if defined(USE_PLT_LIST)
805 struct arch_list_entry *pe;
806# else
807 struct arch_single_entry *pe;
808# endif
809#endif
810
811 switch (ELF_R_TYPE(rel->r_info)) {
812
813#if defined(__arm__)
814
815 case R_ARM_NONE:
816 break;
817
818 case R_ARM_ABS32:
819 *loc += v;
820 break;
821
822 case R_ARM_GOT32:
823 goto bb_use_got;
824
825 case R_ARM_GOTPC:
826 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
827 * (which is .got) similar to branch,
828 * but is full 32 bits relative */
829
830 *loc += got - dot;
831 break;
832
833 case R_ARM_PC24:
834 case R_ARM_PLT32:
835 goto bb_use_plt;
836
837 case R_ARM_GOTOFF: /* address relative to the got */
838 *loc += v - got;
839 break;
840
841#elif defined(__cris__)
842
843 case R_CRIS_NONE:
844 break;
845
846 case R_CRIS_32:
847 /* CRIS keeps the relocation value in the r_addend field and
848 * should not use whats in *loc at all
849 */
850 *loc = v;
851 break;
852
853#elif defined(__H8300H__) || defined(__H8300S__)
854
855 case R_H8_DIR24R8:
856 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
857 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
858 break;
859 case R_H8_DIR24A8:
860 *loc += v;
861 break;
862 case R_H8_DIR32:
863 case R_H8_DIR32A16:
864 *loc += v;
865 break;
866 case R_H8_PCREL16:
867 v -= dot + 2;
868 if ((ElfW(Sword))v > 0x7fff ||
869 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
870 ret = obj_reloc_overflow;
871 else
872 *(unsigned short *)loc = v;
873 break;
874 case R_H8_PCREL8:
875 v -= dot + 1;
876 if ((ElfW(Sword))v > 0x7f ||
877 (ElfW(Sword))v < -(ElfW(Sword))0x80)
878 ret = obj_reloc_overflow;
879 else
880 *(unsigned char *)loc = v;
881 break;
882
883#elif defined(__i386__)
884
885 case R_386_NONE:
886 break;
887
888 case R_386_32:
889 *loc += v;
890 break;
891
892 case R_386_PLT32:
893 case R_386_PC32:
894 case R_386_GOTOFF:
895 *loc += v - dot;
896 break;
897
898 case R_386_GLOB_DAT:
899 case R_386_JMP_SLOT:
900 *loc = v;
901 break;
902
903 case R_386_RELATIVE:
904 *loc += f->baseaddr;
905 break;
906
907 case R_386_GOTPC:
908 *loc += got - dot;
909 break;
910
911 case R_386_GOT32:
912 goto bb_use_got;
913 break;
914
915#elif defined(__microblaze__)
916 case R_MICROBLAZE_NONE:
917 case R_MICROBLAZE_64_NONE:
918 case R_MICROBLAZE_32_SYM_OP_SYM:
919 case R_MICROBLAZE_32_PCREL:
920 break;
921
922 case R_MICROBLAZE_64_PCREL: {
923 /* dot is the address of the current instruction.
924 * v is the target symbol address.
925 * So we need to extract the offset in the code,
926 * adding v, then subtrating the current address
927 * of this instruction.
928 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
929 */
930
931 /* Get split offset stored in code */
932 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
933 (loc[1] & 0xFFFF);
934
935 /* Adjust relative offset. -4 adjustment required
936 * because dot points to the IMM insn, but branch
937 * is computed relative to the branch instruction itself.
938 */
939 temp += v - dot - 4;
940
941 /* Store back into code */
942 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
943 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
944
945 break;
946 }
947
948 case R_MICROBLAZE_32:
949 *loc += v;
950 break;
951
952 case R_MICROBLAZE_64: {
953 /* Get split pointer stored in code */
954 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
955 (loc[1] & 0xFFFF);
956
957 /* Add reloc offset */
958 temp1+=v;
959
960 /* Store back into code */
961 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
962 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
963
964 break;
965 }
966
967 case R_MICROBLAZE_32_PCREL_LO:
968 case R_MICROBLAZE_32_LO:
969 case R_MICROBLAZE_SRO32:
970 case R_MICROBLAZE_SRW32:
971 ret = obj_reloc_unhandled;
972 break;
973
974#elif defined(__mc68000__)
975
976 case R_68K_NONE:
977 break;
978
979 case R_68K_32:
980 *loc += v;
981 break;
982
983 case R_68K_8:
984 if (v > 0xff) {
985 ret = obj_reloc_overflow;
986 }
987 *(char *)loc = v;
988 break;
989
990 case R_68K_16:
991 if (v > 0xffff) {
992 ret = obj_reloc_overflow;
993 }
994 *(short *)loc = v;
995 break;
996
997 case R_68K_PC8:
998 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +0000999 if ((ElfW(Sword))v > 0x7f
1000 || (ElfW(Sword))v < -(ElfW(Sword))0x80
1001 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001002 ret = obj_reloc_overflow;
1003 }
1004 *(char *)loc = v;
1005 break;
1006
1007 case R_68K_PC16:
1008 v -= dot;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001009 if ((ElfW(Sword))v > 0x7fff
1010 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
1011 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001012 ret = obj_reloc_overflow;
1013 }
1014 *(short *)loc = v;
1015 break;
1016
1017 case R_68K_PC32:
1018 *(int *)loc = v - dot;
1019 break;
1020
1021 case R_68K_GLOB_DAT:
1022 case R_68K_JMP_SLOT:
1023 *loc = v;
1024 break;
1025
1026 case R_68K_RELATIVE:
1027 *(int *)loc += f->baseaddr;
1028 break;
1029
1030 case R_68K_GOT32:
1031 goto bb_use_got;
1032
1033# ifdef R_68K_GOTOFF
1034 case R_68K_GOTOFF:
1035 *loc += v - got;
1036 break;
1037# endif
1038
1039#elif defined(__mips__)
1040
1041 case R_MIPS_NONE:
1042 break;
1043
1044 case R_MIPS_32:
1045 *loc += v;
1046 break;
1047
1048 case R_MIPS_26:
1049 if (v % 4)
1050 ret = obj_reloc_dangerous;
1051 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1052 ret = obj_reloc_overflow;
1053 *loc =
1054 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1055 0x03ffffff);
1056 break;
1057
1058 case R_MIPS_HI16:
1059 {
1060 struct mips_hi16 *n;
1061
1062 /* We cannot relocate this one now because we don't know the value
1063 of the carry we need to add. Save the information, and let LO16
1064 do the actual relocation. */
1065 n = xmalloc(sizeof *n);
1066 n->addr = loc;
1067 n->value = v;
1068 n->next = ifile->mips_hi16_list;
1069 ifile->mips_hi16_list = n;
1070 break;
1071 }
1072
1073 case R_MIPS_LO16:
1074 {
1075 unsigned long insnlo = *loc;
1076 ElfW(Addr) val, vallo;
1077
1078 /* Sign extend the addend we extract from the lo insn. */
1079 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1080
1081 if (ifile->mips_hi16_list != NULL) {
1082 struct mips_hi16 *l;
1083
1084 l = ifile->mips_hi16_list;
1085 while (l != NULL) {
1086 struct mips_hi16 *next;
1087 unsigned long insn;
1088
1089 /* Do the HI16 relocation. Note that we actually don't
1090 need to know anything about the LO16 itself, except where
1091 to find the low 16 bits of the addend needed by the LO16. */
1092 insn = *l->addr;
1093 val =
1094 ((insn & 0xffff) << 16) +
1095 vallo;
1096 val += v;
1097
1098 /* Account for the sign extension that will happen in the
1099 low bits. */
1100 val =
1101 ((val >> 16) +
1102 ((val & 0x8000) !=
1103 0)) & 0xffff;
1104
1105 insn = (insn & ~0xffff) | val;
1106 *l->addr = insn;
1107
1108 next = l->next;
1109 free(l);
1110 l = next;
1111 }
1112
1113 ifile->mips_hi16_list = NULL;
1114 }
1115
1116 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1117 val = v + vallo;
1118 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1119 *loc = insnlo;
1120 break;
1121 }
1122
1123#elif defined(__nios2__)
1124
1125 case R_NIOS2_NONE:
1126 break;
1127
1128 case R_NIOS2_BFD_RELOC_32:
1129 *loc += v;
1130 break;
1131
1132 case R_NIOS2_BFD_RELOC_16:
1133 if (v > 0xffff) {
1134 ret = obj_reloc_overflow;
1135 }
1136 *(short *)loc = v;
1137 break;
1138
1139 case R_NIOS2_BFD_RELOC_8:
1140 if (v > 0xff) {
1141 ret = obj_reloc_overflow;
1142 }
1143 *(char *)loc = v;
1144 break;
1145
1146 case R_NIOS2_S16:
1147 {
1148 Elf32_Addr word;
1149
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001150 if ((Elf32_Sword)v > 0x7fff
1151 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1152 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001153 ret = obj_reloc_overflow;
1154 }
1155
1156 word = *loc;
1157 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1158 (word & 0x3f);
1159 }
1160 break;
1161
1162 case R_NIOS2_U16:
1163 {
1164 Elf32_Addr word;
1165
1166 if (v > 0xffff) {
1167 ret = obj_reloc_overflow;
1168 }
1169
1170 word = *loc;
1171 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1172 (word & 0x3f);
1173 }
1174 break;
1175
1176 case R_NIOS2_PCREL16:
1177 {
1178 Elf32_Addr word;
1179
1180 v -= dot + 4;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001181 if ((Elf32_Sword)v > 0x7fff
1182 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1183 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001184 ret = obj_reloc_overflow;
1185 }
1186
1187 word = *loc;
1188 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1189 }
1190 break;
1191
1192 case R_NIOS2_GPREL:
1193 {
1194 Elf32_Addr word, gp;
1195 /* get _gp */
1196 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00001197 v -= gp;
1198 if ((Elf32_Sword)v > 0x7fff
1199 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1200 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001201 ret = obj_reloc_overflow;
1202 }
1203
1204 word = *loc;
1205 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1206 }
1207 break;
1208
1209 case R_NIOS2_CALL26:
1210 if (v & 3)
1211 ret = obj_reloc_dangerous;
1212 if ((v >> 28) != (dot >> 28))
1213 ret = obj_reloc_overflow;
1214 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1215 break;
1216
1217 case R_NIOS2_IMM5:
1218 {
1219 Elf32_Addr word;
1220
1221 if (v > 0x1f) {
1222 ret = obj_reloc_overflow;
1223 }
1224
1225 word = *loc & ~0x7c0;
1226 *loc = word | ((v & 0x1f) << 6);
1227 }
1228 break;
1229
1230 case R_NIOS2_IMM6:
1231 {
1232 Elf32_Addr word;
1233
1234 if (v > 0x3f) {
1235 ret = obj_reloc_overflow;
1236 }
1237
1238 word = *loc & ~0xfc0;
1239 *loc = word | ((v & 0x3f) << 6);
1240 }
1241 break;
1242
1243 case R_NIOS2_IMM8:
1244 {
1245 Elf32_Addr word;
1246
1247 if (v > 0xff) {
1248 ret = obj_reloc_overflow;
1249 }
1250
1251 word = *loc & ~0x3fc0;
1252 *loc = word | ((v & 0xff) << 6);
1253 }
1254 break;
1255
1256 case R_NIOS2_HI16:
1257 {
1258 Elf32_Addr word;
1259
1260 word = *loc;
1261 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1262 (word & 0x3f);
1263 }
1264 break;
1265
1266 case R_NIOS2_LO16:
1267 {
1268 Elf32_Addr word;
1269
1270 word = *loc;
1271 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1272 (word & 0x3f);
1273 }
1274 break;
1275
1276 case R_NIOS2_HIADJ16:
1277 {
1278 Elf32_Addr word1, word2;
1279
1280 word1 = *loc;
1281 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1282 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1283 (word1 & 0x3f);
1284 }
1285 break;
1286
1287#elif defined(__powerpc64__)
1288 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
1289
1290#elif defined(__powerpc__)
1291
1292 case R_PPC_ADDR16_HA:
1293 *(unsigned short *)loc = (v + 0x8000) >> 16;
1294 break;
1295
1296 case R_PPC_ADDR16_HI:
1297 *(unsigned short *)loc = v >> 16;
1298 break;
1299
1300 case R_PPC_ADDR16_LO:
1301 *(unsigned short *)loc = v;
1302 break;
1303
1304 case R_PPC_REL24:
1305 goto bb_use_plt;
1306
1307 case R_PPC_REL32:
1308 *loc = v - dot;
1309 break;
1310
1311 case R_PPC_ADDR32:
1312 *loc = v;
1313 break;
1314
1315#elif defined(__s390__)
1316
1317 case R_390_32:
1318 *(unsigned int *) loc += v;
1319 break;
1320 case R_390_16:
1321 *(unsigned short *) loc += v;
1322 break;
1323 case R_390_8:
1324 *(unsigned char *) loc += v;
1325 break;
1326
1327 case R_390_PC32:
1328 *(unsigned int *) loc += v - dot;
1329 break;
1330 case R_390_PC16DBL:
1331 *(unsigned short *) loc += (v - dot) >> 1;
1332 break;
1333 case R_390_PC16:
1334 *(unsigned short *) loc += v - dot;
1335 break;
1336
1337 case R_390_PLT32:
1338 case R_390_PLT16DBL:
1339 /* find the plt entry and initialize it. */
1340 pe = (struct arch_single_entry *) &isym->pltent;
1341 if (pe->inited == 0) {
1342 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1343 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1344 ip[1] = 0x100607f1;
1345 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1346 ip[2] = v - 2;
1347 else
1348 ip[2] = v;
1349 pe->inited = 1;
1350 }
1351
1352 /* Insert relative distance to target. */
1353 v = plt + pe->offset - dot;
1354 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1355 *(unsigned int *) loc = (unsigned int) v;
1356 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1357 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1358 break;
1359
1360 case R_390_GLOB_DAT:
1361 case R_390_JMP_SLOT:
1362 *loc = v;
1363 break;
1364
1365 case R_390_RELATIVE:
1366 *loc += f->baseaddr;
1367 break;
1368
1369 case R_390_GOTPC:
1370 *(unsigned long *) loc += got - dot;
1371 break;
1372
1373 case R_390_GOT12:
1374 case R_390_GOT16:
1375 case R_390_GOT32:
1376 if (!isym->gotent.inited)
1377 {
1378 isym->gotent.inited = 1;
1379 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1380 }
1381 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1382 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1383 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1384 *(unsigned short *) loc += isym->gotent.offset;
1385 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1386 *(unsigned int *) loc += isym->gotent.offset;
1387 break;
1388
1389# ifndef R_390_GOTOFF32
1390# define R_390_GOTOFF32 R_390_GOTOFF
1391# endif
1392 case R_390_GOTOFF32:
1393 *loc += v - got;
1394 break;
1395
1396#elif defined(__sh__)
1397
1398 case R_SH_NONE:
1399 break;
1400
1401 case R_SH_DIR32:
1402 *loc += v;
1403 break;
1404
1405 case R_SH_REL32:
1406 *loc += v - dot;
1407 break;
1408
1409 case R_SH_PLT32:
1410 *loc = v - dot;
1411 break;
1412
1413 case R_SH_GLOB_DAT:
1414 case R_SH_JMP_SLOT:
1415 *loc = v;
1416 break;
1417
1418 case R_SH_RELATIVE:
1419 *loc = f->baseaddr + rel->r_addend;
1420 break;
1421
1422 case R_SH_GOTPC:
1423 *loc = got - dot + rel->r_addend;
1424 break;
1425
1426 case R_SH_GOT32:
1427 goto bb_use_got;
1428
1429 case R_SH_GOTOFF:
1430 *loc = v - got;
1431 break;
1432
1433# if defined(__SH5__)
1434 case R_SH_IMM_MEDLOW16:
1435 case R_SH_IMM_LOW16:
1436 {
1437 ElfW(Addr) word;
1438
1439 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1440 v >>= 16;
1441
1442 /*
1443 * movi and shori have the format:
1444 *
1445 * | op | imm | reg | reserved |
1446 * 31..26 25..10 9.. 4 3 .. 0
1447 *
1448 * so we simply mask and or in imm.
1449 */
1450 word = *loc & ~0x3fffc00;
1451 word |= (v & 0xffff) << 10;
1452
1453 *loc = word;
1454
1455 break;
1456 }
1457
1458 case R_SH_IMM_MEDLOW16_PCREL:
1459 case R_SH_IMM_LOW16_PCREL:
1460 {
1461 ElfW(Addr) word;
1462
1463 word = *loc & ~0x3fffc00;
1464
1465 v -= dot;
1466
1467 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1468 v >>= 16;
1469
1470 word |= (v & 0xffff) << 10;
1471
1472 *loc = word;
1473
1474 break;
1475 }
1476# endif /* __SH5__ */
1477
1478#elif defined(__v850e__)
1479
1480 case R_V850_NONE:
1481 break;
1482
1483 case R_V850_32:
1484 /* We write two shorts instead of a long because even
1485 32-bit insns only need half-word alignment, but
1486 32-bit data needs to be long-word aligned. */
1487 v += ((unsigned short *)loc)[0];
1488 v += ((unsigned short *)loc)[1] << 16;
1489 ((unsigned short *)loc)[0] = v & 0xffff;
1490 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1491 break;
1492
1493 case R_V850_22_PCREL:
1494 goto bb_use_plt;
1495
1496#elif defined(__x86_64__)
1497
1498 case R_X86_64_NONE:
1499 break;
1500
1501 case R_X86_64_64:
1502 *loc += v;
1503 break;
1504
1505 case R_X86_64_32:
1506 *(unsigned int *) loc += v;
1507 if (v > 0xffffffff)
1508 {
1509 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1510 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1511 }
1512 break;
1513
1514 case R_X86_64_32S:
1515 *(signed int *) loc += v;
1516 break;
1517
1518 case R_X86_64_16:
1519 *(unsigned short *) loc += v;
1520 break;
1521
1522 case R_X86_64_8:
1523 *(unsigned char *) loc += v;
1524 break;
1525
1526 case R_X86_64_PC32:
1527 *(unsigned int *) loc += v - dot;
1528 break;
1529
1530 case R_X86_64_PC16:
1531 *(unsigned short *) loc += v - dot;
1532 break;
1533
1534 case R_X86_64_PC8:
1535 *(unsigned char *) loc += v - dot;
1536 break;
1537
1538 case R_X86_64_GLOB_DAT:
1539 case R_X86_64_JUMP_SLOT:
1540 *loc = v;
1541 break;
1542
1543 case R_X86_64_RELATIVE:
1544 *loc += f->baseaddr;
1545 break;
1546
1547 case R_X86_64_GOT32:
1548 case R_X86_64_GOTPCREL:
1549 goto bb_use_got;
1550# if 0
1551 if (!isym->gotent.reloc_done)
1552 {
1553 isym->gotent.reloc_done = 1;
1554 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1555 }
1556 /* XXX are these really correct? */
1557 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1558 *(unsigned int *) loc += v + isym->gotent.offset;
1559 else
1560 *loc += isym->gotent.offset;
1561 break;
1562# endif
1563
1564#else
1565# warning "no idea how to handle relocations on your arch"
1566#endif
1567
1568 default:
1569 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1570 ret = obj_reloc_unhandled;
1571 break;
1572
1573#if defined(USE_PLT_ENTRIES)
1574
1575bb_use_plt:
1576
1577 /* find the plt entry and initialize it if necessary */
1578
1579#if defined(USE_PLT_LIST)
1580 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1581 pe = pe->next;
1582#else
1583 pe = &isym->pltent;
1584#endif
1585
1586 if (! pe->inited) {
1587 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1588
1589 /* generate some machine code */
1590
1591#if defined(__arm__)
1592 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1593 ip[1] = v; /* sym@ */
1594#endif
1595#if defined(__powerpc__)
1596 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1597 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1598 ip[2] = 0x7d6903a6; /* mtctr r11 */
1599 ip[3] = 0x4e800420; /* bctr */
1600#endif
1601#if defined(__v850e__)
1602 /* We have to trash a register, so we assume that any control
1603 transfer more than 21-bits away must be a function call
1604 (so we can use a call-clobbered register). */
1605 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1606 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
1607#endif
1608 pe->inited = 1;
1609 }
1610
1611 /* relative distance to target */
1612 v -= dot;
1613 /* if the target is too far away.... */
1614#if defined(__arm__) || defined(__powerpc__)
1615 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1616#elif defined(__v850e__)
1617 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1618#endif
1619 /* go via the plt */
1620 v = plt + pe->offset - dot;
1621
1622#if defined(__v850e__)
1623 if (v & 1)
1624#else
1625 if (v & 3)
1626#endif
1627 ret = obj_reloc_dangerous;
1628
1629 /* merge the offset into the instruction. */
1630#if defined(__arm__)
1631 /* Convert to words. */
1632 v >>= 2;
1633
1634 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1635#endif
1636#if defined(__powerpc__)
1637 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1638#endif
1639#if defined(__v850e__)
1640 /* We write two shorts instead of a long because even 32-bit insns
1641 only need half-word alignment, but the 32-bit data write needs
1642 to be long-word aligned. */
1643 ((unsigned short *)loc)[0] =
1644 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1645 | ((v >> 16) & 0x3f); /* offs high part */
1646 ((unsigned short *)loc)[1] =
1647 (v & 0xffff); /* offs low part */
1648#endif
1649 break;
1650#endif /* USE_PLT_ENTRIES */
1651
1652#if defined(USE_GOT_ENTRIES)
1653bb_use_got:
1654
1655 /* needs an entry in the .got: set it, once */
1656 if (!isym->gotent.inited) {
1657 isym->gotent.inited = 1;
1658 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1659 }
1660 /* make the reloc with_respect_to_.got */
1661#if defined(__sh__)
1662 *loc += isym->gotent.offset + rel->r_addend;
1663#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1664 *loc += isym->gotent.offset;
1665#endif
1666 break;
1667
1668#endif /* USE_GOT_ENTRIES */
1669 }
1670
1671 return ret;
1672}
1673
1674
1675#if defined(USE_LIST)
1676
1677static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1678 int offset, int size)
1679{
1680 struct arch_list_entry *pe;
1681
1682 for (pe = *list; pe != NULL; pe = pe->next) {
1683 if (pe->addend == rel->r_addend) {
1684 break;
1685 }
1686 }
1687
1688 if (pe == NULL) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001689 pe = xzalloc(sizeof(struct arch_list_entry));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001690 pe->next = *list;
1691 pe->addend = rel->r_addend;
1692 pe->offset = offset;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00001693 /*pe->inited = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001694 *list = pe;
1695 return size;
1696 }
1697 return 0;
1698}
1699
1700#endif
1701
1702#if defined(USE_SINGLE)
1703
1704static int arch_single_init(/*ElfW(RelM) *rel,*/ struct arch_single_entry *single,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001705 int offset, int size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001706{
1707 if (single->allocated == 0) {
1708 single->allocated = 1;
1709 single->offset = offset;
1710 single->inited = 0;
1711 return size;
1712 }
1713 return 0;
1714}
1715
1716#endif
1717
1718#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1719
1720static struct obj_section *arch_xsect_init(struct obj_file *f, const char *name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001721 int offset, int size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001722{
1723 struct obj_section *myrelsec = obj_find_section(f, name);
1724
1725 if (offset == 0) {
1726 offset += size;
1727 }
1728
1729 if (myrelsec) {
1730 obj_extend_section(myrelsec, offset);
1731 } else {
1732 myrelsec = obj_create_alloced_section(f, name,
1733 size, offset);
1734 }
1735
1736 return myrelsec;
1737}
1738
1739#endif
1740
1741static void arch_create_got(struct obj_file *f)
1742{
1743#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1744 struct arch_file *ifile = (struct arch_file *) f;
1745 int i;
1746#if defined(USE_GOT_ENTRIES)
1747 int got_offset = 0, got_needed = 0, got_allocate;
1748#endif
1749#if defined(USE_PLT_ENTRIES)
1750 int plt_offset = 0, plt_needed = 0, plt_allocate;
1751#endif
1752 struct obj_section *relsec, *symsec, *strsec;
1753 ElfW(RelM) *rel, *relend;
1754 ElfW(Sym) *symtab, *extsym;
1755 const char *strtab, *name;
1756 struct arch_symbol *intsym;
1757
1758 for (i = 0; i < f->header.e_shnum; ++i) {
1759 relsec = f->sections[i];
1760 if (relsec->header.sh_type != SHT_RELM)
1761 continue;
1762
1763 symsec = f->sections[relsec->header.sh_link];
1764 strsec = f->sections[symsec->header.sh_link];
1765
1766 rel = (ElfW(RelM) *) relsec->contents;
1767 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1768 symtab = (ElfW(Sym) *) symsec->contents;
1769 strtab = (const char *) strsec->contents;
1770
1771 for (; rel < relend; ++rel) {
1772 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1773
1774#if defined(USE_GOT_ENTRIES)
1775 got_allocate = 0;
1776#endif
1777#if defined(USE_PLT_ENTRIES)
1778 plt_allocate = 0;
1779#endif
1780
1781 switch (ELF_R_TYPE(rel->r_info)) {
1782#if defined(__arm__)
1783 case R_ARM_PC24:
1784 case R_ARM_PLT32:
1785 plt_allocate = 1;
1786 break;
1787
1788 case R_ARM_GOTOFF:
1789 case R_ARM_GOTPC:
1790 got_needed = 1;
1791 continue;
1792
1793 case R_ARM_GOT32:
1794 got_allocate = 1;
1795 break;
1796
1797#elif defined(__i386__)
1798 case R_386_GOTPC:
1799 case R_386_GOTOFF:
1800 got_needed = 1;
1801 continue;
1802
1803 case R_386_GOT32:
1804 got_allocate = 1;
1805 break;
1806
1807#elif defined(__powerpc__)
1808 case R_PPC_REL24:
1809 plt_allocate = 1;
1810 break;
1811
1812#elif defined(__mc68000__)
1813 case R_68K_GOT32:
1814 got_allocate = 1;
1815 break;
1816
1817#ifdef R_68K_GOTOFF
1818 case R_68K_GOTOFF:
1819 got_needed = 1;
1820 continue;
1821#endif
1822
1823#elif defined(__sh__)
1824 case R_SH_GOT32:
1825 got_allocate = 1;
1826 break;
1827
1828 case R_SH_GOTPC:
1829 case R_SH_GOTOFF:
1830 got_needed = 1;
1831 continue;
1832
1833#elif defined(__v850e__)
1834 case R_V850_22_PCREL:
1835 plt_needed = 1;
1836 break;
1837
1838#endif
1839 default:
1840 continue;
1841 }
1842
1843 if (extsym->st_name != 0) {
1844 name = strtab + extsym->st_name;
1845 } else {
1846 name = f->sections[extsym->st_shndx]->name;
1847 }
1848 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1849#if defined(USE_GOT_ENTRIES)
1850 if (got_allocate) {
1851 got_offset += arch_single_init(
1852 /*rel,*/ &intsym->gotent,
1853 got_offset, GOT_ENTRY_SIZE);
1854
1855 got_needed = 1;
1856 }
1857#endif
1858#if defined(USE_PLT_ENTRIES)
1859 if (plt_allocate) {
1860#if defined(USE_PLT_LIST)
1861 plt_offset += arch_list_add(
1862 rel, &intsym->pltent,
1863 plt_offset, PLT_ENTRY_SIZE);
1864#else
1865 plt_offset += arch_single_init(
1866 /*rel,*/ &intsym->pltent,
1867 plt_offset, PLT_ENTRY_SIZE);
1868#endif
1869 plt_needed = 1;
1870 }
1871#endif
1872 }
1873 }
1874
1875#if defined(USE_GOT_ENTRIES)
1876 if (got_needed) {
1877 ifile->got = arch_xsect_init(f, ".got", got_offset,
1878 GOT_ENTRY_SIZE);
1879 }
1880#endif
1881
1882#if defined(USE_PLT_ENTRIES)
1883 if (plt_needed) {
1884 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1885 PLT_ENTRY_SIZE);
1886 }
1887#endif
1888
1889#endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */
1890}
1891
1892/*======================================================================*/
1893
1894/* Standard ELF hash function. */
1895static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1896{
1897 unsigned long h = 0;
1898 unsigned long g;
1899 unsigned char ch;
1900
1901 while (n > 0) {
1902 ch = *name++;
1903 h = (h << 4) + ch;
1904 g = (h & 0xf0000000);
1905 if (g != 0) {
1906 h ^= g >> 24;
1907 h &= ~g;
1908 }
1909 n--;
1910 }
1911 return h;
1912}
1913
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001914static unsigned long FAST_FUNC obj_elf_hash(const char *name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001915{
1916 return obj_elf_hash_n(name, strlen(name));
1917}
1918
1919#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
1920/* String comparison for non-co-versioned kernel and module. */
1921
1922static int ncv_strcmp(const char *a, const char *b)
1923{
1924 size_t alen = strlen(a), blen = strlen(b);
1925
1926 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1927 return strncmp(a, b, alen);
1928 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1929 return strncmp(a, b, blen);
1930 else
1931 return strcmp(a, b);
1932}
1933
1934/* String hashing for non-co-versioned kernel and module. Here
1935 we are simply forced to drop the crc from the hash. */
1936
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001937static unsigned long FAST_FUNC ncv_symbol_hash(const char *str)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001938{
1939 size_t len = strlen(str);
1940 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1941 len -= 10;
1942 return obj_elf_hash_n(str, len);
1943}
1944
1945static void
1946obj_set_symbol_compare(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001947 int (*cmp) (const char *, const char *),
1948 unsigned long (*hash) (const char *) FAST_FUNC)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001949{
1950 if (cmp)
1951 f->symbol_cmp = cmp;
1952 if (hash) {
1953 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1954 int i;
1955
1956 f->symbol_hash = hash;
1957
1958 memcpy(tmptab, f->symtab, sizeof(tmptab));
1959 memset(f->symtab, 0, sizeof(f->symtab));
1960
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001961 for (i = 0; i < HASH_BUCKETS; ++i) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001962 for (sym = tmptab[i]; sym; sym = next) {
1963 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1964 next = sym->next;
1965 sym->next = f->symtab[h];
1966 f->symtab[h] = sym;
1967 }
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001968 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001969 }
1970}
1971
1972#endif /* FEATURE_INSMOD_VERSION_CHECKING */
1973
1974static struct obj_symbol *
1975obj_add_symbol(struct obj_file *f, const char *name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02001976 unsigned long symidx, int info,
1977 int secidx, ElfW(Addr) value,
1978 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00001979{
1980 struct obj_symbol *sym;
1981 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1982 int n_type = ELF_ST_TYPE(info);
1983 int n_binding = ELF_ST_BIND(info);
1984
1985 for (sym = f->symtab[hash]; sym; sym = sym->next) {
1986 if (f->symbol_cmp(sym->name, name) == 0) {
1987 int o_secidx = sym->secidx;
1988 int o_info = sym->info;
1989 int o_type = ELF_ST_TYPE(o_info);
1990 int o_binding = ELF_ST_BIND(o_info);
1991
1992 /* A redefinition! Is it legal? */
1993
1994 if (secidx == SHN_UNDEF)
1995 return sym;
1996 else if (o_secidx == SHN_UNDEF)
1997 goto found;
1998 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1999 /* Cope with local and global symbols of the same name
2000 in the same object file, as might have been created
2001 by ld -r. The only reason locals are now seen at this
2002 level at all is so that we can do semi-sensible things
2003 with parameters. */
2004
2005 struct obj_symbol *nsym, **p;
2006
2007 nsym = arch_new_symbol();
2008 nsym->next = sym->next;
2009 nsym->ksymidx = -1;
2010
2011 /* Excise the old (local) symbol from the hash chain. */
2012 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2013 continue;
2014 *p = sym = nsym;
2015 goto found;
2016 } else if (n_binding == STB_LOCAL) {
2017 /* Another symbol of the same name has already been defined.
2018 Just add this to the local table. */
2019 sym = arch_new_symbol();
2020 sym->next = NULL;
2021 sym->ksymidx = -1;
2022 f->local_symtab[symidx] = sym;
2023 goto found;
2024 } else if (n_binding == STB_WEAK)
2025 return sym;
2026 else if (o_binding == STB_WEAK)
2027 goto found;
2028 /* Don't unify COMMON symbols with object types the programmer
2029 doesn't expect. */
2030 else if (secidx == SHN_COMMON
2031 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2032 return sym;
2033 else if (o_secidx == SHN_COMMON
2034 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2035 goto found;
2036 else {
2037 /* Don't report an error if the symbol is coming from
2038 the kernel or some external module. */
2039 if (secidx <= SHN_HIRESERVE)
2040 bb_error_msg("%s multiply defined", name);
2041 return sym;
2042 }
2043 }
2044 }
2045
2046 /* Completely new symbol. */
2047 sym = arch_new_symbol();
2048 sym->next = f->symtab[hash];
2049 f->symtab[hash] = sym;
2050 sym->ksymidx = -1;
2051 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
2052 if (symidx >= f->local_symtab_size)
2053 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2054 name, (long) symidx, (long) f->local_symtab_size);
2055 else
2056 f->local_symtab[symidx] = sym;
2057 }
2058
2059found:
2060 sym->name = name;
2061 sym->value = value;
2062 sym->size = size;
2063 sym->secidx = secidx;
2064 sym->info = info;
2065
2066 return sym;
2067}
2068
2069static struct obj_symbol *
2070obj_find_symbol(struct obj_file *f, const char *name)
2071{
2072 struct obj_symbol *sym;
2073 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2074
2075 for (sym = f->symtab[hash]; sym; sym = sym->next)
2076 if (f->symbol_cmp(sym->name, name) == 0)
2077 return sym;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002078 return NULL;
2079}
2080
2081static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2082{
2083 if (sym) {
2084 if (sym->secidx >= SHN_LORESERVE)
2085 return sym->value;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002086 return sym->value + f->sections[sym->secidx]->header.sh_addr;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002087 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002088 /* As a special case, a NULL sym has value zero. */
2089 return 0;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002090}
2091
2092static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2093{
2094 int i, n = f->header.e_shnum;
2095
2096 for (i = 0; i < n; ++i)
2097 if (strcmp(f->sections[i]->name, name) == 0)
2098 return f->sections[i];
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002099 return NULL;
2100}
2101
2102static int obj_load_order_prio(struct obj_section *a)
2103{
2104 unsigned long af, ac;
2105
2106 af = a->header.sh_flags;
2107
2108 ac = 0;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002109 if (a->name[0] != '.' || strlen(a->name) != 10
2110 || strcmp(a->name + 5, ".init") != 0
2111 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002112 ac |= 32;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002113 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002114 if (af & SHF_ALLOC)
2115 ac |= 16;
2116 if (!(af & SHF_WRITE))
2117 ac |= 8;
2118 if (af & SHF_EXECINSTR)
2119 ac |= 4;
2120 if (a->header.sh_type != SHT_NOBITS)
2121 ac |= 2;
2122
2123 return ac;
2124}
2125
2126static void
2127obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2128{
2129 struct obj_section **p;
2130 int prio = obj_load_order_prio(sec);
2131 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2132 if (obj_load_order_prio(*p) < prio)
2133 break;
2134 sec->load_next = *p;
2135 *p = sec;
2136}
2137
Denis Vlasenko49325962009-01-31 23:33:54 +00002138static struct obj_section *helper_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002139 const char *name,
2140 unsigned long align,
2141 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002142{
2143 int newidx = f->header.e_shnum++;
2144 struct obj_section *sec;
2145
2146 f->sections = xrealloc_vector(f->sections, 2, newidx);
2147 f->sections[newidx] = sec = arch_new_section();
2148
2149 sec->header.sh_type = SHT_PROGBITS;
2150 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2151 sec->header.sh_size = size;
2152 sec->header.sh_addralign = align;
2153 sec->name = name;
2154 sec->idx = newidx;
2155 if (size)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002156 sec->contents = xzalloc(size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002157
Denis Vlasenko49325962009-01-31 23:33:54 +00002158 return sec;
2159}
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002160
Denis Vlasenko49325962009-01-31 23:33:54 +00002161static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002162 const char *name,
2163 unsigned long align,
2164 unsigned long size)
Denis Vlasenko49325962009-01-31 23:33:54 +00002165{
2166 struct obj_section *sec;
2167
2168 sec = helper_create_alloced_section(f, name, align, size);
2169 obj_insert_section_load_order(f, sec);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002170 return sec;
2171}
2172
2173static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002174 const char *name,
2175 unsigned long align,
2176 unsigned long size)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002177{
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002178 struct obj_section *sec;
2179
Denis Vlasenko49325962009-01-31 23:33:54 +00002180 sec = helper_create_alloced_section(f, name, align, size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002181 sec->load_next = f->load_order;
2182 f->load_order = sec;
2183 if (f->load_order_search_start == &f->load_order)
2184 f->load_order_search_start = &sec->load_next;
2185
2186 return sec;
2187}
2188
2189static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2190{
2191 unsigned long oldsize = sec->header.sh_size;
2192 if (more) {
2193 sec->header.sh_size += more;
2194 sec->contents = xrealloc(sec->contents, sec->header.sh_size);
2195 }
2196 return sec->contents + oldsize;
2197}
2198
2199
2200/* Conditionally add the symbols from the given symbol set to the
2201 new module. */
2202
Denis Vlasenko49325962009-01-31 23:33:54 +00002203static int add_symbols_from(struct obj_file *f,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002204 int idx,
2205 struct new_module_symbol *syms,
2206 size_t nsyms)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002207{
2208 struct new_module_symbol *s;
2209 size_t i;
2210 int used = 0;
2211#ifdef SYMBOL_PREFIX
Denis Vlasenko49325962009-01-31 23:33:54 +00002212 char *name_buf = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002213 size_t name_alloced_size = 0;
2214#endif
2215#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2216 int gpl;
2217
2218 gpl = obj_gpl_license(f, NULL) == 0;
2219#endif
2220 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2221 /* Only add symbols that are already marked external.
2222 If we override locals we may cause problems for
2223 argument initialization. We will also create a false
2224 dependency on the module. */
2225 struct obj_symbol *sym;
2226 char *name;
2227
2228 /* GPL licensed modules can use symbols exported with
2229 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2230 * exported names. Non-GPL modules never see any GPLONLY_
2231 * symbols so they cannot fudge it by adding the prefix on
2232 * their references.
2233 */
2234 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2235#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2236 if (gpl)
2237 s->name += 8;
2238 else
2239#endif
2240 continue;
2241 }
2242 name = (char *)s->name;
2243
2244#ifdef SYMBOL_PREFIX
2245 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2246 kernel exports `C names', but module object files
2247 reference `linker names'). */
2248 size_t extra = sizeof SYMBOL_PREFIX;
2249 size_t name_size = strlen(name) + extra;
2250 if (name_size > name_alloced_size) {
2251 name_alloced_size = name_size * 2;
2252 name_buf = alloca(name_alloced_size);
2253 }
2254 strcpy(name_buf, SYMBOL_PREFIX);
2255 strcpy(name_buf + extra - 1, name);
2256 name = name_buf;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002257#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002258
2259 sym = obj_find_symbol(f, name);
2260 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2261#ifdef SYMBOL_PREFIX
2262 /* Put NAME_BUF into more permanent storage. */
2263 name = xmalloc(name_size);
2264 strcpy(name, name_buf);
2265#endif
2266 sym = obj_add_symbol(f, name, -1,
2267 ELF_ST_INFO(STB_GLOBAL,
2268 STT_NOTYPE),
2269 idx, s->value, 0);
2270 /* Did our symbol just get installed? If so, mark the
2271 module as "used". */
2272 if (sym->secidx == idx)
2273 used = 1;
2274 }
2275 }
2276
2277 return used;
2278}
2279
2280static void add_kernel_symbols(struct obj_file *f)
2281{
2282 struct external_module *m;
2283 int i, nused = 0;
2284
2285 /* Add module symbols first. */
2286
2287 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) {
2288 if (m->nsyms
2289 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms)
2290 ) {
2291 m->used = 1;
2292 ++nused;
2293 }
2294 }
2295
2296 n_ext_modules_used = nused;
2297
2298 /* And finally the symbols from the kernel proper. */
2299
2300 if (nksyms)
2301 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2302}
2303
2304static char *get_modinfo_value(struct obj_file *f, const char *key)
2305{
2306 struct obj_section *sec;
2307 char *p, *v, *n, *ep;
2308 size_t klen = strlen(key);
2309
2310 sec = obj_find_section(f, ".modinfo");
2311 if (sec == NULL)
2312 return NULL;
2313 p = sec->contents;
2314 ep = p + sec->header.sh_size;
2315 while (p < ep) {
2316 v = strchr(p, '=');
2317 n = strchr(p, '\0');
2318 if (v) {
2319 if (p + klen == v && strncmp(p, key, klen) == 0)
2320 return v + 1;
2321 } else {
2322 if (p + klen == n && strcmp(p, key) == 0)
2323 return n;
2324 }
2325 p = n + 1;
2326 }
2327
2328 return NULL;
2329}
2330
2331
2332/*======================================================================*/
2333/* Functions relating to module loading after 2.1.18. */
2334
2335/* From Linux-2.6 sources */
2336/* You can use " around spaces, but can't escape ". */
2337/* Hyphens and underscores equivalent in parameter names. */
2338static char *next_arg(char *args, char **param, char **val)
2339{
2340 unsigned int i, equals = 0;
2341 int in_quote = 0, quoted = 0;
2342 char *next;
2343
2344 if (*args == '"') {
2345 args++;
2346 in_quote = 1;
2347 quoted = 1;
2348 }
2349
2350 for (i = 0; args[i]; i++) {
2351 if (args[i] == ' ' && !in_quote)
2352 break;
2353 if (equals == 0) {
2354 if (args[i] == '=')
2355 equals = i;
2356 }
2357 if (args[i] == '"')
2358 in_quote = !in_quote;
2359 }
2360
2361 *param = args;
2362 if (!equals)
2363 *val = NULL;
2364 else {
2365 args[equals] = '\0';
2366 *val = args + equals + 1;
2367
2368 /* Don't include quotes in value. */
2369 if (**val == '"') {
2370 (*val)++;
2371 if (args[i-1] == '"')
2372 args[i-1] = '\0';
2373 }
2374 if (quoted && args[i-1] == '"')
2375 args[i-1] = '\0';
2376 }
2377
2378 if (args[i]) {
2379 args[i] = '\0';
2380 next = args + i + 1;
2381 } else
2382 next = args + i;
2383
2384 /* Chew up trailing spaces. */
2385 return skip_whitespace(next);
2386}
2387
2388static void
2389new_process_module_arguments(struct obj_file *f, const char *options)
2390{
2391 char *xoptions, *pos;
2392 char *param, *val;
2393
2394 xoptions = pos = xstrdup(skip_whitespace(options));
2395 while (*pos) {
2396 unsigned long charssize = 0;
2397 char *tmp, *contents, *loc, *pinfo, *p;
2398 struct obj_symbol *sym;
2399 int min, max, n, len;
2400
2401 pos = next_arg(pos, &param, &val);
2402
2403 tmp = xasprintf("parm_%s", param);
2404 pinfo = get_modinfo_value(f, tmp);
2405 free(tmp);
2406 if (pinfo == NULL)
2407 bb_error_msg_and_die("invalid parameter %s", param);
2408
2409#ifdef SYMBOL_PREFIX
2410 tmp = xasprintf(SYMBOL_PREFIX "%s", param);
2411 sym = obj_find_symbol(f, tmp);
2412 free(tmp);
2413#else
2414 sym = obj_find_symbol(f, param);
2415#endif
2416
2417 /* Also check that the parameter was not resolved from the kernel. */
2418 if (sym == NULL || sym->secidx > SHN_HIRESERVE)
2419 bb_error_msg_and_die("symbol for parameter %s not found", param);
2420
2421 /* Number of parameters */
2422 if (isdigit(*pinfo)) {
2423 min = strtoul(pinfo, &pinfo, 10);
2424 if (*pinfo == '-')
2425 max = strtoul(pinfo + 1, &pinfo, 10);
2426 else
2427 max = min;
2428 } else
2429 min = max = 1;
2430
2431 contents = f->sections[sym->secidx]->contents;
2432 loc = contents + sym->value;
2433
2434 if (*pinfo == 'c') {
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002435 if (!isdigit(pinfo[1])) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002436 bb_error_msg_and_die("parameter type 'c' for %s must be followed by"
2437 " the maximum size", param);
2438 }
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002439 charssize = strtoul(pinfo + 1, NULL, 10);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002440 }
2441
2442 if (val == NULL) {
2443 if (*pinfo != 'b')
2444 bb_error_msg_and_die("argument expected for parameter %s", param);
2445 val = (char *) "1";
2446 }
2447
2448 /* Parse parameter values */
2449 n = 0;
2450 p = val;
2451 while (*p != 0) {
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002452 char *endp;
2453
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002454 if (++n > max)
2455 bb_error_msg_and_die("too many values for %s (max %d)", param, max);
2456
2457 switch (*pinfo) {
2458 case 's':
2459 len = strcspn(p, ",");
2460 p[len] = 0;
2461 obj_string_patch(f, sym->secidx,
2462 loc - contents, p);
2463 loc += tgt_sizeof_char_p;
2464 p += len;
2465 break;
2466 case 'c':
2467 len = strcspn(p, ",");
2468 p[len] = 0;
2469 if (len >= charssize)
2470 bb_error_msg_and_die("string too long for %s (max %ld)", param,
2471 charssize - 1);
2472 strcpy((char *) loc, p);
2473 loc += charssize;
2474 p += len;
2475 break;
2476 case 'b':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002477 *loc++ = strtoul(p, &endp, 0);
2478 p = endp; /* gcc likes temp var for &endp */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002479 break;
2480 case 'h':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002481 *(short *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002482 loc += tgt_sizeof_short;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002483 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002484 break;
2485 case 'i':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002486 *(int *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002487 loc += tgt_sizeof_int;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002488 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002489 break;
2490 case 'l':
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002491 *(long *) loc = strtoul(p, &endp, 0);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002492 loc += tgt_sizeof_long;
Denys Vlasenko1f27ab02009-09-23 17:17:53 +02002493 p = endp;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002494 break;
2495 default:
2496 bb_error_msg_and_die("unknown parameter type '%c' for %s",
2497 *pinfo, param);
2498 }
2499
2500 p = skip_whitespace(p);
2501 if (*p != ',')
2502 break;
2503 p = skip_whitespace(p + 1);
2504 }
2505
2506 if (n < min)
2507 bb_error_msg_and_die("parameter %s requires at least %d arguments", param, min);
2508 if (*p != '\0')
2509 bb_error_msg_and_die("invalid argument syntax for %s", param);
2510 }
2511
2512 free(xoptions);
2513}
2514
2515#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
2516static int new_is_module_checksummed(struct obj_file *f)
2517{
2518 const char *p = get_modinfo_value(f, "using_checksums");
2519 if (p)
2520 return xatoi(p);
2521 return 0;
2522}
2523
2524/* Get the module's kernel version in the canonical integer form. */
2525
2526static int
2527new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2528{
2529 char *p, *q;
2530 int a, b, c;
2531
2532 p = get_modinfo_value(f, "kernel_version");
2533 if (p == NULL)
2534 return -1;
2535 safe_strncpy(str, p, STRVERSIONLEN);
2536
2537 a = strtoul(p, &p, 10);
2538 if (*p != '.')
2539 return -1;
2540 b = strtoul(p + 1, &p, 10);
2541 if (*p != '.')
2542 return -1;
2543 c = strtoul(p + 1, &q, 10);
2544 if (p + 1 == q)
2545 return -1;
2546
2547 return a << 16 | b << 8 | c;
2548}
2549
2550#endif /* FEATURE_INSMOD_VERSION_CHECKING */
2551
2552
2553/* Fetch the loaded modules, and all currently exported symbols. */
2554
2555static void new_get_kernel_symbols(void)
2556{
2557 char *module_names, *mn;
2558 struct external_module *modules, *m;
2559 struct new_module_symbol *syms, *s;
2560 size_t ret, bufsize, nmod, nsyms, i, j;
2561
2562 /* Collect the loaded modules. */
2563
2564 bufsize = 256;
2565 module_names = xmalloc(bufsize);
2566
2567 retry_modules_load:
2568 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2569 if (errno == ENOSPC && bufsize < ret) {
2570 bufsize = ret;
2571 module_names = xrealloc(module_names, bufsize);
2572 goto retry_modules_load;
2573 }
2574 bb_perror_msg_and_die("QM_MODULES");
2575 }
2576
2577 n_ext_modules = nmod = ret;
2578
2579 /* Collect the modules' symbols. */
2580
2581 if (nmod) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002582 ext_modules = modules = xzalloc(nmod * sizeof(*modules));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002583 for (i = 0, mn = module_names, m = modules;
2584 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2585 struct new_module_info info;
2586
2587 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2588 if (errno == ENOENT) {
2589 /* The module was removed out from underneath us. */
2590 continue;
2591 }
2592 bb_perror_msg_and_die("query_module: QM_INFO: %s", mn);
2593 }
2594
2595 bufsize = 1024;
2596 syms = xmalloc(bufsize);
2597 retry_mod_sym_load:
2598 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2599 switch (errno) {
2600 case ENOSPC:
2601 bufsize = ret;
2602 syms = xrealloc(syms, bufsize);
2603 goto retry_mod_sym_load;
2604 case ENOENT:
2605 /* The module was removed out from underneath us. */
2606 continue;
2607 default:
2608 bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn);
2609 }
2610 }
2611 nsyms = ret;
2612
2613 m->name = mn;
2614 m->addr = info.addr;
2615 m->nsyms = nsyms;
2616 m->syms = syms;
2617
2618 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2619 s->name += (unsigned long) syms;
2620 }
2621 }
2622 }
2623
2624 /* Collect the kernel's symbols. */
2625
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002626 bufsize = 16 * 1024;
2627 syms = xmalloc(bufsize);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002628 retry_kern_sym_load:
2629 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2630 if (errno == ENOSPC && bufsize < ret) {
2631 bufsize = ret;
2632 syms = xrealloc(syms, bufsize);
2633 goto retry_kern_sym_load;
2634 }
2635 bb_perror_msg_and_die("kernel: QM_SYMBOLS");
2636 }
2637 nksyms = nsyms = ret;
2638 ksyms = syms;
2639
2640 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2641 s->name += (unsigned long) syms;
2642 }
2643}
2644
2645
2646/* Return the kernel symbol checksum version, or zero if not used. */
2647
2648static int new_is_kernel_checksummed(void)
2649{
2650 struct new_module_symbol *s;
2651 size_t i;
2652
2653 /* Using_Versions is not the first symbol, but it should be in there. */
2654
2655 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2656 if (strcmp((char *) s->name, "Using_Versions") == 0)
2657 return s->value;
2658
2659 return 0;
2660}
2661
2662
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002663static void new_create_this_module(struct obj_file *f, const char *m_name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002664{
2665 struct obj_section *sec;
2666
2667 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2668 sizeof(struct new_module));
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002669 /* done by obj_create_alloced_section_first: */
2670 /*memset(sec->contents, 0, sizeof(struct new_module));*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002671
2672 obj_add_symbol(f, SPFX "__this_module", -1,
2673 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2674 sizeof(struct new_module));
2675
2676 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2677 m_name);
2678}
2679
2680#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2681/* add an entry to the __ksymtab section, creating it if necessary */
2682static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2683{
2684 struct obj_section *sec;
2685 ElfW(Addr) ofs;
2686
2687 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2688 * If __ksymtab is defined but not marked alloc, x out the first character
2689 * (no obj_delete routine) and create a new __ksymtab with the correct
2690 * characteristics.
2691 */
2692 sec = obj_find_section(f, "__ksymtab");
2693 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2694 *((char *)(sec->name)) = 'x'; /* override const */
2695 sec = NULL;
2696 }
2697 if (!sec)
2698 sec = obj_create_alloced_section(f, "__ksymtab",
2699 tgt_sizeof_void_p, 0);
2700 if (!sec)
2701 return;
2702 sec->header.sh_flags |= SHF_ALLOC;
2703 /* Empty section might be byte-aligned */
2704 sec->header.sh_addralign = tgt_sizeof_void_p;
2705 ofs = sec->header.sh_size;
2706 obj_symbol_patch(f, sec->idx, ofs, sym);
2707 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2708 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2709}
2710#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
2711
2712static int new_create_module_ksymtab(struct obj_file *f)
2713{
2714 struct obj_section *sec;
2715 int i;
2716
2717 /* We must always add the module references. */
2718
2719 if (n_ext_modules_used) {
2720 struct new_module_ref *dep;
2721 struct obj_symbol *tm;
2722
2723 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2724 (sizeof(struct new_module_ref)
2725 * n_ext_modules_used));
2726 if (!sec)
2727 return 0;
2728
2729 tm = obj_find_symbol(f, SPFX "__this_module");
2730 dep = (struct new_module_ref *) sec->contents;
2731 for (i = 0; i < n_ext_modules; ++i)
2732 if (ext_modules[i].used) {
2733 dep->dep = ext_modules[i].addr;
2734 obj_symbol_patch(f, sec->idx,
2735 (char *) &dep->ref - sec->contents, tm);
2736 dep->next_ref = 0;
2737 ++dep;
2738 }
2739 }
2740
2741 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
2742 size_t nsyms;
2743 int *loaded;
2744
2745 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
2746
2747 /* We don't want to export symbols residing in sections that
2748 aren't loaded. There are a number of these created so that
2749 we make sure certain module options don't appear twice. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002750 i = f->header.e_shnum;
2751 loaded = alloca(sizeof(int) * i);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002752 while (--i >= 0)
2753 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2754
2755 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2756 struct obj_symbol *sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002757 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002758 if (ELF_ST_BIND(sym->info) != STB_LOCAL
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002759 && sym->secidx <= SHN_HIRESERVE
2760 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002761 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002762 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2763
2764 obj_symbol_patch(f, sec->idx, ofs, sym);
2765 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2766 sym->name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002767 nsyms++;
2768 }
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002769 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002770 }
2771
2772 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2773 }
2774
2775 return 1;
2776}
2777
2778
2779static int
2780new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2781{
2782 struct new_module *module;
2783 struct obj_section *sec;
2784 void *image;
2785 int ret;
2786 tgt_long m_addr;
2787
2788 sec = obj_find_section(f, ".this");
2789 if (!sec || !sec->contents) {
2790 bb_perror_msg_and_die("corrupt module %s?", m_name);
2791 }
2792 module = (struct new_module *) sec->contents;
2793 m_addr = sec->header.sh_addr;
2794
2795 module->size_of_struct = sizeof(*module);
2796 module->size = m_size;
2797 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2798
2799 sec = obj_find_section(f, "__ksymtab");
2800 if (sec && sec->header.sh_size) {
2801 module->syms = sec->header.sh_addr;
2802 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2803 }
2804
2805 if (n_ext_modules_used) {
2806 sec = obj_find_section(f, ".kmodtab");
2807 module->deps = sec->header.sh_addr;
2808 module->ndeps = n_ext_modules_used;
2809 }
2810
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002811 module->init = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2812 module->cleanup = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002813
2814 sec = obj_find_section(f, "__ex_table");
2815 if (sec) {
2816 module->ex_table_start = sec->header.sh_addr;
2817 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2818 }
2819
2820 sec = obj_find_section(f, ".text.init");
2821 if (sec) {
2822 module->runsize = sec->header.sh_addr - m_addr;
2823 }
2824 sec = obj_find_section(f, ".data.init");
2825 if (sec) {
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002826 if (!module->runsize
2827 || module->runsize > sec->header.sh_addr - m_addr
2828 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002829 module->runsize = sec->header.sh_addr - m_addr;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00002830 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002831 }
2832 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2833 if (sec && sec->header.sh_size) {
2834 module->archdata_start = (void*)sec->header.sh_addr;
2835 module->archdata_end = module->archdata_start + sec->header.sh_size;
2836 }
2837 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2838 if (sec && sec->header.sh_size) {
2839 module->kallsyms_start = (void*)sec->header.sh_addr;
2840 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2841 }
2842
2843 /* Whew! All of the initialization is complete. Collect the final
2844 module image and give it to the kernel. */
2845
2846 image = xmalloc(m_size);
2847 obj_create_image(f, image);
2848
2849 ret = init_module(m_name, (struct new_module *) image);
2850 if (ret)
2851 bb_perror_msg("init_module: %s", m_name);
2852
2853 free(image);
2854
2855 return ret == 0;
2856}
2857
2858
2859/*======================================================================*/
2860
2861static void
2862obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2863 const char *string)
2864{
2865 struct obj_string_patch *p;
2866 struct obj_section *strsec;
2867 size_t len = strlen(string) + 1;
2868 char *loc;
2869
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002870 p = xzalloc(sizeof(*p));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002871 p->next = f->string_patches;
2872 p->reloc_secidx = secidx;
2873 p->reloc_offset = offset;
2874 f->string_patches = p;
2875
2876 strsec = obj_find_section(f, ".kstrtab");
2877 if (strsec == NULL) {
2878 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002879 /*p->string_offset = 0;*/
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002880 loc = strsec->contents;
2881 } else {
2882 p->string_offset = strsec->header.sh_size;
2883 loc = obj_extend_section(strsec, len);
2884 }
2885 memcpy(loc, string, len);
2886}
2887
2888static void
2889obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02002890 struct obj_symbol *sym)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002891{
2892 struct obj_symbol_patch *p;
2893
2894 p = xmalloc(sizeof(*p));
2895 p->next = f->symbol_patches;
2896 p->reloc_secidx = secidx;
2897 p->reloc_offset = offset;
2898 p->sym = sym;
2899 f->symbol_patches = p;
2900}
2901
2902static void obj_check_undefineds(struct obj_file *f)
2903{
2904 unsigned i;
2905
2906 for (i = 0; i < HASH_BUCKETS; ++i) {
2907 struct obj_symbol *sym;
Denis Vlasenko49325962009-01-31 23:33:54 +00002908 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002909 if (sym->secidx == SHN_UNDEF) {
2910 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
2911 sym->secidx = SHN_ABS;
2912 sym->value = 0;
2913 } else {
2914 if (!flag_quiet)
2915 bb_error_msg_and_die("unresolved symbol %s", sym->name);
2916 }
2917 }
Denis Vlasenko49325962009-01-31 23:33:54 +00002918 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002919 }
2920}
2921
2922static void obj_allocate_commons(struct obj_file *f)
2923{
2924 struct common_entry {
2925 struct common_entry *next;
2926 struct obj_symbol *sym;
2927 } *common_head = NULL;
2928
2929 unsigned long i;
2930
2931 for (i = 0; i < HASH_BUCKETS; ++i) {
2932 struct obj_symbol *sym;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002933 for (sym = f->symtab[i]; sym; sym = sym->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002934 if (sym->secidx == SHN_COMMON) {
2935 /* Collect all COMMON symbols and sort them by size so as to
2936 minimize space wasted by alignment requirements. */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002937 struct common_entry **p, *n;
2938 for (p = &common_head; *p; p = &(*p)->next)
2939 if (sym->size <= (*p)->sym->size)
2940 break;
2941 n = alloca(sizeof(*n));
2942 n->next = *p;
2943 n->sym = sym;
2944 *p = n;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002945 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002946 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002947 }
2948
2949 for (i = 1; i < f->local_symtab_size; ++i) {
2950 struct obj_symbol *sym = f->local_symtab[i];
2951 if (sym && sym->secidx == SHN_COMMON) {
2952 struct common_entry **p, *n;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002953 for (p = &common_head; *p; p = &(*p)->next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002954 if (sym == (*p)->sym)
2955 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002956 if (sym->size < (*p)->sym->size) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002957 n = alloca(sizeof(*n));
2958 n->next = *p;
2959 n->sym = sym;
2960 *p = n;
2961 break;
2962 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00002963 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002964 }
2965 }
2966
2967 if (common_head) {
2968 /* Find the bss section. */
2969 for (i = 0; i < f->header.e_shnum; ++i)
2970 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2971 break;
2972
2973 /* If for some reason there hadn't been one, create one. */
2974 if (i == f->header.e_shnum) {
2975 struct obj_section *sec;
2976
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00002977 f->header.e_shnum++;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002978 f->sections = xrealloc_vector(f->sections, 2, i);
2979 f->sections[i] = sec = arch_new_section();
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00002980
2981 sec->header.sh_type = SHT_PROGBITS;
2982 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2983 sec->name = ".bss";
2984 sec->idx = i;
2985 }
2986
2987 /* Allocate the COMMONS. */
2988 {
2989 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2990 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2991 struct common_entry *c;
2992
2993 for (c = common_head; c; c = c->next) {
2994 ElfW(Addr) align = c->sym->value;
2995
2996 if (align > max_align)
2997 max_align = align;
2998 if (bss_size & (align - 1))
2999 bss_size = (bss_size | (align - 1)) + 1;
3000
3001 c->sym->secidx = i;
3002 c->sym->value = bss_size;
3003
3004 bss_size += c->sym->size;
3005 }
3006
3007 f->sections[i]->header.sh_size = bss_size;
3008 f->sections[i]->header.sh_addralign = max_align;
3009 }
3010 }
3011
3012 /* For the sake of patch relocation and parameter initialization,
3013 allocate zeroed data for NOBITS sections now. Note that after
3014 this we cannot assume NOBITS are really empty. */
3015 for (i = 0; i < f->header.e_shnum; ++i) {
3016 struct obj_section *s = f->sections[i];
3017 if (s->header.sh_type == SHT_NOBITS) {
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003018 s->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003019 if (s->header.sh_size != 0)
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003020 s->contents = xzalloc(s->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003021 s->header.sh_type = SHT_PROGBITS;
3022 }
3023 }
3024}
3025
3026static unsigned long obj_load_size(struct obj_file *f)
3027{
3028 unsigned long dot = 0;
3029 struct obj_section *sec;
3030
3031 /* Finalize the positions of the sections relative to one another. */
3032
3033 for (sec = f->load_order; sec; sec = sec->load_next) {
3034 ElfW(Addr) align;
3035
3036 align = sec->header.sh_addralign;
3037 if (align && (dot & (align - 1)))
3038 dot = (dot | (align - 1)) + 1;
3039
3040 sec->header.sh_addr = dot;
3041 dot += sec->header.sh_size;
3042 }
3043
3044 return dot;
3045}
3046
3047static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3048{
3049 int i, n = f->header.e_shnum;
3050 int ret = 1;
3051
3052 /* Finalize the addresses of the sections. */
3053
3054 f->baseaddr = base;
3055 for (i = 0; i < n; ++i)
3056 f->sections[i]->header.sh_addr += base;
3057
3058 /* And iterate over all of the relocations. */
3059
3060 for (i = 0; i < n; ++i) {
3061 struct obj_section *relsec, *symsec, *targsec, *strsec;
3062 ElfW(RelM) * rel, *relend;
3063 ElfW(Sym) * symtab;
3064 const char *strtab;
3065
3066 relsec = f->sections[i];
3067 if (relsec->header.sh_type != SHT_RELM)
3068 continue;
3069
3070 symsec = f->sections[relsec->header.sh_link];
3071 targsec = f->sections[relsec->header.sh_info];
3072 strsec = f->sections[symsec->header.sh_link];
3073
3074 rel = (ElfW(RelM) *) relsec->contents;
3075 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3076 symtab = (ElfW(Sym) *) symsec->contents;
3077 strtab = (const char *) strsec->contents;
3078
3079 for (; rel < relend; ++rel) {
3080 ElfW(Addr) value = 0;
3081 struct obj_symbol *intsym = NULL;
3082 unsigned long symndx;
Denis Vlasenko49325962009-01-31 23:33:54 +00003083 ElfW(Sym) *extsym = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003084 const char *errmsg;
3085
3086 /* Attempt to find a value to use for this relocation. */
3087
3088 symndx = ELF_R_SYM(rel->r_info);
3089 if (symndx) {
3090 /* Note we've already checked for undefined symbols. */
3091
3092 extsym = &symtab[symndx];
3093 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3094 /* Local symbols we look up in the local table to be sure
3095 we get the one that is really intended. */
3096 intsym = f->local_symtab[symndx];
3097 } else {
3098 /* Others we look up in the hash table. */
3099 const char *name;
3100 if (extsym->st_name)
3101 name = strtab + extsym->st_name;
3102 else
3103 name = f->sections[extsym->st_shndx]->name;
3104 intsym = obj_find_symbol(f, name);
3105 }
3106
3107 value = obj_symbol_final_value(f, intsym);
3108 intsym->referenced = 1;
3109 }
3110#if SHT_RELM == SHT_RELA
3111#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3112 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003113 if (!extsym || !extsym->st_name
3114 || ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003115#endif
3116 value += rel->r_addend;
3117#endif
3118
3119 /* Do it! */
3120 switch (arch_apply_relocation
3121 (f, targsec, /*symsec,*/ intsym, rel, value)
3122 ) {
3123 case obj_reloc_ok:
3124 break;
3125
3126 case obj_reloc_overflow:
3127 errmsg = "Relocation overflow";
3128 goto bad_reloc;
3129 case obj_reloc_dangerous:
3130 errmsg = "Dangerous relocation";
3131 goto bad_reloc;
3132 case obj_reloc_unhandled:
3133 errmsg = "Unhandled relocation";
3134bad_reloc:
3135 if (extsym) {
3136 bb_error_msg("%s of type %ld for %s", errmsg,
3137 (long) ELF_R_TYPE(rel->r_info),
3138 strtab + extsym->st_name);
3139 } else {
3140 bb_error_msg("%s of type %ld", errmsg,
3141 (long) ELF_R_TYPE(rel->r_info));
3142 }
3143 ret = 0;
3144 break;
3145 }
3146 }
3147 }
3148
3149 /* Finally, take care of the patches. */
3150
3151 if (f->string_patches) {
3152 struct obj_string_patch *p;
3153 struct obj_section *strsec;
3154 ElfW(Addr) strsec_base;
3155 strsec = obj_find_section(f, ".kstrtab");
3156 strsec_base = strsec->header.sh_addr;
3157
3158 for (p = f->string_patches; p; p = p->next) {
3159 struct obj_section *targsec = f->sections[p->reloc_secidx];
3160 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3161 = strsec_base + p->string_offset;
3162 }
3163 }
3164
3165 if (f->symbol_patches) {
3166 struct obj_symbol_patch *p;
3167
3168 for (p = f->symbol_patches; p; p = p->next) {
3169 struct obj_section *targsec = f->sections[p->reloc_secidx];
3170 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3171 = obj_symbol_final_value(f, p->sym);
3172 }
3173 }
3174
3175 return ret;
3176}
3177
3178static int obj_create_image(struct obj_file *f, char *image)
3179{
3180 struct obj_section *sec;
3181 ElfW(Addr) base = f->baseaddr;
3182
3183 for (sec = f->load_order; sec; sec = sec->load_next) {
3184 char *secimg;
3185
3186 if (sec->contents == 0 || sec->header.sh_size == 0)
3187 continue;
3188
3189 secimg = image + (sec->header.sh_addr - base);
3190
3191 /* Note that we allocated data for NOBITS sections earlier. */
3192 memcpy(secimg, sec->contents, sec->header.sh_size);
3193 }
3194
3195 return 1;
3196}
3197
3198/*======================================================================*/
3199
Denis Vlasenkof4393042009-04-05 23:25:09 +00003200static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003201{
Denis Vlasenkoe1de3af2009-03-29 16:38:59 +00003202#if BB_LITTLE_ENDIAN
3203# define ELFMAG_U32 ((uint32_t)(ELFMAG0 + 0x100 * (ELFMAG1 + (0x100 * (ELFMAG2 + 0x100 * ELFMAG3)))))
3204#else
3205# define ELFMAG_U32 ((uint32_t)((((ELFMAG0 * 0x100) + ELFMAG1) * 0x100 + ELFMAG2) * 0x100 + ELFMAG3))
3206#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003207 struct obj_file *f;
3208 ElfW(Shdr) * section_headers;
3209 size_t shnum, i;
3210 char *shstrtab;
3211
3212 /* Read the file header. */
3213
3214 f = arch_new_file();
3215 f->symbol_cmp = strcmp;
3216 f->symbol_hash = obj_elf_hash;
3217 f->load_order_search_start = &f->load_order;
3218
Denis Vlasenkof4393042009-04-05 23:25:09 +00003219 if (image_size < sizeof(f->header))
3220 bb_error_msg_and_die("error while loading ELF header");
3221 memcpy(&f->header, image, sizeof(f->header));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003222
Denis Vlasenkoe1de3af2009-03-29 16:38:59 +00003223 if (*(uint32_t*)(&f->header.e_ident) != ELFMAG_U32) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003224 bb_error_msg_and_die("not an ELF file");
3225 }
3226 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003227 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3228 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3229 || !MATCH_MACHINE(f->header.e_machine)
3230 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003231 bb_error_msg_and_die("ELF file not for this architecture");
3232 }
3233 if (f->header.e_type != ET_REL) {
3234 bb_error_msg_and_die("ELF file not a relocatable object");
3235 }
3236
3237 /* Read the section headers. */
3238
3239 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3240 bb_error_msg_and_die("section header size mismatch: %lu != %lu",
3241 (unsigned long) f->header.e_shentsize,
3242 (unsigned long) sizeof(ElfW(Shdr)));
3243 }
3244
3245 shnum = f->header.e_shnum;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003246 /* Growth of ->sections vector will be done by
3247 * xrealloc_vector(..., 2, ...), therefore we must allocate
3248 * at least 2^2 = 4 extra elements here. */
3249 f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003250
3251 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003252 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum)
3253 bb_error_msg_and_die("error while loading section headers");
3254 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003255
3256 /* Read the section data. */
3257
3258 for (i = 0; i < shnum; ++i) {
3259 struct obj_section *sec;
3260
3261 f->sections[i] = sec = arch_new_section();
3262
3263 sec->header = section_headers[i];
3264 sec->idx = i;
3265
3266 if (sec->header.sh_size) {
3267 switch (sec->header.sh_type) {
3268 case SHT_NULL:
3269 case SHT_NOTE:
3270 case SHT_NOBITS:
3271 /* ignore */
3272 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003273 case SHT_PROGBITS:
3274#if LOADBITS
3275 if (!loadprogbits) {
3276 sec->contents = NULL;
3277 break;
3278 }
3279#endif
3280 case SHT_SYMTAB:
3281 case SHT_STRTAB:
3282 case SHT_RELM:
Denis Vlasenko3bc3f082008-11-22 20:18:37 +00003283 sec->contents = NULL;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003284 if (sec->header.sh_size > 0) {
3285 sec->contents = xmalloc(sec->header.sh_size);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003286 if (image_size < (sec->header.sh_offset + sec->header.sh_size))
3287 bb_error_msg_and_die("error while loading section data");
3288 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003289 }
3290 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003291#if SHT_RELM == SHT_REL
3292 case SHT_RELA:
3293 bb_error_msg_and_die("RELA relocations not supported on this architecture");
3294#else
3295 case SHT_REL:
3296 bb_error_msg_and_die("REL relocations not supported on this architecture");
3297#endif
3298 default:
3299 if (sec->header.sh_type >= SHT_LOPROC) {
3300 /* Assume processor specific section types are debug
3301 info and can safely be ignored. If this is ever not
3302 the case (Hello MIPS?), don't put ifdefs here but
3303 create an arch_load_proc_section(). */
3304 break;
3305 }
3306
3307 bb_error_msg_and_die("can't handle sections of type %ld",
3308 (long) sec->header.sh_type);
3309 }
3310 }
3311 }
3312
3313 /* Do what sort of interpretation as needed by each section. */
3314
3315 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3316
3317 for (i = 0; i < shnum; ++i) {
3318 struct obj_section *sec = f->sections[i];
3319 sec->name = shstrtab + sec->header.sh_name;
3320 }
3321
3322 for (i = 0; i < shnum; ++i) {
3323 struct obj_section *sec = f->sections[i];
3324
3325 /* .modinfo should be contents only but gcc has no attribute for that.
3326 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3327 */
3328 if (strcmp(sec->name, ".modinfo") == 0)
3329 sec->header.sh_flags &= ~SHF_ALLOC;
3330
3331 if (sec->header.sh_flags & SHF_ALLOC)
3332 obj_insert_section_load_order(f, sec);
3333
3334 switch (sec->header.sh_type) {
3335 case SHT_SYMTAB:
3336 {
3337 unsigned long nsym, j;
3338 char *strtab;
3339 ElfW(Sym) * sym;
3340
3341 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3342 bb_error_msg_and_die("symbol size mismatch: %lu != %lu",
3343 (unsigned long) sec->header.sh_entsize,
3344 (unsigned long) sizeof(ElfW(Sym)));
3345 }
3346
3347 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3348 strtab = f->sections[sec->header.sh_link]->contents;
3349 sym = (ElfW(Sym) *) sec->contents;
3350
3351 /* Allocate space for a table of local symbols. */
3352 j = f->local_symtab_size = sec->header.sh_info;
3353 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
3354
3355 /* Insert all symbols into the hash table. */
3356 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3357 ElfW(Addr) val = sym->st_value;
3358 const char *name;
3359 if (sym->st_name)
3360 name = strtab + sym->st_name;
3361 else if (sym->st_shndx < shnum)
3362 name = f->sections[sym->st_shndx]->name;
3363 else
3364 continue;
3365#if defined(__SH5__)
3366 /*
3367 * For sh64 it is possible that the target of a branch
3368 * requires a mode switch (32 to 16 and back again).
3369 *
3370 * This is implied by the lsb being set in the target
3371 * address for SHmedia mode and clear for SHcompact.
3372 */
3373 val |= sym->st_other & 4;
3374#endif
3375 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3376 val, sym->st_size);
3377 }
3378 }
3379 break;
3380
3381 case SHT_RELM:
3382 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3383 bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu",
3384 (unsigned long) sec->header.sh_entsize,
3385 (unsigned long) sizeof(ElfW(RelM)));
3386 }
3387 break;
3388 /* XXX Relocation code from modutils-2.3.19 is not here.
3389 * Why? That's about 20 lines of code from obj/obj_load.c,
3390 * which gets done in a second pass through the sections.
3391 * This BusyBox insmod does similar work in obj_relocate(). */
3392 }
3393 }
3394
3395 return f;
3396}
3397
3398#if ENABLE_FEATURE_INSMOD_LOADINKMEM
3399/*
3400 * load the unloaded sections directly into the memory allocated by
3401 * kernel for the module
3402 */
3403
Denis Vlasenkof4393042009-04-05 23:25:09 +00003404static int obj_load_progbits(char *image, size_t image_size, struct obj_file *f, char *imagebase)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003405{
3406 ElfW(Addr) base = f->baseaddr;
3407 struct obj_section* sec;
3408
3409 for (sec = f->load_order; sec; sec = sec->load_next) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003410 /* section already loaded? */
3411 if (sec->contents != NULL)
3412 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003413 if (sec->header.sh_size == 0)
3414 continue;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003415 sec->contents = imagebase + (sec->header.sh_addr - base);
Denis Vlasenkof4393042009-04-05 23:25:09 +00003416 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) {
3417 bb_error_msg("error reading ELF section data");
3418 return 0; /* need to delete half-loaded module! */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003419 }
Denis Vlasenkof4393042009-04-05 23:25:09 +00003420 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003421 }
3422 return 1;
3423}
3424#endif
3425
3426static void hide_special_symbols(struct obj_file *f)
3427{
3428 static const char *const specials[] = {
3429 SPFX "cleanup_module",
3430 SPFX "init_module",
3431 SPFX "kernel_version",
3432 NULL
3433 };
3434
3435 struct obj_symbol *sym;
3436 const char *const *p;
3437
3438 for (p = specials; *p; ++p) {
3439 sym = obj_find_symbol(f, *p);
3440 if (sym != NULL)
3441 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3442 }
3443}
3444
3445
3446#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
3447static int obj_gpl_license(struct obj_file *f, const char **license)
3448{
3449 struct obj_section *sec;
3450 /* This list must match *exactly* the list of allowable licenses in
3451 * linux/include/linux/module.h. Checking for leading "GPL" will not
3452 * work, somebody will use "GPL sucks, this is proprietary".
3453 */
3454 static const char *const gpl_licenses[] = {
3455 "GPL",
3456 "GPL v2",
3457 "GPL and additional rights",
3458 "Dual BSD/GPL",
3459 "Dual MPL/GPL"
3460 };
3461
3462 sec = obj_find_section(f, ".modinfo");
3463 if (sec) {
3464 const char *value, *ptr, *endptr;
3465 ptr = sec->contents;
3466 endptr = ptr + sec->header.sh_size;
3467 while (ptr < endptr) {
3468 value = strchr(ptr, '=');
3469 if (value && strncmp(ptr, "license", value-ptr) == 0) {
3470 unsigned i;
3471 if (license)
3472 *license = value+1;
3473 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
3474 if (strcmp(value+1, gpl_licenses[i]) == 0)
3475 return 0;
3476 }
3477 return 2;
3478 }
3479 ptr = strchr(ptr, '\0');
3480 if (ptr)
3481 ptr++;
3482 else
3483 ptr = endptr;
3484 }
3485 }
3486 return 1;
3487}
3488
3489#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3490#define TAINT_PROPRIETORY_MODULE (1 << 0)
3491#define TAINT_FORCED_MODULE (1 << 1)
3492#define TAINT_UNSAFE_SMP (1 << 2)
3493#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3494
3495static void set_tainted(int fd, const char *m_name,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02003496 int kernel_has_tainted, int taint,
3497 const char *text1, const char *text2)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003498{
3499 static smallint printed_info;
3500
3501 char buf[80];
3502 int oldval;
3503
3504 if (fd < 0 && !kernel_has_tainted)
3505 return; /* New modutils on old kernel */
3506 printf("Warning: loading %s will taint the kernel: %s%s\n",
3507 m_name, text1, text2);
3508 if (!printed_info) {
3509 printf(" See %s for information about tainted modules\n", TAINT_URL);
3510 printed_info = 1;
3511 }
3512 if (fd >= 0) {
3513 read(fd, buf, sizeof(buf)-1);
3514 buf[sizeof(buf)-1] = '\0';
3515 oldval = strtoul(buf, NULL, 10);
3516 sprintf(buf, "%d\n", oldval | taint);
Denis Vlasenko73c571a2009-03-09 00:12:37 +00003517 xwrite_str(fd, buf);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003518 }
3519}
3520
3521/* Check if loading this module will taint the kernel. */
3522static void check_tainted_module(struct obj_file *f, const char *m_name)
3523{
3524 static const char tainted_file[] ALIGN1 = TAINT_FILENAME;
3525
3526 int fd, kernel_has_tainted;
3527 const char *ptr;
3528
3529 kernel_has_tainted = 1;
3530 fd = open(tainted_file, O_RDWR);
3531 if (fd < 0) {
3532 if (errno == ENOENT)
3533 kernel_has_tainted = 0;
3534 else if (errno == EACCES)
3535 kernel_has_tainted = 1;
3536 else {
3537 perror(tainted_file);
3538 kernel_has_tainted = 0;
3539 }
3540 }
3541
3542 switch (obj_gpl_license(f, &ptr)) {
3543 case 0:
3544 break;
3545 case 1:
3546 set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3547 break;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003548 default: /* case 2: */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003549 /* The module has a non-GPL license so we pretend that the
3550 * kernel always has a taint flag to get a warning even on
3551 * kernels without the proc flag.
3552 */
3553 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3554 break;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003555 }
3556
3557 if (flag_force_load)
3558 set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3559
3560 if (fd >= 0)
3561 close(fd);
3562}
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003563#else /* !FEATURE_CHECK_TAINTED_MODULE */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003564#define check_tainted_module(x, y) do { } while (0);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003565#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003566
3567#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3568/* add module source, timestamp, kernel version and a symbol for the
3569 * start of some sections. this info is used by ksymoops to do better
3570 * debugging.
3571 */
3572#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3573#define get_module_version(f, str) get_module_version(str)
3574#endif
3575static int
3576get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3577{
3578#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3579 return new_get_module_version(f, str);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003580#else
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003581 strncpy(str, "???", sizeof(str));
3582 return -1;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003583#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003584}
3585
3586/* add module source, timestamp, kernel version and a symbol for the
3587 * start of some sections. this info is used by ksymoops to do better
3588 * debugging.
3589 */
3590static void
3591add_ksymoops_symbols(struct obj_file *f, const char *filename,
Denys Vlasenkod5f1b1b2009-06-05 12:06:05 +02003592 const char *m_name)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003593{
3594 static const char symprefix[] ALIGN1 = "__insmod_";
3595 static const char section_names[][8] = {
3596 ".text",
3597 ".rodata",
3598 ".data",
3599 ".bss",
3600 ".sbss"
3601 };
3602
3603 struct obj_section *sec;
3604 struct obj_symbol *sym;
3605 char *name, *absolute_filename;
3606 char str[STRVERSIONLEN];
3607 unsigned i;
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003608 int lm_name, lfilename, use_ksymtab, version;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003609 struct stat statbuf;
3610
3611 /* WARNING: was using realpath, but replaced by readlink to stop using
3612 * lots of stack. But here it seems to be able to cause problems? */
3613 absolute_filename = xmalloc_readlink(filename);
3614 if (!absolute_filename)
3615 absolute_filename = xstrdup(filename);
3616
3617 lm_name = strlen(m_name);
3618 lfilename = strlen(absolute_filename);
3619
3620 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3621 * are not to be exported. otherwise leave ksymtab alone for now, the
3622 * "export all symbols" compatibility code will export these symbols later.
3623 */
3624 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
3625
3626 sec = obj_find_section(f, ".this");
3627 if (sec) {
3628 /* tag the module header with the object name, last modified
3629 * timestamp and module version. worst case for module version
3630 * is 0xffffff, decimal 16777215. putting all three fields in
3631 * one symbol is less readable but saves kernel space.
3632 */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003633 if (stat(absolute_filename, &statbuf) != 0)
3634 statbuf.st_mtime = 0;
3635 version = get_module_version(f, str); /* -1 if not found */
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003636 name = xasprintf("%s%s_O%s_M%0*lX_V%d",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003637 symprefix, m_name, absolute_filename,
Denis Vlasenko49325962009-01-31 23:33:54 +00003638 (int)(2 * sizeof(statbuf.st_mtime)),
3639 (long)statbuf.st_mtime,
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003640 version);
3641 sym = obj_add_symbol(f, name, -1,
3642 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3643 sec->idx, sec->header.sh_addr, 0);
3644 if (use_ksymtab)
3645 new_add_ksymtab(f, sym);
3646 }
3647 free(absolute_filename);
3648#ifdef _NOT_SUPPORTED_
3649 /* record where the persistent data is going, same address as previous symbol */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003650 if (f->persist) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003651 name = xasprintf("%s%s_P%s",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003652 symprefix, m_name, f->persist);
3653 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3654 sec->idx, sec->header.sh_addr, 0);
3655 if (use_ksymtab)
3656 new_add_ksymtab(f, sym);
3657 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003658#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003659 /* tag the desired sections if size is non-zero */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003660 for (i = 0; i < ARRAY_SIZE(section_names); ++i) {
3661 sec = obj_find_section(f, section_names[i]);
3662 if (sec && sec->header.sh_size) {
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003663 name = xasprintf("%s%s_S%s_L%ld",
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003664 symprefix, m_name, sec->name,
3665 (long)sec->header.sh_size);
3666 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3667 sec->idx, sec->header.sh_addr, 0);
3668 if (use_ksymtab)
3669 new_add_ksymtab(f, sym);
3670 }
3671 }
3672}
3673#endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3674
3675#if ENABLE_FEATURE_INSMOD_LOAD_MAP
3676static void print_load_map(struct obj_file *f)
3677{
3678 struct obj_section *sec;
3679#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3680 struct obj_symbol **all, **p;
Denis Vlasenko49325962009-01-31 23:33:54 +00003681 int i, nsyms;
3682 char *loaded; /* array of booleans */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003683 struct obj_symbol *sym;
3684#endif
3685 /* Report on the section layout. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003686 printf("Sections: Size %-*s Align\n",
3687 (int) (2 * sizeof(void *)), "Address");
3688
3689 for (sec = f->load_order; sec; sec = sec->load_next) {
3690 int a;
3691 unsigned long tmp;
3692
3693 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3694 tmp >>= 1;
3695 if (a == -1)
3696 a = 0;
3697
3698 printf("%-15s %08lx %0*lx 2**%d\n",
3699 sec->name,
3700 (long)sec->header.sh_size,
3701 (int) (2 * sizeof(void *)),
3702 (long)sec->header.sh_addr,
3703 a);
3704 }
3705#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3706 /* Quick reference which section indices are loaded. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003707 i = f->header.e_shnum;
Denis Vlasenko49325962009-01-31 23:33:54 +00003708 loaded = alloca(i * sizeof(loaded[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003709 while (--i >= 0)
3710 loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0);
3711
3712 /* Collect the symbols we'll be listing. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003713 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3714 for (sym = f->symtab[i]; sym; sym = sym->next)
3715 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003716 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3717 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003718 ++nsyms;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003719 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003720
Denis Vlasenko49325962009-01-31 23:33:54 +00003721 all = alloca(nsyms * sizeof(all[0]));
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003722
3723 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3724 for (sym = f->symtab[i]; sym; sym = sym->next)
3725 if (sym->secidx <= SHN_HIRESERVE
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003726 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3727 ) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003728 *p++ = sym;
Denis Vlasenko1ad4db12008-11-12 00:09:58 +00003729 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003730
3731 /* And list them. */
3732 printf("\nSymbols:\n");
3733 for (p = all; p < all + nsyms; ++p) {
3734 char type = '?';
3735 unsigned long value;
3736
3737 sym = *p;
3738 if (sym->secidx == SHN_ABS) {
3739 type = 'A';
3740 value = sym->value;
3741 } else if (sym->secidx == SHN_UNDEF) {
3742 type = 'U';
3743 value = 0;
3744 } else {
3745 sec = f->sections[sym->secidx];
3746
3747 if (sec->header.sh_type == SHT_NOBITS)
3748 type = 'B';
3749 else if (sec->header.sh_flags & SHF_ALLOC) {
3750 if (sec->header.sh_flags & SHF_EXECINSTR)
3751 type = 'T';
3752 else if (sec->header.sh_flags & SHF_WRITE)
3753 type = 'D';
3754 else
3755 type = 'R';
3756 }
3757 value = sym->value + sec->header.sh_addr;
3758 }
3759
3760 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
Denis Vlasenko49325962009-01-31 23:33:54 +00003761 type |= 0x20; /* tolower. safe for '?' too */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003762
3763 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3764 type, sym->name);
3765 }
3766#endif
3767}
3768#else /* !FEATURE_INSMOD_LOAD_MAP */
3769static void print_load_map(struct obj_file *f UNUSED_PARAM)
3770{
3771}
3772#endif
3773
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003774int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003775{
3776 int k_crcs;
3777 unsigned long m_size;
3778 ElfW(Addr) m_addr;
3779 struct obj_file *f;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003780 int exit_status = EXIT_FAILURE;
Denis Vlasenkof4393042009-04-05 23:25:09 +00003781 char *m_name;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003782#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003783 int m_has_modinfo;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003784#endif
Denis Vlasenkof4393042009-04-05 23:25:09 +00003785 char *image;
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003786 size_t image_size;
3787 bool mmaped;
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003788
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003789 image_size = INT_MAX - 4095;
3790 mmaped = 0;
3791 image = try_to_mmap_module(m_filename, &image_size);
3792 if (image) {
3793 mmaped = 1;
3794 } else {
3795 /* Load module into memory and unzip if compressed */
3796 image = xmalloc_open_zipped_read_close(m_filename, &image_size);
3797 if (!image)
3798 return EXIT_FAILURE;
3799 }
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003800
3801 m_name = xstrdup(bb_basename(m_filename));
Denis Vlasenkof4393042009-04-05 23:25:09 +00003802 /* "module.o[.gz]" -> "module" */
3803 *strchrnul(m_name, '.') = '\0';
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003804
Denis Vlasenkof4393042009-04-05 23:25:09 +00003805 f = obj_load(image, image_size, LOADBITS);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003806
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003807#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3808 /* Version correspondence? */
Denis Vlasenko51056b32009-04-12 14:21:29 +00003809 m_has_modinfo = (get_modinfo_value(f, "kernel_version") != NULL);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003810 if (!flag_quiet) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003811 char m_strversion[STRVERSIONLEN];
3812 struct utsname uts;
3813
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003814 if (m_has_modinfo) {
Denis Vlasenko51056b32009-04-12 14:21:29 +00003815 int m_version = new_get_module_version(f, m_strversion);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003816 if (m_version == -1) {
Denis Vlasenko1f632292009-04-13 02:25:40 +00003817 bb_error_msg_and_die("can't find the kernel version "
Denis Vlasenko51056b32009-04-12 14:21:29 +00003818 "the module was compiled for");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003819 }
3820 }
3821
Denis Vlasenko51056b32009-04-12 14:21:29 +00003822 uname(&uts);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003823 if (strncmp(uts.release, m_strversion, STRVERSIONLEN) != 0) {
3824 bb_error_msg("%skernel-module version mismatch\n"
3825 "\t%s was compiled for kernel version %s\n"
3826 "\twhile this kernel is version %s",
3827 flag_force_load ? "warning: " : "",
3828 m_name, m_strversion, uts.release);
3829 if (!flag_force_load)
3830 goto out;
3831 }
3832 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003833#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003834
3835 if (query_module(NULL, 0, NULL, 0, NULL))
Denis Vlasenkof4393042009-04-05 23:25:09 +00003836 bb_error_msg_and_die("old (unsupported) kernel");
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003837 new_get_kernel_symbols();
3838 k_crcs = new_is_kernel_checksummed();
3839
3840#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
Denis Vlasenko51056b32009-04-12 14:21:29 +00003841 {
3842 int m_crcs = 0;
3843 if (m_has_modinfo)
3844 m_crcs = new_is_module_checksummed(f);
3845 if (m_crcs != k_crcs)
3846 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3847 }
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003848#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003849
3850 /* Let the module know about the kernel symbols. */
3851 add_kernel_symbols(f);
3852
3853 /* Allocate common symbols, symbol tables, and string tables. */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003854 new_create_this_module(f, m_name);
3855 obj_check_undefineds(f);
3856 obj_allocate_commons(f);
3857 check_tainted_module(f, m_name);
3858
Denis Vlasenko49325962009-01-31 23:33:54 +00003859 /* Done with the module name, on to the optional var=value arguments */
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003860 new_process_module_arguments(f, options);
3861
3862 arch_create_got(f);
3863 hide_special_symbols(f);
3864
3865#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3866 add_ksymoops_symbols(f, m_filename, m_name);
Denis Vlasenkoe35af562009-01-31 14:22:24 +00003867#endif
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003868
3869 new_create_module_ksymtab(f);
3870
3871 /* Find current size of the module */
3872 m_size = obj_load_size(f);
3873
3874 m_addr = create_module(m_name, m_size);
3875 if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
Denis Vlasenko36309cf2008-11-22 18:29:01 +00003876 case EEXIST:
3877 bb_error_msg_and_die("a module named %s already exists", m_name);
3878 case ENOMEM:
3879 bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes",
3880 m_size);
3881 default:
3882 bb_perror_msg_and_die("create_module: %s", m_name);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003883 }
3884
3885#if !LOADBITS
3886 /*
3887 * the PROGBITS section was not loaded by the obj_load
3888 * now we can load them directly into the kernel memory
3889 */
Denis Vlasenkof4393042009-04-05 23:25:09 +00003890 if (!obj_load_progbits(image, image_size, f, (char*)m_addr)) {
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003891 delete_module(m_name, 0);
3892 goto out;
3893 }
3894#endif
3895
3896 if (!obj_relocate(f, m_addr)) {
3897 delete_module(m_name, 0);
3898 goto out;
3899 }
3900
3901 if (!new_init_module(m_name, f, m_size)) {
3902 delete_module(m_name, 0);
3903 goto out;
3904 }
3905
3906 if (flag_print_load_map)
3907 print_load_map(f);
3908
3909 exit_status = EXIT_SUCCESS;
3910
3911 out:
Denys Vlasenko77c066e2009-10-25 04:35:22 +01003912 if (mmaped)
3913 munmap(image, image_size);
3914 else
3915 free(image);
Denis Vlasenkoba1315d2008-09-13 14:59:38 +00003916 free(m_name);
3917
3918 return exit_status;
3919}