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