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