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