blob: 0554def06f6b5967b250fc6b7d8eae5718712a38 [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Erik Andersen02104321999-12-17 18:57:34 +00002/*
3 * Mini insmod implementation for busybox
Eric Andersen2835efe2001-07-25 16:58:58 +00004 *
Eric Andersen45a05132004-09-02 23:03:25 +00005 * 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.
Eric Andersen2835efe2001-07-25 16:58:58 +00007 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00008 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersen9f16d612000-06-12 23:11:16 +00009 * and Ron Alder <alder@lineo.com>
10 *
Eric Andersena4d27d22004-08-19 19:17:30 +000011 * Rodney Radford <rradford@mindspring.com> 17-Aug-2004.
12 * Added x86_64 support.
13 *
Miles Bader75ce8d72002-04-01 14:25:51 +000014 * Miles Bader <miles@gnu.org> added NEC V850E support.
Miles Baderae28b042002-04-01 09:34:25 +000015 *
Eric Andersenfe4208f2000-09-24 03:44:29 +000016 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
Eric Andersen21adca72000-12-06 18:18:26 +000017 * 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.
Eric Andersenfe4208f2000-09-24 03:44:29 +000023 *
Eric Andersenee70fa52004-05-26 11:38:46 +000024 * Yoshinori Sato <ysato@users.sourceforge.jp> 19-May-2004.
25 * added Renesas H8/300 support.
26 *
Eric Andersenbf833552003-08-13 19:56:33 +000027 * 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 *
Eric Andersencffd5022002-05-24 06:50:15 +000032 * 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 *
Eric Andersen90fe7fe2001-02-20 20:47:08 +000039 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
Eric Andersenc7bda1c2004-03-15 08:29:22 +000040 * PowerPC specific code stolen from modutils-2.3.16,
Eric Andersen90fe7fe2001-02-20 20:47:08 +000041 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
42 * I've only tested the code on mpc8xx platforms in big-endian mode.
Eric Andersenbdfd0d72001-10-24 05:00:29 +000043 * Did some cleanup and added CONFIG_USE_xxx_ENTRIES...
Eric Andersen90fe7fe2001-02-20 20:47:08 +000044 *
Eric Andersen2bf658d2001-02-24 20:01:53 +000045 * 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 *
Eric Andersen9f16d612000-06-12 23:11:16 +000051 * 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
Erik Andersen02104321999-12-17 18:57:34 +000057 *
Bernhard Reutner-Fischerc2cb0f32006-04-13 12:45:04 +000058 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Erik Andersen02104321999-12-17 18:57:34 +000059 */
60
Bernhard Reutner-Fischerdeda6a52006-06-03 19:35:15 +000061#include "busybox.h"
Rob Landley519d7df2006-08-09 20:56:23 +000062#include <libgen.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000063#include <sys/utsname.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000064
Eric Andersene7047882003-12-11 01:42:13 +000065#if !defined(CONFIG_FEATURE_2_4_MODULES) && \
Eric Andersene7047882003-12-11 01:42:13 +000066 !defined(CONFIG_FEATURE_2_6_MODULES)
67#define CONFIG_FEATURE_2_4_MODULES
68#endif
69
Eric Andersencb3b9b12004-06-22 11:50:52 +000070#if !defined(CONFIG_FEATURE_2_4_MODULES)
Eric Andersene7047882003-12-11 01:42:13 +000071#define insmod_ng_main insmod_main
72#endif
73
Eric Andersene7047882003-12-11 01:42:13 +000074#if defined(CONFIG_FEATURE_2_6_MODULES)
75extern int insmod_ng_main( int argc, char **argv);
76#endif
77
Eric Andersencb3b9b12004-06-22 11:50:52 +000078
79#if defined(CONFIG_FEATURE_2_4_MODULES)
80
Eric Andersen64c8b172001-04-05 07:33:10 +000081
Eric Andersenbdfd0d72001-10-24 05:00:29 +000082#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersenc7bda1c2004-03-15 08:29:22 +000083#define LOADBITS 0
Eric Andersen8ae319a2001-05-21 16:09:18 +000084#else
85#define LOADBITS 1
86#endif
87
Eric Andersen90fe7fe2001-02-20 20:47:08 +000088
Mike Frysinger63654c12004-12-26 09:13:32 +000089/* Alpha */
Mike Frysingerfa17c4b2005-10-02 07:14:06 +000090#if defined(__alpha__)
Mike Frysinger63654c12004-12-26 09:13:32 +000091#define MATCH_MACHINE(x) (x == EM_ALPHA)
92#define SHT_RELM SHT_RELA
93#define Elf64_RelM Elf64_Rela
94#define ELFCLASSM ELFCLASS64
95#endif
96
Eric Andersen45a05132004-09-02 23:03:25 +000097/* ARM support */
Eric Andersen90fe7fe2001-02-20 20:47:08 +000098#if defined(__arm__)
Eric Andersencffd5022002-05-24 06:50:15 +000099#define MATCH_MACHINE(x) (x == EM_ARM)
100#define SHT_RELM SHT_REL
101#define Elf32_RelM Elf32_Rel
102#define ELFCLASSM ELFCLASS32
Eric Andersenc3b2dbe2003-03-13 18:57:08 +0000103#define CONFIG_USE_PLT_ENTRIES
104#define CONFIG_PLT_ENTRY_SIZE 8
105#define CONFIG_USE_GOT_ENTRIES
106#define CONFIG_GOT_ENTRY_SIZE 8
107#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000108#endif
Eric Andersenbf77f612003-01-23 06:02:39 +0000109
Mike Frysingerb306cb72006-06-06 06:15:52 +0000110/* blackfin */
111#if defined(BFIN)
112#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
113#define SHT_RELM SHT_RELA
114#define Elf32_RelM Elf32_Rela
115#define ELFCLASSM ELFCLASS32
116#endif
117
Eric Andersen45a05132004-09-02 23:03:25 +0000118/* CRIS */
119#if defined(__cris__)
120#define MATCH_MACHINE(x) (x == EM_CRIS)
Eric Andersenbf77f612003-01-23 06:02:39 +0000121#define SHT_RELM SHT_RELA
122#define Elf32_RelM Elf32_Rela
123#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000124#ifndef EM_CRIS
125#define EM_CRIS 76
126#define R_CRIS_NONE 0
127#define R_CRIS_32 3
128#endif
Eric Andersenbf77f612003-01-23 06:02:39 +0000129#endif
130
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000131/* H8/300 */
132#if defined(__H8300H__) || defined(__H8300S__)
133#define MATCH_MACHINE(x) (x == EM_H8_300)
134#define SHT_RELM SHT_RELA
135#define Elf32_RelM Elf32_Rela
136#define ELFCLASSM ELFCLASS32
137#define CONFIG_USE_SINGLE
138#define SYMBOL_PREFIX "_"
139#endif
140
Mike Frysinger63654c12004-12-26 09:13:32 +0000141/* PA-RISC / HP-PA */
142#if defined(__hppa__)
143#define MATCH_MACHINE(x) (x == EM_PARISC)
144#define SHT_RELM SHT_RELA
145#if defined(__LP64__)
146#define Elf64_RelM Elf64_Rela
147#define ELFCLASSM ELFCLASS64
148#else
149#define Elf32_RelM Elf32_Rela
150#define ELFCLASSM ELFCLASS32
151#endif
152#endif
153
Eric Andersen45a05132004-09-02 23:03:25 +0000154/* x86 */
155#if defined(__i386__)
Eric Andersencffd5022002-05-24 06:50:15 +0000156#ifndef EM_486
157#define MATCH_MACHINE(x) (x == EM_386)
158#else
159#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
160#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000161#define SHT_RELM SHT_REL
162#define Elf32_RelM Elf32_Rel
163#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000164#define CONFIG_USE_GOT_ENTRIES
165#define CONFIG_GOT_ENTRY_SIZE 4
166#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000167#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000168
Eric Andersen45a05132004-09-02 23:03:25 +0000169/* IA64, aka Itanium */
170#if defined(__ia64__)
171#define MATCH_MACHINE(x) (x == EM_IA_64)
172#define SHT_RELM SHT_RELA
173#define Elf64_RelM Elf64_Rela
174#define ELFCLASSM ELFCLASS64
175#endif
176
177/* m68k */
178#if defined(__mc68000__)
Eric Andersencffd5022002-05-24 06:50:15 +0000179#define MATCH_MACHINE(x) (x == EM_68K)
180#define SHT_RELM SHT_RELA
181#define Elf32_RelM Elf32_Rela
Eric Andersen9e458f52004-03-19 12:17:04 +0000182#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000183#define CONFIG_USE_GOT_ENTRIES
184#define CONFIG_GOT_ENTRY_SIZE 4
185#define CONFIG_USE_SINGLE
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000186#endif
187
Mike Frysingerb306cb72006-06-06 06:15:52 +0000188/* Microblaze */
189#if defined(__microblaze__)
190#define CONFIG_USE_SINGLE
191#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
192#define SHT_RELM SHT_RELA
193#define Elf32_RelM Elf32_Rela
194#define ELFCLASSM ELFCLASS32
195#endif
196
Eric Andersen45a05132004-09-02 23:03:25 +0000197/* MIPS */
Eric Andersen2bf658d2001-02-24 20:01:53 +0000198#if defined(__mips__)
Eric Andersen45a05132004-09-02 23:03:25 +0000199#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
200#define SHT_RELM SHT_REL
201#define Elf32_RelM Elf32_Rel
202#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000203/* Account for ELF spec changes. */
204#ifndef EM_MIPS_RS3_LE
205#ifdef EM_MIPS_RS4_BE
206#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
207#else
208#define EM_MIPS_RS3_LE 10
209#endif
210#endif /* !EM_MIPS_RS3_LE */
Eric Andersencffd5022002-05-24 06:50:15 +0000211#define ARCHDATAM "__dbe_table"
212#endif
213
Mike Frysingerf982d862006-01-04 00:11:26 +0000214/* Nios II */
215#if defined(__nios2__)
216#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
217#define SHT_RELM SHT_RELA
218#define Elf32_RelM Elf32_Rela
219#define ELFCLASSM ELFCLASS32
220#endif
221
Eric Andersen45a05132004-09-02 23:03:25 +0000222/* PowerPC */
Mike Frysingerbc48ebd2005-09-14 00:07:26 +0000223#if defined(__powerpc64__)
224#define MATCH_MACHINE(x) (x == EM_PPC64)
225#define SHT_RELM SHT_RELA
226#define Elf64_RelM Elf64_Rela
227#define ELFCLASSM ELFCLASS64
228#elif defined(__powerpc__)
Eric Andersen45a05132004-09-02 23:03:25 +0000229#define MATCH_MACHINE(x) (x == EM_PPC)
230#define SHT_RELM SHT_RELA
231#define Elf32_RelM Elf32_Rela
232#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000233#define CONFIG_USE_PLT_ENTRIES
234#define CONFIG_PLT_ENTRY_SIZE 16
235#define CONFIG_USE_PLT_LIST
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000236#define CONFIG_LIST_ARCHTYPE ElfW(Addr)
Eric Andersencffd5022002-05-24 06:50:15 +0000237#define CONFIG_USE_LIST
Eric Andersencffd5022002-05-24 06:50:15 +0000238#define ARCHDATAM "__ftr_fixup"
239#endif
240
Eric Andersen45a05132004-09-02 23:03:25 +0000241/* S390 */
242#if defined(__s390__)
243#define MATCH_MACHINE(x) (x == EM_S390)
244#define SHT_RELM SHT_RELA
245#define Elf32_RelM Elf32_Rela
246#define ELFCLASSM ELFCLASS32
247#define CONFIG_USE_PLT_ENTRIES
248#define CONFIG_PLT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000249#define CONFIG_USE_GOT_ENTRIES
Eric Andersen45a05132004-09-02 23:03:25 +0000250#define CONFIG_GOT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000251#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000252#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000253
Eric Andersen45a05132004-09-02 23:03:25 +0000254/* SuperH */
255#if defined(__sh__)
Eric Andersencffd5022002-05-24 06:50:15 +0000256#define MATCH_MACHINE(x) (x == EM_SH)
257#define SHT_RELM SHT_RELA
258#define Elf32_RelM Elf32_Rela
259#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000260#define CONFIG_USE_GOT_ENTRIES
261#define CONFIG_GOT_ENTRY_SIZE 4
262#define CONFIG_USE_SINGLE
Eric Andersenbf833552003-08-13 19:56:33 +0000263/* the SH changes have only been tested in =little endian= mode */
Eric Andersencffd5022002-05-24 06:50:15 +0000264/* I'm not sure about big endian, so let's warn: */
Rob Landley688ed0d2006-03-04 22:40:25 +0000265#if defined(__sh__) && BB_BIG_ENDIAN
266# error insmod.c may require changes for use on big endian SH
Eric Andersencffd5022002-05-24 06:50:15 +0000267#endif
Eric Andersen45a05132004-09-02 23:03:25 +0000268/* it may or may not work on the SH1/SH2... Error on those also */
269#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
Eric Andersenbf833552003-08-13 19:56:33 +0000270#error insmod.c may require changes for SH1 or SH2 use
Eric Andersencffd5022002-05-24 06:50:15 +0000271#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000272#endif
273
Eric Andersen45a05132004-09-02 23:03:25 +0000274/* Sparc */
275#if defined(__sparc__)
276#define MATCH_MACHINE(x) (x == EM_SPARC)
277#define SHT_RELM SHT_RELA
278#define Elf32_RelM Elf32_Rela
279#define ELFCLASSM ELFCLASS32
Miles Baderae28b042002-04-01 09:34:25 +0000280#endif
281
Eric Andersen45a05132004-09-02 23:03:25 +0000282/* v850e */
283#if defined (__v850e__)
Eric Andersencffd5022002-05-24 06:50:15 +0000284#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
285#define SHT_RELM SHT_RELA
286#define Elf32_RelM Elf32_Rela
287#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000288#define CONFIG_USE_PLT_ENTRIES
289#define CONFIG_PLT_ENTRY_SIZE 8
Eric Andersenee70fa52004-05-26 11:38:46 +0000290#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000291#ifndef EM_CYGNUS_V850 /* grumble */
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000292#define EM_CYGNUS_V850 0x9080
Eric Andersen45a05132004-09-02 23:03:25 +0000293#endif
Eric Andersenee70fa52004-05-26 11:38:46 +0000294#define SYMBOL_PREFIX "_"
295#endif
296
Eric Andersen45a05132004-09-02 23:03:25 +0000297/* X86_64 */
298#if defined(__x86_64__)
299#define MATCH_MACHINE(x) (x == EM_X86_64)
Mike Frysinger354b5272005-03-30 06:29:41 +0000300#define SHT_RELM SHT_RELA
Mike Frysinger91fbdac2005-10-02 06:44:39 +0000301#define CONFIG_USE_GOT_ENTRIES
302#define CONFIG_GOT_ENTRY_SIZE 8
303#define CONFIG_USE_SINGLE
Mike Frysinger354b5272005-03-30 06:29:41 +0000304#define Elf64_RelM Elf64_Rela
Eric Andersen45a05132004-09-02 23:03:25 +0000305#define ELFCLASSM ELFCLASS64
306#endif
307
Eric Andersencffd5022002-05-24 06:50:15 +0000308#ifndef SHT_RELM
309#error Sorry, but insmod.c does not yet support this architecture...
310#endif
311
312
Eric Andersen9f16d612000-06-12 23:11:16 +0000313//----------------------------------------------------------------------------
314//--------modutils module.h, lines 45-242
315//----------------------------------------------------------------------------
316
317/* Definitions for the Linux module syscall interface.
318 Copyright 1996, 1997 Linux International.
319
320 Contributed by Richard Henderson <rth@tamu.edu>
321
322 This file is part of the Linux modutils.
323
324 This program is free software; you can redistribute it and/or modify it
325 under the terms of the GNU General Public License as published by the
326 Free Software Foundation; either version 2 of the License, or (at your
327 option) any later version.
328
329 This program is distributed in the hope that it will be useful, but
330 WITHOUT ANY WARRANTY; without even the implied warranty of
331 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
332 General Public License for more details.
333
334 You should have received a copy of the GNU General Public License
335 along with this program; if not, write to the Free Software Foundation,
336 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
337
338
339#ifndef MODUTILS_MODULE_H
Rob Landleybc68cd12006-03-10 19:22:06 +0000340/* Why? static const int MODUTILS_MODULE_H = 1;*/
Eric Andersen9f16d612000-06-12 23:11:16 +0000341
Eric Andersen9f16d612000-06-12 23:11:16 +0000342/*======================================================================*/
343/* For sizeof() which are related to the module platform and not to the
344 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
345
346#define tgt_sizeof_char sizeof(char)
347#define tgt_sizeof_short sizeof(short)
348#define tgt_sizeof_int sizeof(int)
349#define tgt_sizeof_long sizeof(long)
350#define tgt_sizeof_char_p sizeof(char *)
351#define tgt_sizeof_void_p sizeof(void *)
352#define tgt_long long
353
354#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
355#undef tgt_sizeof_long
356#undef tgt_sizeof_char_p
357#undef tgt_sizeof_void_p
358#undef tgt_long
Rob Landleybc68cd12006-03-10 19:22:06 +0000359enum {
360 tgt_sizeof_long = 8,
361 tgt_sizeof_char_p = 8,
362 tgt_sizeof_void_p = 8
363};
Eric Andersen9f16d612000-06-12 23:11:16 +0000364#define tgt_long long long
365#endif
366
367/*======================================================================*/
368/* The structures used in Linux 2.1. */
369
370/* Note: new_module_symbol does not use tgt_long intentionally */
371struct new_module_symbol
372{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000373 unsigned long value;
374 unsigned long name;
Eric Andersen9f16d612000-06-12 23:11:16 +0000375};
376
377struct new_module_persist;
378
379struct new_module_ref
380{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000381 unsigned tgt_long dep; /* kernel addresses */
382 unsigned tgt_long ref;
383 unsigned tgt_long next_ref;
Eric Andersen9f16d612000-06-12 23:11:16 +0000384};
385
386struct new_module
387{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000388 unsigned tgt_long size_of_struct; /* == sizeof(module) */
389 unsigned tgt_long next;
390 unsigned tgt_long name;
391 unsigned tgt_long size;
Eric Andersen9f16d612000-06-12 23:11:16 +0000392
Eric Andersen3b1a7442003-12-24 20:30:45 +0000393 tgt_long usecount;
394 unsigned tgt_long flags; /* AUTOCLEAN et al */
Eric Andersen9f16d612000-06-12 23:11:16 +0000395
Eric Andersen3b1a7442003-12-24 20:30:45 +0000396 unsigned nsyms;
397 unsigned ndeps;
Eric Andersen9f16d612000-06-12 23:11:16 +0000398
Eric Andersen3b1a7442003-12-24 20:30:45 +0000399 unsigned tgt_long syms;
400 unsigned tgt_long deps;
401 unsigned tgt_long refs;
402 unsigned tgt_long init;
403 unsigned tgt_long cleanup;
404 unsigned tgt_long ex_table_start;
405 unsigned tgt_long ex_table_end;
Eric Andersen9f16d612000-06-12 23:11:16 +0000406#ifdef __alpha__
Eric Andersen3b1a7442003-12-24 20:30:45 +0000407 unsigned tgt_long gp;
Eric Andersen9f16d612000-06-12 23:11:16 +0000408#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +0000409 /* Everything after here is extension. */
410 unsigned tgt_long persist_start;
411 unsigned tgt_long persist_end;
412 unsigned tgt_long can_unload;
413 unsigned tgt_long runsize;
Eric Andersen3b1a7442003-12-24 20:30:45 +0000414 const char *kallsyms_start; /* All symbols for kernel debugging */
415 const char *kallsyms_end;
416 const char *archdata_start; /* arch specific data for module */
417 const char *archdata_end;
418 const char *kernel_data; /* Reserved for kernel internal use */
Eric Andersen9f16d612000-06-12 23:11:16 +0000419};
420
Eric Andersencffd5022002-05-24 06:50:15 +0000421#ifdef ARCHDATAM
422#define ARCHDATA_SEC_NAME ARCHDATAM
423#else
Eric Andersen8ae319a2001-05-21 16:09:18 +0000424#define ARCHDATA_SEC_NAME "__archdata"
Eric Andersencffd5022002-05-24 06:50:15 +0000425#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +0000426#define KALLSYMS_SEC_NAME "__kallsyms"
427
428
Eric Andersen9f16d612000-06-12 23:11:16 +0000429struct new_module_info
430{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000431 unsigned long addr;
432 unsigned long size;
433 unsigned long flags;
434 long usecount;
Eric Andersen9f16d612000-06-12 23:11:16 +0000435};
436
437/* Bits of module.flags. */
Rob Landleybc68cd12006-03-10 19:22:06 +0000438enum {
439 NEW_MOD_RUNNING = 1,
440 NEW_MOD_DELETED = 2,
441 NEW_MOD_AUTOCLEAN = 4,
442 NEW_MOD_VISITED = 8,
443 NEW_MOD_USED_ONCE = 16
444};
Eric Andersen9f16d612000-06-12 23:11:16 +0000445
Eric Andersencb3b9b12004-06-22 11:50:52 +0000446int init_module(const char *name, const struct new_module *);
447int query_module(const char *name, int which, void *buf,
448 size_t bufsize, size_t *ret);
Eric Andersen9f16d612000-06-12 23:11:16 +0000449
450/* Values for query_module's which. */
Rob Landleybc68cd12006-03-10 19:22:06 +0000451enum {
452 QM_MODULES = 1,
453 QM_DEPS = 2,
454 QM_REFS = 3,
455 QM_SYMBOLS = 4,
456 QM_INFO = 5
457};
Eric Andersen9f16d612000-06-12 23:11:16 +0000458
459/*======================================================================*/
460/* The system calls unchanged between 2.0 and 2.1. */
461
462unsigned long create_module(const char *, size_t);
463int delete_module(const char *);
464
465
466#endif /* module.h */
467
468//----------------------------------------------------------------------------
469//--------end of modutils module.h
470//----------------------------------------------------------------------------
471
472
473
474//----------------------------------------------------------------------------
475//--------modutils obj.h, lines 253-462
476//----------------------------------------------------------------------------
477
478/* Elf object file loading and relocation routines.
479 Copyright 1996, 1997 Linux International.
480
481 Contributed by Richard Henderson <rth@tamu.edu>
482
483 This file is part of the Linux modutils.
484
485 This program is free software; you can redistribute it and/or modify it
486 under the terms of the GNU General Public License as published by the
487 Free Software Foundation; either version 2 of the License, or (at your
488 option) any later version.
489
490 This program is distributed in the hope that it will be useful, but
491 WITHOUT ANY WARRANTY; without even the implied warranty of
492 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
493 General Public License for more details.
494
495 You should have received a copy of the GNU General Public License
496 along with this program; if not, write to the Free Software Foundation,
497 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
498
499
500#ifndef MODUTILS_OBJ_H
Rob Landleybc68cd12006-03-10 19:22:06 +0000501/* Why? static const int MODUTILS_OBJ_H = 1; */
Eric Andersen9f16d612000-06-12 23:11:16 +0000502
Eric Andersen9f16d612000-06-12 23:11:16 +0000503/* The relocatable object is manipulated using elfin types. */
504
505#include <stdio.h>
506#include <elf.h>
Eric Andersenb1591d12002-04-12 00:28:59 +0000507#include <endian.h>
508
Eric Andersen9f16d612000-06-12 23:11:16 +0000509#ifndef ElfW
510# if ELFCLASSM == ELFCLASS32
511# define ElfW(x) Elf32_ ## x
512# define ELFW(x) ELF32_ ## x
513# else
514# define ElfW(x) Elf64_ ## x
515# define ELFW(x) ELF64_ ## x
516# endif
517#endif
518
Eric Andersen85e5e722003-07-22 08:56:55 +0000519/* For some reason this is missing from some ancient C libraries.... */
Eric Andersen9f16d612000-06-12 23:11:16 +0000520#ifndef ELF32_ST_INFO
521# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
522#endif
523
524#ifndef ELF64_ST_INFO
525# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
526#endif
527
Mike Frysinger86a4bfb2005-10-02 07:02:16 +0000528#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
529#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
530#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
531#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
532#define ELF_R_SYM(val) ELFW(R_SYM)(val)
533
Eric Andersen9f16d612000-06-12 23:11:16 +0000534struct obj_string_patch;
535struct obj_symbol_patch;
536
537struct obj_section
538{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000539 ElfW(Shdr) header;
540 const char *name;
541 char *contents;
542 struct obj_section *load_next;
543 int idx;
Eric Andersen9f16d612000-06-12 23:11:16 +0000544};
545
546struct obj_symbol
547{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000548 struct obj_symbol *next; /* hash table link */
549 const char *name;
550 unsigned long value;
551 unsigned long size;
552 int secidx; /* the defining section index/module */
553 int info;
554 int ksymidx; /* for export to the kernel symtab */
555 int referenced; /* actually used in the link */
Eric Andersen9f16d612000-06-12 23:11:16 +0000556};
557
558/* Hardcode the hash table size. We shouldn't be needing so many
559 symbols that we begin to degrade performance, and we get a big win
560 by giving the compiler a constant divisor. */
561
562#define HASH_BUCKETS 521
563
564struct obj_file
565{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000566 ElfW(Ehdr) header;
567 ElfW(Addr) baseaddr;
568 struct obj_section **sections;
569 struct obj_section *load_order;
570 struct obj_section **load_order_search_start;
571 struct obj_string_patch *string_patches;
572 struct obj_symbol_patch *symbol_patches;
573 int (*symbol_cmp)(const char *, const char *);
574 unsigned long (*symbol_hash)(const char *);
575 unsigned long local_symtab_size;
576 struct obj_symbol **local_symtab;
577 struct obj_symbol *symtab[HASH_BUCKETS];
Eric Andersen9f16d612000-06-12 23:11:16 +0000578};
579
580enum obj_reloc
581{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000582 obj_reloc_ok,
583 obj_reloc_overflow,
584 obj_reloc_dangerous,
585 obj_reloc_unhandled
Eric Andersen9f16d612000-06-12 23:11:16 +0000586};
587
588struct obj_string_patch
589{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000590 struct obj_string_patch *next;
591 int reloc_secidx;
592 ElfW(Addr) reloc_offset;
593 ElfW(Addr) string_offset;
Eric Andersen9f16d612000-06-12 23:11:16 +0000594};
595
596struct obj_symbol_patch
597{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000598 struct obj_symbol_patch *next;
599 int reloc_secidx;
600 ElfW(Addr) reloc_offset;
601 struct obj_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000602};
603
604
605/* Generic object manipulation routines. */
606
Eric Andersen044228d2001-07-17 01:12:36 +0000607static unsigned long obj_elf_hash(const char *);
Eric Andersen9f16d612000-06-12 23:11:16 +0000608
Eric Andersen044228d2001-07-17 01:12:36 +0000609static unsigned long obj_elf_hash_n(const char *, unsigned long len);
Eric Andersen9f16d612000-06-12 23:11:16 +0000610
Eric Andersen044228d2001-07-17 01:12:36 +0000611static struct obj_symbol *obj_find_symbol (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000612 const char *name);
613
Eric Andersen044228d2001-07-17 01:12:36 +0000614static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000615 struct obj_symbol *sym);
616
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000617#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen044228d2001-07-17 01:12:36 +0000618static void obj_set_symbol_compare(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000619 int (*cmp)(const char *, const char *),
620 unsigned long (*hash)(const char *));
Eric Andersenf672c9e2001-07-31 22:51:49 +0000621#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000622
Eric Andersen044228d2001-07-17 01:12:36 +0000623static struct obj_section *obj_find_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000624 const char *name);
625
Eric Andersen044228d2001-07-17 01:12:36 +0000626static void obj_insert_section_load_order (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000627 struct obj_section *sec);
628
Eric Andersen044228d2001-07-17 01:12:36 +0000629static struct obj_section *obj_create_alloced_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000630 const char *name,
631 unsigned long align,
632 unsigned long size);
633
Eric Andersen044228d2001-07-17 01:12:36 +0000634static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000635 const char *name,
636 unsigned long align,
637 unsigned long size);
638
Eric Andersen044228d2001-07-17 01:12:36 +0000639static void *obj_extend_section (struct obj_section *sec, unsigned long more);
Eric Andersen9f16d612000-06-12 23:11:16 +0000640
Eric Andersen044228d2001-07-17 01:12:36 +0000641static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000642 const char *string);
643
Eric Andersen044228d2001-07-17 01:12:36 +0000644static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000645 struct obj_symbol *sym);
646
Eric Andersen044228d2001-07-17 01:12:36 +0000647static int obj_check_undefineds(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000648
Eric Andersen044228d2001-07-17 01:12:36 +0000649static void obj_allocate_commons(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000650
Eric Andersen044228d2001-07-17 01:12:36 +0000651static unsigned long obj_load_size (struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000652
Eric Andersen044228d2001-07-17 01:12:36 +0000653static int obj_relocate (struct obj_file *f, ElfW(Addr) base);
Eric Andersen9f16d612000-06-12 23:11:16 +0000654
Eric Andersen044228d2001-07-17 01:12:36 +0000655static struct obj_file *obj_load(FILE *f, int loadprogbits);
Eric Andersen9f16d612000-06-12 23:11:16 +0000656
Eric Andersen044228d2001-07-17 01:12:36 +0000657static int obj_create_image (struct obj_file *f, char *image);
Eric Andersen9f16d612000-06-12 23:11:16 +0000658
659/* Architecture specific manipulation routines. */
660
Eric Andersen044228d2001-07-17 01:12:36 +0000661static struct obj_file *arch_new_file (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000662
Eric Andersen044228d2001-07-17 01:12:36 +0000663static struct obj_section *arch_new_section (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000664
Eric Andersen044228d2001-07-17 01:12:36 +0000665static struct obj_symbol *arch_new_symbol (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000666
Eric Andersen044228d2001-07-17 01:12:36 +0000667static enum obj_reloc arch_apply_relocation (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000668 struct obj_section *targsec,
669 struct obj_section *symsec,
670 struct obj_symbol *sym,
671 ElfW(RelM) *rel, ElfW(Addr) value);
672
Eric Andersencffd5022002-05-24 06:50:15 +0000673static void arch_create_got (struct obj_file *f);
Bernhard Reutner-Fischere375e8c2006-03-29 18:57:09 +0000674#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
Glenn L McGrath759515c2003-08-30 06:00:33 +0000675static int obj_gpl_license(struct obj_file *f, const char **license);
Bernhard Reutner-Fischere375e8c2006-03-29 18:57:09 +0000676#endif /* ENABLE_FEATURE_CHECK_TAINTED_MODULE */
Eric Andersen9f16d612000-06-12 23:11:16 +0000677#endif /* obj.h */
678//----------------------------------------------------------------------------
679//--------end of modutils obj.h
680//----------------------------------------------------------------------------
681
682
Miles Baderae28b042002-04-01 09:34:25 +0000683/* SPFX is always a string, so it can be concatenated to string constants. */
684#ifdef SYMBOL_PREFIX
685#define SPFX SYMBOL_PREFIX
686#else
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000687#define SPFX ""
Miles Baderae28b042002-04-01 09:34:25 +0000688#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000689
Erik Andersen02104321999-12-17 18:57:34 +0000690
Erik Andersend387d011999-12-21 02:55:11 +0000691#define _PATH_MODULES "/lib/modules"
Rob Landleybc68cd12006-03-10 19:22:06 +0000692enum { STRVERSIONLEN = 32 };
Erik Andersend387d011999-12-21 02:55:11 +0000693
Eric Andersen9f16d612000-06-12 23:11:16 +0000694/*======================================================================*/
695
Denis Vlasenkofe76cd52006-09-23 12:32:58 +0000696static unsigned option_mask;
697#define OPTION_STR "sLo:fkvqx" USE_FEATURE_INSMOD_LOAD_MAP("m")
698enum {
699 OPT_s = 0x1, // -s /* log to syslog */
700 /* Not supported but kernel needs this for request_module(),
701 as this calls: modprobe -k -s -- <module>
702 so silently ignore this flag */
703 OPT_L = 0x2, // -L /* Stub warning */
704 /* Compatibility with modprobe.
705 In theory, this does locking, but we don't do
706 that. So be careful and plan your life around not
707 loading the same module 50 times concurrently. */
708 OPT_o = 0x4, // -o /* name the output module */
709 OPT_f = 0x8, // -f /* force loading */
710 OPT_k = 0x10, // -k /* module loaded by kerneld, auto-cleanable */
711 OPT_v = 0x20, // -v /* verbose output */
712 OPT_q = 0x40, // -q /* silent */
713 OPT_x = 0x80, // -x /* do not export externs */
714 OPT_m = 0x100, // -m /* print module load map */
715};
716#define flag_force_load (option_mask & OPT_f)
717#define flag_autoclean (option_mask & OPT_k)
718#define flag_verbose (option_mask & OPT_v)
719#define flag_quiet (option_mask & OPT_q)
720#define flag_noexport (option_mask & OPT_x)
721#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
722#define flag_print_load_map (option_mask & OPT_m)
723#else
724#define flag_print_load_map 0
725#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000726
727/*======================================================================*/
728
Eric Andersencffd5022002-05-24 06:50:15 +0000729#if defined(CONFIG_USE_LIST)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000730
Eric Andersencffd5022002-05-24 06:50:15 +0000731struct arch_list_entry
Eric Andersen21adca72000-12-06 18:18:26 +0000732{
Eric Andersencffd5022002-05-24 06:50:15 +0000733 struct arch_list_entry *next;
734 CONFIG_LIST_ARCHTYPE addend;
735 int offset;
736 int inited : 1;
Eric Andersen21adca72000-12-06 18:18:26 +0000737};
Eric Andersencffd5022002-05-24 06:50:15 +0000738
Eric Andersen21adca72000-12-06 18:18:26 +0000739#endif
740
Eric Andersencffd5022002-05-24 06:50:15 +0000741#if defined(CONFIG_USE_SINGLE)
742
743struct arch_single_entry
744{
Eric Andersen9f16d612000-06-12 23:11:16 +0000745 int offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000746 int inited : 1;
747 int allocated : 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000748};
Eric Andersencffd5022002-05-24 06:50:15 +0000749
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000750#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000751
Eric Andersen2bf658d2001-02-24 20:01:53 +0000752#if defined(__mips__)
753struct mips_hi16
754{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000755 struct mips_hi16 *next;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +0000756 ElfW(Addr) *addr;
757 ElfW(Addr) value;
Eric Andersen2bf658d2001-02-24 20:01:53 +0000758};
759#endif
760
Eric Andersenfe4208f2000-09-24 03:44:29 +0000761struct arch_file {
Eric Andersen9f16d612000-06-12 23:11:16 +0000762 struct obj_file root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000763#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000764 struct obj_section *plt;
Eric Andersen21adca72000-12-06 18:18:26 +0000765#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000766#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000767 struct obj_section *got;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000768#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000769#if defined(__mips__)
770 struct mips_hi16 *mips_hi16_list;
771#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000772};
773
Eric Andersenfe4208f2000-09-24 03:44:29 +0000774struct arch_symbol {
Eric Andersen9f16d612000-06-12 23:11:16 +0000775 struct obj_symbol root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000776#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000777#if defined(CONFIG_USE_PLT_LIST)
778 struct arch_list_entry *pltent;
779#else
780 struct arch_single_entry pltent;
781#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000782#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000783#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000784 struct arch_single_entry gotent;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000785#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000786};
787
788
Eric Andersen9f16d612000-06-12 23:11:16 +0000789struct external_module {
790 const char *name;
791 ElfW(Addr) addr;
792 int used;
793 size_t nsyms;
794 struct new_module_symbol *syms;
795};
796
Eric Andersen044228d2001-07-17 01:12:36 +0000797static struct new_module_symbol *ksyms;
798static size_t nksyms;
Eric Andersen9f16d612000-06-12 23:11:16 +0000799
Eric Andersen044228d2001-07-17 01:12:36 +0000800static struct external_module *ext_modules;
801static int n_ext_modules;
802static int n_ext_modules_used;
Erik Andersen02104321999-12-17 18:57:34 +0000803extern int delete_module(const char *);
Eric Andersena2a978a2001-04-05 06:08:14 +0000804
Eric Andersen61f83052002-06-22 17:15:42 +0000805static char *m_filename;
Robert Griebld378c312002-07-19 00:05:54 +0000806static char *m_fullName;
Erik Andersen02104321999-12-17 18:57:34 +0000807
Eric Andersenfe4208f2000-09-24 03:44:29 +0000808
Erik Andersen02104321999-12-17 18:57:34 +0000809
Eric Andersen9f16d612000-06-12 23:11:16 +0000810/*======================================================================*/
Erik Andersen02104321999-12-17 18:57:34 +0000811
Eric Andersen9f16d612000-06-12 23:11:16 +0000812
Eric Andersen14d35432001-05-14 17:07:32 +0000813static int check_module_name_match(const char *filename, struct stat *statbuf,
814 void *userdata)
Eric Andersen9f16d612000-06-12 23:11:16 +0000815{
Eric Andersen14d35432001-05-14 17:07:32 +0000816 char *fullname = (char *) userdata;
Eric Andersen9f16d612000-06-12 23:11:16 +0000817
Eric Andersen14d35432001-05-14 17:07:32 +0000818 if (fullname[0] == '\0')
Erik Andersene49d5ec2000-02-08 19:58:47 +0000819 return (FALSE);
820 else {
Rob Landleyd921b2e2006-08-03 15:41:12 +0000821 char *tmp, *tmp1 = xstrdup(filename);
Manuel Novoa III cad53642003-03-19 09:13:01 +0000822 tmp = bb_get_last_path_component(tmp1);
Eric Andersen14d35432001-05-14 17:07:32 +0000823 if (strcmp(tmp, fullname) == 0) {
824 free(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000825 /* Stop searching if we find a match */
Rob Landleyd921b2e2006-08-03 15:41:12 +0000826 m_filename = xstrdup(filename);
Eric Andersen3f47c452004-04-06 11:56:26 +0000827 return (FALSE);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000828 }
Eric Andersen14d35432001-05-14 17:07:32 +0000829 free(tmp1);
Erik Andersend387d011999-12-21 02:55:11 +0000830 }
Eric Andersen3f47c452004-04-06 11:56:26 +0000831 return (TRUE);
Erik Andersend387d011999-12-21 02:55:11 +0000832}
833
Erik Andersen02104321999-12-17 18:57:34 +0000834
Eric Andersen9f16d612000-06-12 23:11:16 +0000835/*======================================================================*/
836
Eric Andersen044228d2001-07-17 01:12:36 +0000837static struct obj_file *arch_new_file(void)
Erik Andersen02104321999-12-17 18:57:34 +0000838{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000839 struct arch_file *f;
Eric Andersen9f16d612000-06-12 23:11:16 +0000840 f = xmalloc(sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000841
Eric Andersencffd5022002-05-24 06:50:15 +0000842 memset(f, 0, sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000843
Eric Andersen9f16d612000-06-12 23:11:16 +0000844 return &f->root;
845}
846
Eric Andersen044228d2001-07-17 01:12:36 +0000847static struct obj_section *arch_new_section(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000848{
849 return xmalloc(sizeof(struct obj_section));
850}
851
Eric Andersen044228d2001-07-17 01:12:36 +0000852static struct obj_symbol *arch_new_symbol(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000853{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000854 struct arch_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000855 sym = xmalloc(sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000856
Eric Andersencffd5022002-05-24 06:50:15 +0000857 memset(sym, 0, sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000858
Eric Andersen9f16d612000-06-12 23:11:16 +0000859 return &sym->root;
860}
Eric Andersenfe4208f2000-09-24 03:44:29 +0000861
Eric Andersen044228d2001-07-17 01:12:36 +0000862static enum obj_reloc
Eric Andersen9f16d612000-06-12 23:11:16 +0000863arch_apply_relocation(struct obj_file *f,
864 struct obj_section *targsec,
865 struct obj_section *symsec,
866 struct obj_symbol *sym,
Mike Frysingerfa17c4b2005-10-02 07:14:06 +0000867 ElfW(RelM) *rel, ElfW(Addr) v)
Eric Andersen9f16d612000-06-12 23:11:16 +0000868{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000869 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersencffd5022002-05-24 06:50:15 +0000870 enum obj_reloc ret = obj_reloc_ok;
Eric Andersen21adca72000-12-06 18:18:26 +0000871 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
872 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000873#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
874 struct arch_symbol *isym = (struct arch_symbol *) sym;
875#endif
Eric Andersen3496fdc2006-01-30 23:09:20 +0000876#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) || defined(__sh__) || defined(__s390__)
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000877#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000878 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000879#endif
Eric Andersen3496fdc2006-01-30 23:09:20 +0000880#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000881#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000882 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
Eric Andersen21adca72000-12-06 18:18:26 +0000883 unsigned long *ip;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000884# if defined(CONFIG_USE_PLT_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +0000885 struct arch_list_entry *pe;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000886# else
Eric Andersencffd5022002-05-24 06:50:15 +0000887 struct arch_single_entry *pe;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000888# endif
Eric Andersencffd5022002-05-24 06:50:15 +0000889#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000890
Mike Frysinger86a4bfb2005-10-02 07:02:16 +0000891 switch (ELF_R_TYPE(rel->r_info)) {
Eric Andersenfe4208f2000-09-24 03:44:29 +0000892
Eric Andersencffd5022002-05-24 06:50:15 +0000893#if defined(__arm__)
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000894
Eric Andersen3b1a7442003-12-24 20:30:45 +0000895 case R_ARM_NONE:
896 break;
Eric Andersen9f16d612000-06-12 23:11:16 +0000897
Eric Andersen3b1a7442003-12-24 20:30:45 +0000898 case R_ARM_ABS32:
899 *loc += v;
900 break;
Miles Baderae28b042002-04-01 09:34:25 +0000901
Eric Andersen3b1a7442003-12-24 20:30:45 +0000902 case R_ARM_GOT32:
903 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +0000904
Eric Andersen3b1a7442003-12-24 20:30:45 +0000905 case R_ARM_GOTPC:
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000906 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
907 * (which is .got) similar to branch,
Eric Andersen3b1a7442003-12-24 20:30:45 +0000908 * but is full 32 bits relative */
Eric Andersencffd5022002-05-24 06:50:15 +0000909
Eric Andersen3b1a7442003-12-24 20:30:45 +0000910 *loc += got - dot;
911 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000912
Eric Andersen3b1a7442003-12-24 20:30:45 +0000913 case R_ARM_PC24:
914 case R_ARM_PLT32:
915 goto bb_use_plt;
916
917 case R_ARM_GOTOFF: /* address relative to the got */
Eric Andersen3b1a7442003-12-24 20:30:45 +0000918 *loc += v - got;
919 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000920
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000921#elif defined(__cris__)
922
923 case R_CRIS_NONE:
Eric Andersen3b1a7442003-12-24 20:30:45 +0000924 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000925
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000926 case R_CRIS_32:
927 /* CRIS keeps the relocation value in the r_addend field and
928 * should not use whats in *loc at all
929 */
Eric Andersen3b1a7442003-12-24 20:30:45 +0000930 *loc = v;
931 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000932
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000933#elif defined(__H8300H__) || defined(__H8300S__)
Eric Andersenbf77f612003-01-23 06:02:39 +0000934
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000935 case R_H8_DIR24R8:
936 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
937 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
Eric Andersen3b1a7442003-12-24 20:30:45 +0000938 break;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000939 case R_H8_DIR24A8:
940 *loc += v;
Eric Andersen3b1a7442003-12-24 20:30:45 +0000941 break;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +0000942 case R_H8_DIR32:
943 case R_H8_DIR32A16:
944 *loc += v;
945 break;
946 case R_H8_PCREL16:
947 v -= dot + 2;
948 if ((ElfW(Sword))v > 0x7fff ||
949 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
950 ret = obj_reloc_overflow;
951 else
952 *(unsigned short *)loc = v;
953 break;
954 case R_H8_PCREL8:
955 v -= dot + 1;
956 if ((ElfW(Sword))v > 0x7f ||
957 (ElfW(Sword))v < -(ElfW(Sword))0x80)
958 ret = obj_reloc_overflow;
959 else
960 *(unsigned char *)loc = v;
Eric Andersen3b1a7442003-12-24 20:30:45 +0000961 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000962
Eric Andersencffd5022002-05-24 06:50:15 +0000963#elif defined(__i386__)
964
Eric Andersen3b1a7442003-12-24 20:30:45 +0000965 case R_386_NONE:
966 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000967
Eric Andersen3b1a7442003-12-24 20:30:45 +0000968 case R_386_32:
969 *loc += v;
970 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000971
Eric Andersen3b1a7442003-12-24 20:30:45 +0000972 case R_386_PLT32:
973 case R_386_PC32:
974 *loc += v - dot;
975 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000976
Eric Andersen3b1a7442003-12-24 20:30:45 +0000977 case R_386_GLOB_DAT:
978 case R_386_JMP_SLOT:
979 *loc = v;
980 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000981
Eric Andersen3b1a7442003-12-24 20:30:45 +0000982 case R_386_RELATIVE:
983 *loc += f->baseaddr;
984 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000985
Eric Andersen3b1a7442003-12-24 20:30:45 +0000986 case R_386_GOTPC:
Eric Andersen3b1a7442003-12-24 20:30:45 +0000987 *loc += got - dot;
988 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000989
Eric Andersen3b1a7442003-12-24 20:30:45 +0000990 case R_386_GOT32:
991 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +0000992
Eric Andersen3b1a7442003-12-24 20:30:45 +0000993 case R_386_GOTOFF:
Eric Andersen3b1a7442003-12-24 20:30:45 +0000994 *loc += v - got;
995 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000996
Mike Frysinger280dae72006-06-06 06:30:32 +0000997#elif defined (__microblaze__)
998 case R_MICROBLAZE_NONE:
999 case R_MICROBLAZE_64_NONE:
1000 case R_MICROBLAZE_32_SYM_OP_SYM:
1001 case R_MICROBLAZE_32_PCREL:
1002 break;
1003
1004 case R_MICROBLAZE_64_PCREL: {
1005 /* dot is the address of the current instruction.
1006 * v is the target symbol address.
1007 * So we need to extract the offset in the code,
Denis Vlasenko9213a9e2006-09-17 16:28:10 +00001008 * adding v, then subtrating the current address
Mike Frysinger280dae72006-06-06 06:30:32 +00001009 * of this instruction.
1010 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000"
1011 */
1012
1013 /* Get split offset stored in code */
1014 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
1015 (loc[1] & 0xFFFF);
1016
Denis Vlasenko9213a9e2006-09-17 16:28:10 +00001017 /* Adjust relative offset. -4 adjustment required
Mike Frysinger280dae72006-06-06 06:30:32 +00001018 * because dot points to the IMM insn, but branch
1019 * is computed relative to the branch instruction itself.
1020 */
1021 temp += v - dot - 4;
1022
1023 /* Store back into code */
1024 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
1025 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
1026
1027 break;
1028 }
1029
1030 case R_MICROBLAZE_32:
1031 *loc += v;
1032 break;
1033
1034 case R_MICROBLAZE_64: {
1035 /* Get split pointer stored in code */
1036 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
1037 (loc[1] & 0xFFFF);
1038
1039 /* Add reloc offset */
1040 temp1+=v;
1041
1042 /* Store back into code */
1043 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
1044 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
1045
1046 break;
1047 }
1048
1049 case R_MICROBLAZE_32_PCREL_LO:
1050 case R_MICROBLAZE_32_LO:
1051 case R_MICROBLAZE_SRO32:
1052 case R_MICROBLAZE_SRW32:
1053 ret = obj_reloc_unhandled;
1054 break;
1055
Eric Andersencffd5022002-05-24 06:50:15 +00001056#elif defined(__mc68000__)
1057
Eric Andersen3b1a7442003-12-24 20:30:45 +00001058 case R_68K_NONE:
1059 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001060
Eric Andersen3b1a7442003-12-24 20:30:45 +00001061 case R_68K_32:
1062 *loc += v;
1063 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001064
Eric Andersen3b1a7442003-12-24 20:30:45 +00001065 case R_68K_8:
1066 if (v > 0xff) {
1067 ret = obj_reloc_overflow;
1068 }
1069 *(char *)loc = v;
1070 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001071
Eric Andersen3b1a7442003-12-24 20:30:45 +00001072 case R_68K_16:
1073 if (v > 0xffff) {
1074 ret = obj_reloc_overflow;
1075 }
1076 *(short *)loc = v;
1077 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001078
Eric Andersen3b1a7442003-12-24 20:30:45 +00001079 case R_68K_PC8:
1080 v -= dot;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001081 if ((ElfW(Sword))v > 0x7f ||
1082 (ElfW(Sword))v < -(ElfW(Sword))0x80) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00001083 ret = obj_reloc_overflow;
1084 }
1085 *(char *)loc = v;
1086 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001087
Eric Andersen3b1a7442003-12-24 20:30:45 +00001088 case R_68K_PC16:
1089 v -= dot;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001090 if ((ElfW(Sword))v > 0x7fff ||
1091 (ElfW(Sword))v < -(ElfW(Sword))0x8000) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00001092 ret = obj_reloc_overflow;
1093 }
1094 *(short *)loc = v;
1095 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001096
Eric Andersen3b1a7442003-12-24 20:30:45 +00001097 case R_68K_PC32:
1098 *(int *)loc = v - dot;
1099 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001100
Eric Andersen3b1a7442003-12-24 20:30:45 +00001101 case R_68K_GLOB_DAT:
1102 case R_68K_JMP_SLOT:
1103 *loc = v;
1104 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001105
Eric Andersen3b1a7442003-12-24 20:30:45 +00001106 case R_68K_RELATIVE:
1107 *(int *)loc += f->baseaddr;
1108 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001109
Eric Andersen3b1a7442003-12-24 20:30:45 +00001110 case R_68K_GOT32:
1111 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +00001112
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001113# ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001114 case R_68K_GOTOFF:
Eric Andersen3b1a7442003-12-24 20:30:45 +00001115 *loc += v - got;
1116 break;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001117# endif
Eric Andersencffd5022002-05-24 06:50:15 +00001118
1119#elif defined(__mips__)
1120
Eric Andersen3b1a7442003-12-24 20:30:45 +00001121 case R_MIPS_NONE:
1122 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001123
Eric Andersen3b1a7442003-12-24 20:30:45 +00001124 case R_MIPS_32:
1125 *loc += v;
1126 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001127
Eric Andersen3b1a7442003-12-24 20:30:45 +00001128 case R_MIPS_26:
1129 if (v % 4)
1130 ret = obj_reloc_dangerous;
1131 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1132 ret = obj_reloc_overflow;
1133 *loc =
1134 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1135 0x03ffffff);
1136 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001137
Eric Andersen3b1a7442003-12-24 20:30:45 +00001138 case R_MIPS_HI16:
1139 {
1140 struct mips_hi16 *n;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001141
Eric Andersen3b1a7442003-12-24 20:30:45 +00001142 /* We cannot relocate this one now because we don't know the value
1143 of the carry we need to add. Save the information, and let LO16
1144 do the actual relocation. */
1145 n = (struct mips_hi16 *) xmalloc(sizeof *n);
1146 n->addr = loc;
1147 n->value = v;
1148 n->next = ifile->mips_hi16_list;
1149 ifile->mips_hi16_list = n;
1150 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001151 }
1152
Eric Andersen3b1a7442003-12-24 20:30:45 +00001153 case R_MIPS_LO16:
1154 {
1155 unsigned long insnlo = *loc;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001156 ElfW(Addr) val, vallo;
Eric Andersen3b1a7442003-12-24 20:30:45 +00001157
1158 /* Sign extend the addend we extract from the lo insn. */
1159 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1160
1161 if (ifile->mips_hi16_list != NULL) {
1162 struct mips_hi16 *l;
1163
1164 l = ifile->mips_hi16_list;
1165 while (l != NULL) {
1166 struct mips_hi16 *next;
1167 unsigned long insn;
1168
Eric Andersen3b1a7442003-12-24 20:30:45 +00001169 /* Do the HI16 relocation. Note that we actually don't
1170 need to know anything about the LO16 itself, except where
1171 to find the low 16 bits of the addend needed by the LO16. */
1172 insn = *l->addr;
1173 val =
1174 ((insn & 0xffff) << 16) +
1175 vallo;
1176 val += v;
1177
1178 /* Account for the sign extension that will happen in the
1179 low bits. */
1180 val =
1181 ((val >> 16) +
1182 ((val & 0x8000) !=
1183 0)) & 0xffff;
1184
1185 insn = (insn & ~0xffff) | val;
1186 *l->addr = insn;
1187
1188 next = l->next;
1189 free(l);
1190 l = next;
1191 }
1192
1193 ifile->mips_hi16_list = NULL;
1194 }
1195
1196 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1197 val = v + vallo;
1198 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1199 *loc = insnlo;
1200 break;
1201 }
Eric Andersen2bf658d2001-02-24 20:01:53 +00001202
Mike Frysingerf982d862006-01-04 00:11:26 +00001203#elif defined(__nios2__)
1204
1205 case R_NIOS2_NONE:
1206 break;
1207
1208 case R_NIOS2_BFD_RELOC_32:
1209 *loc += v;
1210 break;
1211
1212 case R_NIOS2_BFD_RELOC_16:
1213 if (v > 0xffff) {
1214 ret = obj_reloc_overflow;
1215 }
1216 *(short *)loc = v;
1217 break;
1218
1219 case R_NIOS2_BFD_RELOC_8:
1220 if (v > 0xff) {
1221 ret = obj_reloc_overflow;
1222 }
1223 *(char *)loc = v;
1224 break;
1225
1226 case R_NIOS2_S16:
1227 {
1228 Elf32_Addr word;
1229
1230 if ((Elf32_Sword)v > 0x7fff ||
1231 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1232 ret = obj_reloc_overflow;
1233 }
1234
1235 word = *loc;
1236 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1237 (word & 0x3f);
1238 }
1239 break;
1240
1241 case R_NIOS2_U16:
1242 {
1243 Elf32_Addr word;
1244
1245 if (v > 0xffff) {
1246 ret = obj_reloc_overflow;
1247 }
1248
1249 word = *loc;
1250 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1251 (word & 0x3f);
1252 }
1253 break;
1254
1255 case R_NIOS2_PCREL16:
1256 {
1257 Elf32_Addr word;
1258
1259 v -= dot + 4;
1260 if ((Elf32_Sword)v > 0x7fff ||
1261 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1262 ret = obj_reloc_overflow;
1263 }
1264
1265 word = *loc;
1266 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1267 }
1268 break;
1269
1270 case R_NIOS2_GPREL:
1271 {
1272 Elf32_Addr word, gp;
1273 /* get _gp */
1274 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
1275 v-=gp;
1276 if ((Elf32_Sword)v > 0x7fff ||
1277 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1278 ret = obj_reloc_overflow;
1279 }
1280
1281 word = *loc;
1282 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1283 }
1284 break;
1285
1286 case R_NIOS2_CALL26:
1287 if (v & 3)
1288 ret = obj_reloc_dangerous;
1289 if ((v >> 28) != (dot >> 28))
1290 ret = obj_reloc_overflow;
1291 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1292 break;
1293
1294 case R_NIOS2_IMM5:
1295 {
1296 Elf32_Addr word;
1297
1298 if (v > 0x1f) {
1299 ret = obj_reloc_overflow;
1300 }
1301
1302 word = *loc & ~0x7c0;
1303 *loc = word | ((v & 0x1f) << 6);
1304 }
1305 break;
1306
1307 case R_NIOS2_IMM6:
1308 {
1309 Elf32_Addr word;
1310
1311 if (v > 0x3f) {
1312 ret = obj_reloc_overflow;
1313 }
1314
1315 word = *loc & ~0xfc0;
1316 *loc = word | ((v & 0x3f) << 6);
1317 }
1318 break;
1319
1320 case R_NIOS2_IMM8:
1321 {
1322 Elf32_Addr word;
1323
1324 if (v > 0xff) {
1325 ret = obj_reloc_overflow;
1326 }
1327
1328 word = *loc & ~0x3fc0;
1329 *loc = word | ((v & 0xff) << 6);
1330 }
1331 break;
1332
1333 case R_NIOS2_HI16:
1334 {
1335 Elf32_Addr word;
1336
1337 word = *loc;
1338 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1339 (word & 0x3f);
1340 }
1341 break;
1342
1343 case R_NIOS2_LO16:
1344 {
1345 Elf32_Addr word;
1346
1347 word = *loc;
1348 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1349 (word & 0x3f);
1350 }
1351 break;
1352
1353 case R_NIOS2_HIADJ16:
1354 {
1355 Elf32_Addr word1, word2;
1356
1357 word1 = *loc;
1358 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1359 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1360 (word1 & 0x3f);
1361 }
1362 break;
1363
Mike Frysingerebee0e72006-02-18 06:14:31 +00001364#elif defined(__powerpc64__)
Rob Landleyb4ec3392006-02-20 14:39:55 +00001365 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */
Mike Frysingerebee0e72006-02-18 06:14:31 +00001366
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001367#elif defined(__powerpc__)
Eric Andersencffd5022002-05-24 06:50:15 +00001368
Eric Andersen3b1a7442003-12-24 20:30:45 +00001369 case R_PPC_ADDR16_HA:
1370 *(unsigned short *)loc = (v + 0x8000) >> 16;
1371 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001372
Eric Andersen3b1a7442003-12-24 20:30:45 +00001373 case R_PPC_ADDR16_HI:
1374 *(unsigned short *)loc = v >> 16;
1375 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001376
Eric Andersen3b1a7442003-12-24 20:30:45 +00001377 case R_PPC_ADDR16_LO:
1378 *(unsigned short *)loc = v;
1379 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001380
Eric Andersen3b1a7442003-12-24 20:30:45 +00001381 case R_PPC_REL24:
1382 goto bb_use_plt;
Eric Andersencffd5022002-05-24 06:50:15 +00001383
Eric Andersen3b1a7442003-12-24 20:30:45 +00001384 case R_PPC_REL32:
1385 *loc = v - dot;
1386 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001387
Eric Andersen3b1a7442003-12-24 20:30:45 +00001388 case R_PPC_ADDR32:
1389 *loc = v;
1390 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001391
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001392#elif defined(__s390__)
1393
1394 case R_390_32:
1395 *(unsigned int *) loc += v;
1396 break;
1397 case R_390_16:
1398 *(unsigned short *) loc += v;
1399 break;
1400 case R_390_8:
1401 *(unsigned char *) loc += v;
1402 break;
1403
1404 case R_390_PC32:
1405 *(unsigned int *) loc += v - dot;
1406 break;
1407 case R_390_PC16DBL:
1408 *(unsigned short *) loc += (v - dot) >> 1;
1409 break;
1410 case R_390_PC16:
1411 *(unsigned short *) loc += v - dot;
1412 break;
1413
1414 case R_390_PLT32:
1415 case R_390_PLT16DBL:
1416 /* find the plt entry and initialize it. */
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001417 pe = (struct arch_single_entry *) &isym->pltent;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001418 if (pe->inited == 0) {
1419 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1420 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
1421 ip[1] = 0x100607f1;
1422 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1423 ip[2] = v - 2;
1424 else
1425 ip[2] = v;
1426 pe->inited = 1;
1427 }
1428
1429 /* Insert relative distance to target. */
1430 v = plt + pe->offset - dot;
1431 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1432 *(unsigned int *) loc = (unsigned int) v;
1433 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1434 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1435 break;
1436
1437 case R_390_GLOB_DAT:
1438 case R_390_JMP_SLOT:
1439 *loc = v;
1440 break;
1441
1442 case R_390_RELATIVE:
1443 *loc += f->baseaddr;
1444 break;
1445
1446 case R_390_GOTPC:
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001447 *(unsigned long *) loc += got - dot;
1448 break;
1449
1450 case R_390_GOT12:
1451 case R_390_GOT16:
1452 case R_390_GOT32:
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001453 if (!isym->gotent.inited)
1454 {
1455 isym->gotent.inited = 1;
1456 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1457 }
1458 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1459 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1460 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1461 *(unsigned short *) loc += isym->gotent.offset;
1462 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1463 *(unsigned int *) loc += isym->gotent.offset;
1464 break;
1465
1466# ifndef R_390_GOTOFF32
1467# define R_390_GOTOFF32 R_390_GOTOFF
1468# endif
1469 case R_390_GOTOFF32:
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001470 *loc += v - got;
1471 break;
1472
Eric Andersencffd5022002-05-24 06:50:15 +00001473#elif defined(__sh__)
1474
Eric Andersen3b1a7442003-12-24 20:30:45 +00001475 case R_SH_NONE:
1476 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001477
Eric Andersen3b1a7442003-12-24 20:30:45 +00001478 case R_SH_DIR32:
1479 *loc += v;
1480 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001481
Eric Andersen3b1a7442003-12-24 20:30:45 +00001482 case R_SH_REL32:
1483 *loc += v - dot;
1484 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001485
Eric Andersen3b1a7442003-12-24 20:30:45 +00001486 case R_SH_PLT32:
1487 *loc = v - dot;
1488 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001489
Eric Andersen3b1a7442003-12-24 20:30:45 +00001490 case R_SH_GLOB_DAT:
1491 case R_SH_JMP_SLOT:
1492 *loc = v;
1493 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001494
Eric Andersen3b1a7442003-12-24 20:30:45 +00001495 case R_SH_RELATIVE:
1496 *loc = f->baseaddr + rel->r_addend;
1497 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001498
Eric Andersen3b1a7442003-12-24 20:30:45 +00001499 case R_SH_GOTPC:
Eric Andersen3b1a7442003-12-24 20:30:45 +00001500 *loc = got - dot + rel->r_addend;
1501 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001502
Eric Andersen3b1a7442003-12-24 20:30:45 +00001503 case R_SH_GOT32:
1504 goto bb_use_got;
1505
1506 case R_SH_GOTOFF:
Eric Andersen3b1a7442003-12-24 20:30:45 +00001507 *loc = v - got;
1508 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001509
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001510# if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001511 case R_SH_IMM_MEDLOW16:
1512 case R_SH_IMM_LOW16:
1513 {
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001514 ElfW(Addr) word;
Eric Andersenbf833552003-08-13 19:56:33 +00001515
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001516 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001517 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001518
Eric Andersen3b1a7442003-12-24 20:30:45 +00001519 /*
1520 * movi and shori have the format:
1521 *
1522 * | op | imm | reg | reserved |
1523 * 31..26 25..10 9.. 4 3 .. 0
1524 *
1525 * so we simply mask and or in imm.
1526 */
1527 word = *loc & ~0x3fffc00;
1528 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001529
Eric Andersen3b1a7442003-12-24 20:30:45 +00001530 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001531
Eric Andersen3b1a7442003-12-24 20:30:45 +00001532 break;
1533 }
Eric Andersenbf833552003-08-13 19:56:33 +00001534
Eric Andersen3b1a7442003-12-24 20:30:45 +00001535 case R_SH_IMM_MEDLOW16_PCREL:
1536 case R_SH_IMM_LOW16_PCREL:
1537 {
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001538 ElfW(Addr) word;
Eric Andersenbf833552003-08-13 19:56:33 +00001539
Eric Andersen3b1a7442003-12-24 20:30:45 +00001540 word = *loc & ~0x3fffc00;
Eric Andersenbf833552003-08-13 19:56:33 +00001541
Eric Andersen3b1a7442003-12-24 20:30:45 +00001542 v -= dot;
Eric Andersenbf833552003-08-13 19:56:33 +00001543
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001544 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001545 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001546
Eric Andersen3b1a7442003-12-24 20:30:45 +00001547 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001548
Eric Andersen3b1a7442003-12-24 20:30:45 +00001549 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001550
Eric Andersen3b1a7442003-12-24 20:30:45 +00001551 break;
1552 }
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001553# endif /* __SH5__ */
Eric Andersen9f16d612000-06-12 23:11:16 +00001554
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001555#elif defined (__v850e__)
Eric Andersencffd5022002-05-24 06:50:15 +00001556
Eric Andersen3b1a7442003-12-24 20:30:45 +00001557 case R_V850_NONE:
1558 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001559
Eric Andersen3b1a7442003-12-24 20:30:45 +00001560 case R_V850_32:
1561 /* We write two shorts instead of a long because even
1562 32-bit insns only need half-word alignment, but
1563 32-bit data needs to be long-word aligned. */
1564 v += ((unsigned short *)loc)[0];
1565 v += ((unsigned short *)loc)[1] << 16;
1566 ((unsigned short *)loc)[0] = v & 0xffff;
1567 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1568 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001569
Eric Andersen3b1a7442003-12-24 20:30:45 +00001570 case R_V850_22_PCREL:
1571 goto bb_use_plt;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001572
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001573#elif defined(__x86_64__)
Mike Frysingerc31fcbb2005-10-02 07:54:07 +00001574
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001575 case R_X86_64_NONE:
Eric Andersen3b1a7442003-12-24 20:30:45 +00001576 break;
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001577
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001578 case R_X86_64_64:
1579 *loc += v;
1580 break;
1581
1582 case R_X86_64_32:
1583 *(unsigned int *) loc += v;
1584 if (v > 0xffffffff)
1585 {
1586 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */
1587 /* error("Possibly is module compiled without -mcmodel=kernel!"); */
1588 }
1589 break;
1590
1591 case R_X86_64_32S:
1592 *(signed int *) loc += v;
1593 break;
1594
1595 case R_X86_64_16:
1596 *(unsigned short *) loc += v;
1597 break;
1598
1599 case R_X86_64_8:
1600 *(unsigned char *) loc += v;
1601 break;
1602
1603 case R_X86_64_PC32:
1604 *(unsigned int *) loc += v - dot;
1605 break;
1606
1607 case R_X86_64_PC16:
1608 *(unsigned short *) loc += v - dot;
1609 break;
1610
1611 case R_X86_64_PC8:
1612 *(unsigned char *) loc += v - dot;
1613 break;
1614
1615 case R_X86_64_GLOB_DAT:
1616 case R_X86_64_JUMP_SLOT:
Eric Andersen3b1a7442003-12-24 20:30:45 +00001617 *loc = v;
1618 break;
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001619
1620 case R_X86_64_RELATIVE:
1621 *loc += f->baseaddr;
1622 break;
1623
1624 case R_X86_64_GOT32:
1625 case R_X86_64_GOTPCREL:
1626 goto bb_use_got;
1627# if 0
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001628 if (!isym->gotent.reloc_done)
1629 {
1630 isym->gotent.reloc_done = 1;
1631 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1632 }
1633 /* XXX are these really correct? */
1634 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1635 *(unsigned int *) loc += v + isym->gotent.offset;
1636 else
1637 *loc += isym->gotent.offset;
1638 break;
1639# endif
1640
Mike Frysingerf982d862006-01-04 00:11:26 +00001641#else
1642# warning "no idea how to handle relocations on your arch"
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001643#endif
1644
Mike Frysingercb1ce7b2005-10-02 07:50:49 +00001645 default:
1646 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1647 ret = obj_reloc_unhandled;
Eric Andersenee70fa52004-05-26 11:38:46 +00001648 break;
Eric Andersenee70fa52004-05-26 11:38:46 +00001649
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001650#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001651
Eric Andersen3b1a7442003-12-24 20:30:45 +00001652bb_use_plt:
Eric Andersencffd5022002-05-24 06:50:15 +00001653
Eric Andersen3b1a7442003-12-24 20:30:45 +00001654 /* find the plt entry and initialize it if necessary */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001655
Eric Andersencffd5022002-05-24 06:50:15 +00001656#if defined(CONFIG_USE_PLT_LIST)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001657 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1658 pe = pe->next;
Eric Andersencffd5022002-05-24 06:50:15 +00001659#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001660 pe = &isym->pltent;
Eric Andersencffd5022002-05-24 06:50:15 +00001661#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001662
Eric Andersen3b1a7442003-12-24 20:30:45 +00001663 if (! pe->inited) {
1664 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001665
Eric Andersen3b1a7442003-12-24 20:30:45 +00001666 /* generate some machine code */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001667
1668#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001669 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1670 ip[1] = v; /* sym@ */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001671#endif
1672#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001673 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
Mike Frysingerfa17c4b2005-10-02 07:14:06 +00001674 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
Eric Andersen3b1a7442003-12-24 20:30:45 +00001675 ip[2] = 0x7d6903a6; /* mtctr r11 */
1676 ip[3] = 0x4e800420; /* bctr */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001677#endif
Miles Baderae28b042002-04-01 09:34:25 +00001678#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001679 /* We have to trash a register, so we assume that any control
1680 transfer more than 21-bits away must be a function call
1681 (so we can use a call-clobbered register). */
1682 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1683 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
Miles Baderae28b042002-04-01 09:34:25 +00001684#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001685 pe->inited = 1;
1686 }
Eric Andersen21adca72000-12-06 18:18:26 +00001687
Eric Andersen3b1a7442003-12-24 20:30:45 +00001688 /* relative distance to target */
1689 v -= dot;
1690 /* if the target is too far away.... */
Miles Baderae28b042002-04-01 09:34:25 +00001691#if defined (__arm__) || defined (__powerpc__)
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001692 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
Miles Baderae28b042002-04-01 09:34:25 +00001693#elif defined (__v850e__)
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001694 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
Miles Baderae28b042002-04-01 09:34:25 +00001695#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001696 /* go via the plt */
1697 v = plt + pe->offset - dot;
Miles Baderae28b042002-04-01 09:34:25 +00001698
1699#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001700 if (v & 1)
Miles Baderae28b042002-04-01 09:34:25 +00001701#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001702 if (v & 3)
Miles Baderae28b042002-04-01 09:34:25 +00001703#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001704 ret = obj_reloc_dangerous;
Eric Andersen21adca72000-12-06 18:18:26 +00001705
Eric Andersen3b1a7442003-12-24 20:30:45 +00001706 /* merge the offset into the instruction. */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001707#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001708 /* Convert to words. */
1709 v >>= 2;
Eric Andersen21adca72000-12-06 18:18:26 +00001710
Eric Andersen3b1a7442003-12-24 20:30:45 +00001711 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
Eric Andersenfe4208f2000-09-24 03:44:29 +00001712#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001713#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001714 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001715#endif
Miles Baderae28b042002-04-01 09:34:25 +00001716#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001717 /* We write two shorts instead of a long because even 32-bit insns
1718 only need half-word alignment, but the 32-bit data write needs
1719 to be long-word aligned. */
1720 ((unsigned short *)loc)[0] =
1721 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1722 | ((v >> 16) & 0x3f); /* offs high part */
1723 ((unsigned short *)loc)[1] =
1724 (v & 0xffff); /* offs low part */
Miles Baderae28b042002-04-01 09:34:25 +00001725#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001726 break;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001727#endif /* CONFIG_USE_PLT_ENTRIES */
Eric Andersenfe4208f2000-09-24 03:44:29 +00001728
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001729#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001730bb_use_got:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001731
Eric Andersen3b1a7442003-12-24 20:30:45 +00001732 /* needs an entry in the .got: set it, once */
1733 if (!isym->gotent.inited) {
1734 isym->gotent.inited = 1;
1735 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1736 }
1737 /* make the reloc with_respect_to_.got */
Eric Andersen21adca72000-12-06 18:18:26 +00001738#if defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001739 *loc += isym->gotent.offset + rel->r_addend;
Eric Andersenb4a26e62001-06-19 15:00:52 +00001740#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001741 *loc += isym->gotent.offset;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001742#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001743 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001744
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001745#endif /* CONFIG_USE_GOT_ENTRIES */
Eric Andersen9f16d612000-06-12 23:11:16 +00001746 }
1747
1748 return ret;
1749}
1750
Eric Andersencffd5022002-05-24 06:50:15 +00001751
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001752#if defined(CONFIG_USE_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001753
1754static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1755 int offset, int size)
1756{
1757 struct arch_list_entry *pe;
1758
1759 for (pe = *list; pe != NULL; pe = pe->next) {
1760 if (pe->addend == rel->r_addend) {
1761 break;
1762 }
1763 }
1764
1765 if (pe == NULL) {
1766 pe = xmalloc(sizeof(struct arch_list_entry));
1767 pe->next = *list;
1768 pe->addend = rel->r_addend;
1769 pe->offset = offset;
1770 pe->inited = 0;
1771 *list = pe;
1772 return size;
1773 }
1774 return 0;
1775}
1776
1777#endif
1778
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001779#if defined(CONFIG_USE_SINGLE)
Eric Andersencffd5022002-05-24 06:50:15 +00001780
1781static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
1782 int offset, int size)
1783{
1784 if (single->allocated == 0) {
1785 single->allocated = 1;
1786 single->offset = offset;
1787 single->inited = 0;
1788 return size;
1789 }
1790 return 0;
1791}
1792
1793#endif
1794
1795#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
1796
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001797static struct obj_section *arch_xsect_init(struct obj_file *f, char *name,
Eric Andersencffd5022002-05-24 06:50:15 +00001798 int offset, int size)
1799{
1800 struct obj_section *myrelsec = obj_find_section(f, name);
1801
1802 if (offset == 0) {
1803 offset += size;
1804 }
1805
1806 if (myrelsec) {
1807 obj_extend_section(myrelsec, offset);
1808 } else {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001809 myrelsec = obj_create_alloced_section(f, name,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001810 size, offset);
Eric Andersencffd5022002-05-24 06:50:15 +00001811 }
1812
1813 return myrelsec;
1814}
1815
1816#endif
1817
1818static void arch_create_got(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00001819{
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001820#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001821 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001822 int i;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001823#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001824 int got_offset = 0, got_needed = 0, got_allocate;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001825#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001826#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001827 int plt_offset = 0, plt_needed = 0, plt_allocate;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001828#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001829 struct obj_section *relsec, *symsec, *strsec;
Eric Andersen21adca72000-12-06 18:18:26 +00001830 ElfW(RelM) *rel, *relend;
1831 ElfW(Sym) *symtab, *extsym;
1832 const char *strtab, *name;
1833 struct arch_symbol *intsym;
Eric Andersen9f16d612000-06-12 23:11:16 +00001834
Eric Andersen21adca72000-12-06 18:18:26 +00001835 for (i = 0; i < f->header.e_shnum; ++i) {
1836 relsec = f->sections[i];
1837 if (relsec->header.sh_type != SHT_RELM)
Eric Andersen9f16d612000-06-12 23:11:16 +00001838 continue;
1839
Eric Andersen21adca72000-12-06 18:18:26 +00001840 symsec = f->sections[relsec->header.sh_link];
1841 strsec = f->sections[symsec->header.sh_link];
Eric Andersen9f16d612000-06-12 23:11:16 +00001842
Eric Andersen21adca72000-12-06 18:18:26 +00001843 rel = (ElfW(RelM) *) relsec->contents;
1844 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1845 symtab = (ElfW(Sym) *) symsec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00001846 strtab = (const char *) strsec->contents;
1847
1848 for (; rel < relend; ++rel) {
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001849 extsym = &symtab[ELF_R_SYM(rel->r_info)];
Eric Andersen9f16d612000-06-12 23:11:16 +00001850
Eric Andersencffd5022002-05-24 06:50:15 +00001851#if defined(CONFIG_USE_GOT_ENTRIES)
1852 got_allocate = 0;
1853#endif
1854#if defined(CONFIG_USE_PLT_ENTRIES)
1855 plt_allocate = 0;
1856#endif
1857
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00001858 switch (ELF_R_TYPE(rel->r_info)) {
Eric Andersen21adca72000-12-06 18:18:26 +00001859#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001860 case R_ARM_PC24:
1861 case R_ARM_PLT32:
1862 plt_allocate = 1;
1863 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001864
Eric Andersen3b1a7442003-12-24 20:30:45 +00001865 case R_ARM_GOTOFF:
1866 case R_ARM_GOTPC:
1867 got_needed = 1;
1868 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001869
Eric Andersen3b1a7442003-12-24 20:30:45 +00001870 case R_ARM_GOT32:
1871 got_allocate = 1;
1872 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001873
Eric Andersen21adca72000-12-06 18:18:26 +00001874#elif defined(__i386__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001875 case R_386_GOTPC:
1876 case R_386_GOTOFF:
1877 got_needed = 1;
1878 continue;
Eric Andersen21adca72000-12-06 18:18:26 +00001879
Eric Andersen3b1a7442003-12-24 20:30:45 +00001880 case R_386_GOT32:
1881 got_allocate = 1;
1882 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001883
1884#elif defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001885 case R_PPC_REL24:
1886 plt_allocate = 1;
1887 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001888
1889#elif defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001890 case R_68K_GOT32:
1891 got_allocate = 1;
1892 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001893
Eric Andersen16451a02004-03-19 12:16:18 +00001894#ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001895 case R_68K_GOTOFF:
1896 got_needed = 1;
1897 continue;
Eric Andersen16451a02004-03-19 12:16:18 +00001898#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001899
1900#elif defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001901 case R_SH_GOT32:
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001902 got_allocate = 1;
Eric Andersen3b1a7442003-12-24 20:30:45 +00001903 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001904
Eric Andersen3b1a7442003-12-24 20:30:45 +00001905 case R_SH_GOTPC:
1906 case R_SH_GOTOFF:
1907 got_needed = 1;
1908 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001909
1910#elif defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001911 case R_V850_22_PCREL:
1912 plt_needed = 1;
1913 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001914
1915#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001916 default:
1917 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00001918 }
1919
Eric Andersen21adca72000-12-06 18:18:26 +00001920 if (extsym->st_name != 0) {
Eric Andersen9f16d612000-06-12 23:11:16 +00001921 name = strtab + extsym->st_name;
Eric Andersen21adca72000-12-06 18:18:26 +00001922 } else {
Eric Andersen9f16d612000-06-12 23:11:16 +00001923 name = f->sections[extsym->st_shndx]->name;
Eric Andersen21adca72000-12-06 18:18:26 +00001924 }
1925 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001926#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001927 if (got_allocate) {
1928 got_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001929 rel, &intsym->gotent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001930 got_offset, CONFIG_GOT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001931
1932 got_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001933 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001934#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001935#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001936 if (plt_allocate) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001937#if defined(CONFIG_USE_PLT_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001938 plt_offset += arch_list_add(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001939 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001940 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001941#else
1942 plt_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001943 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001944 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001945#endif
1946 plt_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001947 }
1948#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001949 }
Miles Baderae28b042002-04-01 09:34:25 +00001950 }
Eric Andersen21adca72000-12-06 18:18:26 +00001951
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001952#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001953 if (got_needed) {
1954 ifile->got = arch_xsect_init(f, ".got", got_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001955 CONFIG_GOT_ENTRY_SIZE);
Eric Andersen9f16d612000-06-12 23:11:16 +00001956 }
Eric Andersen21adca72000-12-06 18:18:26 +00001957#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001958
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001959#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001960 if (plt_needed) {
1961 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001962 CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001963 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001964#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001965
1966#endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */
Eric Andersen9f16d612000-06-12 23:11:16 +00001967}
1968
Eric Andersen9f16d612000-06-12 23:11:16 +00001969/*======================================================================*/
1970
1971/* Standard ELF hash function. */
Rob Landley88621d72006-08-29 19:41:06 +00001972static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
Eric Andersen9f16d612000-06-12 23:11:16 +00001973{
1974 unsigned long h = 0;
1975 unsigned long g;
1976 unsigned char ch;
1977
1978 while (n > 0) {
1979 ch = *name++;
1980 h = (h << 4) + ch;
1981 if ((g = (h & 0xf0000000)) != 0) {
1982 h ^= g >> 24;
1983 h &= ~g;
1984 }
1985 n--;
1986 }
1987 return h;
1988}
1989
Eric Andersen044228d2001-07-17 01:12:36 +00001990static unsigned long obj_elf_hash(const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001991{
1992 return obj_elf_hash_n(name, strlen(name));
1993}
1994
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001995#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00001996/* String comparison for non-co-versioned kernel and module. */
1997
1998static int ncv_strcmp(const char *a, const char *b)
1999{
2000 size_t alen = strlen(a), blen = strlen(b);
2001
2002 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
2003 return strncmp(a, b, alen);
2004 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
2005 return strncmp(a, b, blen);
2006 else
2007 return strcmp(a, b);
2008}
2009
2010/* String hashing for non-co-versioned kernel and module. Here
2011 we are simply forced to drop the crc from the hash. */
2012
2013static unsigned long ncv_symbol_hash(const char *str)
2014{
2015 size_t len = strlen(str);
2016 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
2017 len -= 10;
2018 return obj_elf_hash_n(str, len);
2019}
2020
Eric Andersen044228d2001-07-17 01:12:36 +00002021static void
Eric Andersen9f16d612000-06-12 23:11:16 +00002022obj_set_symbol_compare(struct obj_file *f,
2023 int (*cmp) (const char *, const char *),
2024 unsigned long (*hash) (const char *))
2025{
2026 if (cmp)
2027 f->symbol_cmp = cmp;
2028 if (hash) {
2029 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
2030 int i;
2031
2032 f->symbol_hash = hash;
2033
2034 memcpy(tmptab, f->symtab, sizeof(tmptab));
2035 memset(f->symtab, 0, sizeof(f->symtab));
2036
2037 for (i = 0; i < HASH_BUCKETS; ++i)
2038 for (sym = tmptab[i]; sym; sym = next) {
2039 unsigned long h = hash(sym->name) % HASH_BUCKETS;
2040 next = sym->next;
2041 sym->next = f->symtab[h];
2042 f->symtab[h] = sym;
2043 }
2044 }
2045}
2046
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002047#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00002048
Eric Andersen044228d2001-07-17 01:12:36 +00002049static struct obj_symbol *
2050obj_add_symbol(struct obj_file *f, const char *name,
Eric Andersen9f16d612000-06-12 23:11:16 +00002051 unsigned long symidx, int info,
2052 int secidx, ElfW(Addr) value,
2053 unsigned long size)
2054{
2055 struct obj_symbol *sym;
2056 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002057 int n_type = ELF_ST_TYPE(info);
2058 int n_binding = ELF_ST_BIND(info);
Eric Andersen9f16d612000-06-12 23:11:16 +00002059
2060 for (sym = f->symtab[hash]; sym; sym = sym->next)
2061 if (f->symbol_cmp(sym->name, name) == 0) {
2062 int o_secidx = sym->secidx;
2063 int o_info = sym->info;
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002064 int o_type = ELF_ST_TYPE(o_info);
2065 int o_binding = ELF_ST_BIND(o_info);
Eric Andersen9f16d612000-06-12 23:11:16 +00002066
2067 /* A redefinition! Is it legal? */
2068
2069 if (secidx == SHN_UNDEF)
2070 return sym;
2071 else if (o_secidx == SHN_UNDEF)
2072 goto found;
2073 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2074 /* Cope with local and global symbols of the same name
2075 in the same object file, as might have been created
2076 by ld -r. The only reason locals are now seen at this
2077 level at all is so that we can do semi-sensible things
2078 with parameters. */
2079
2080 struct obj_symbol *nsym, **p;
2081
2082 nsym = arch_new_symbol();
2083 nsym->next = sym->next;
2084 nsym->ksymidx = -1;
2085
2086 /* Excise the old (local) symbol from the hash chain. */
2087 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2088 continue;
2089 *p = sym = nsym;
2090 goto found;
2091 } else if (n_binding == STB_LOCAL) {
2092 /* Another symbol of the same name has already been defined.
2093 Just add this to the local table. */
2094 sym = arch_new_symbol();
2095 sym->next = NULL;
2096 sym->ksymidx = -1;
2097 f->local_symtab[symidx] = sym;
2098 goto found;
2099 } else if (n_binding == STB_WEAK)
2100 return sym;
2101 else if (o_binding == STB_WEAK)
2102 goto found;
2103 /* Don't unify COMMON symbols with object types the programmer
2104 doesn't expect. */
2105 else if (secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00002106 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00002107 return sym;
2108 else if (o_secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00002109 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00002110 goto found;
2111 else {
2112 /* Don't report an error if the symbol is coming from
2113 the kernel or some external module. */
2114 if (secidx <= SHN_HIRESERVE)
Manuel Novoa III cad53642003-03-19 09:13:01 +00002115 bb_error_msg("%s multiply defined", name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002116 return sym;
2117 }
2118 }
2119
2120 /* Completely new symbol. */
2121 sym = arch_new_symbol();
2122 sym->next = f->symtab[hash];
2123 f->symtab[hash] = sym;
2124 sym->ksymidx = -1;
2125
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002126 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) {
Eric Andersen66ca9482001-06-28 21:36:06 +00002127 if (symidx >= f->local_symtab_size)
Manuel Novoa III cad53642003-03-19 09:13:01 +00002128 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
Eric Andersen66ca9482001-06-28 21:36:06 +00002129 name, (long) symidx, (long) f->local_symtab_size);
2130 else
2131 f->local_symtab[symidx] = sym;
2132 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002133
Eric Andersen3b1a7442003-12-24 20:30:45 +00002134found:
Eric Andersen9f16d612000-06-12 23:11:16 +00002135 sym->name = name;
2136 sym->value = value;
2137 sym->size = size;
2138 sym->secidx = secidx;
2139 sym->info = info;
2140
2141 return sym;
2142}
2143
Eric Andersen044228d2001-07-17 01:12:36 +00002144static struct obj_symbol *
2145obj_find_symbol(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00002146{
2147 struct obj_symbol *sym;
2148 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2149
2150 for (sym = f->symtab[hash]; sym; sym = sym->next)
2151 if (f->symbol_cmp(sym->name, name) == 0)
2152 return sym;
2153
2154 return NULL;
2155}
2156
Eric Andersen044228d2001-07-17 01:12:36 +00002157static ElfW(Addr)
Eric Andersen9f16d612000-06-12 23:11:16 +00002158 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2159{
2160 if (sym) {
2161 if (sym->secidx >= SHN_LORESERVE)
2162 return sym->value;
2163
2164 return sym->value + f->sections[sym->secidx]->header.sh_addr;
2165 } else {
2166 /* As a special case, a NULL sym has value zero. */
2167 return 0;
2168 }
2169}
2170
Eric Andersen044228d2001-07-17 01:12:36 +00002171static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00002172{
2173 int i, n = f->header.e_shnum;
2174
2175 for (i = 0; i < n; ++i)
2176 if (strcmp(f->sections[i]->name, name) == 0)
2177 return f->sections[i];
2178
2179 return NULL;
2180}
2181
2182static int obj_load_order_prio(struct obj_section *a)
2183{
2184 unsigned long af, ac;
2185
2186 af = a->header.sh_flags;
2187
2188 ac = 0;
2189 if (a->name[0] != '.' || strlen(a->name) != 10 ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002190 strcmp(a->name + 5, ".init"))
Eric Andersen9f16d612000-06-12 23:11:16 +00002191 ac |= 32;
2192 if (af & SHF_ALLOC)
2193 ac |= 16;
2194 if (!(af & SHF_WRITE))
2195 ac |= 8;
2196 if (af & SHF_EXECINSTR)
2197 ac |= 4;
2198 if (a->header.sh_type != SHT_NOBITS)
2199 ac |= 2;
2200
2201 return ac;
2202}
2203
Eric Andersen044228d2001-07-17 01:12:36 +00002204static void
Eric Andersen9f16d612000-06-12 23:11:16 +00002205obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2206{
2207 struct obj_section **p;
2208 int prio = obj_load_order_prio(sec);
2209 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2210 if (obj_load_order_prio(*p) < prio)
2211 break;
2212 sec->load_next = *p;
2213 *p = sec;
2214}
2215
Eric Andersen044228d2001-07-17 01:12:36 +00002216static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00002217 const char *name,
2218 unsigned long align,
2219 unsigned long size)
2220{
2221 int newidx = f->header.e_shnum++;
2222 struct obj_section *sec;
2223
2224 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2225 f->sections[newidx] = sec = arch_new_section();
2226
2227 memset(sec, 0, sizeof(*sec));
2228 sec->header.sh_type = SHT_PROGBITS;
2229 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2230 sec->header.sh_size = size;
2231 sec->header.sh_addralign = align;
2232 sec->name = name;
2233 sec->idx = newidx;
2234 if (size)
2235 sec->contents = xmalloc(size);
2236
2237 obj_insert_section_load_order(f, sec);
2238
2239 return sec;
2240}
2241
Eric Andersen044228d2001-07-17 01:12:36 +00002242static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00002243 const char *name,
2244 unsigned long align,
2245 unsigned long size)
2246{
2247 int newidx = f->header.e_shnum++;
2248 struct obj_section *sec;
2249
2250 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
2251 f->sections[newidx] = sec = arch_new_section();
2252
2253 memset(sec, 0, sizeof(*sec));
2254 sec->header.sh_type = SHT_PROGBITS;
2255 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2256 sec->header.sh_size = size;
2257 sec->header.sh_addralign = align;
2258 sec->name = name;
2259 sec->idx = newidx;
2260 if (size)
2261 sec->contents = xmalloc(size);
2262
2263 sec->load_next = f->load_order;
2264 f->load_order = sec;
2265 if (f->load_order_search_start == &f->load_order)
2266 f->load_order_search_start = &sec->load_next;
2267
2268 return sec;
2269}
2270
Eric Andersen044228d2001-07-17 01:12:36 +00002271static void *obj_extend_section(struct obj_section *sec, unsigned long more)
Eric Andersen9f16d612000-06-12 23:11:16 +00002272{
2273 unsigned long oldsize = sec->header.sh_size;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00002274 if (more) {
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002275 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
2276 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002277 return sec->contents + oldsize;
2278}
2279
2280
Eric Andersen9f16d612000-06-12 23:11:16 +00002281/* Conditionally add the symbols from the given symbol set to the
2282 new module. */
2283
2284static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00002285add_symbols_from( struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00002286 int idx, struct new_module_symbol *syms, size_t nsyms)
2287{
2288 struct new_module_symbol *s;
2289 size_t i;
2290 int used = 0;
Miles Baderae28b042002-04-01 09:34:25 +00002291#ifdef SYMBOL_PREFIX
2292 char *name_buf = 0;
2293 size_t name_alloced_size = 0;
2294#endif
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002295#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
2296 int gpl;
Eric Andersen9f16d612000-06-12 23:11:16 +00002297
Glenn L McGrath759515c2003-08-30 06:00:33 +00002298 gpl = obj_gpl_license(f, NULL) == 0;
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002299#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00002300 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
Miles Baderae28b042002-04-01 09:34:25 +00002301 /* Only add symbols that are already marked external.
2302 If we override locals we may cause problems for
2303 argument initialization. We will also create a false
2304 dependency on the module. */
Eric Andersen9f16d612000-06-12 23:11:16 +00002305 struct obj_symbol *sym;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00002306 char *name;
Eric Andersen9f16d612000-06-12 23:11:16 +00002307
Glenn L McGrath759515c2003-08-30 06:00:33 +00002308 /* GPL licensed modules can use symbols exported with
2309 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
2310 * exported names. Non-GPL modules never see any GPLONLY_
2311 * symbols so they cannot fudge it by adding the prefix on
2312 * their references.
2313 */
2314 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002315#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Glenn L McGrath759515c2003-08-30 06:00:33 +00002316 if (gpl)
Eric Andersenb225e2a2004-08-28 00:43:07 +00002317 s->name += 8;
Glenn L McGrath759515c2003-08-30 06:00:33 +00002318 else
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002319#endif
Glenn L McGrath759515c2003-08-30 06:00:33 +00002320 continue;
2321 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00002322 name = (char *)s->name;
Glenn L McGrath759515c2003-08-30 06:00:33 +00002323
Miles Baderae28b042002-04-01 09:34:25 +00002324#ifdef SYMBOL_PREFIX
2325 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2326 kernel exports `C names', but module object files
2327 reference `linker names'). */
2328 size_t extra = sizeof SYMBOL_PREFIX;
2329 size_t name_size = strlen (name) + extra;
2330 if (name_size > name_alloced_size) {
2331 name_alloced_size = name_size * 2;
2332 name_buf = alloca (name_alloced_size);
2333 }
2334 strcpy (name_buf, SYMBOL_PREFIX);
2335 strcpy (name_buf + extra - 1, name);
2336 name = name_buf;
2337#endif /* SYMBOL_PREFIX */
2338
2339 sym = obj_find_symbol(f, name);
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002340 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
Miles Baderae28b042002-04-01 09:34:25 +00002341#ifdef SYMBOL_PREFIX
2342 /* Put NAME_BUF into more permanent storage. */
2343 name = xmalloc (name_size);
2344 strcpy (name, name_buf);
2345#endif
2346 sym = obj_add_symbol(f, name, -1,
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002347 ELF_ST_INFO(STB_GLOBAL,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002348 STT_NOTYPE),
2349 idx, s->value, 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00002350 /* Did our symbol just get installed? If so, mark the
2351 module as "used". */
2352 if (sym->secidx == idx)
2353 used = 1;
2354 }
2355 }
2356
2357 return used;
2358}
2359
2360static void add_kernel_symbols(struct obj_file *f)
2361{
2362 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00002363 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002364
2365 /* Add module symbols first. */
2366
2367 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
2368 if (m->nsyms
Eric Andersen3b1a7442003-12-24 20:30:45 +00002369 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
2370 m->nsyms)) m->used = 1, ++nused;
Eric Andersen9f16d612000-06-12 23:11:16 +00002371
2372 n_ext_modules_used = nused;
2373
2374 /* And finally the symbols from the kernel proper. */
2375
2376 if (nksyms)
2377 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2378}
2379
2380static char *get_modinfo_value(struct obj_file *f, const char *key)
2381{
2382 struct obj_section *sec;
2383 char *p, *v, *n, *ep;
2384 size_t klen = strlen(key);
2385
2386 sec = obj_find_section(f, ".modinfo");
2387 if (sec == NULL)
2388 return NULL;
2389 p = sec->contents;
2390 ep = p + sec->header.sh_size;
2391 while (p < ep) {
2392 v = strchr(p, '=');
2393 n = strchr(p, '\0');
2394 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002395 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002396 return v + 1;
2397 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002398 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002399 return n;
2400 }
2401 p = n + 1;
2402 }
2403
2404 return NULL;
2405}
2406
2407
2408/*======================================================================*/
Eric Andersen9f16d612000-06-12 23:11:16 +00002409/* Functions relating to module loading after 2.1.18. */
2410
2411static int
2412new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2413{
2414 while (argc > 0) {
Miles Baderae28b042002-04-01 09:34:25 +00002415 char *p, *q, *key, *sym_name;
Eric Andersen9f16d612000-06-12 23:11:16 +00002416 struct obj_symbol *sym;
2417 char *contents, *loc;
2418 int min, max, n;
2419
2420 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00002421 if ((q = strchr(p, '=')) == NULL) {
2422 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00002423 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002424 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002425
2426 key = alloca(q - p + 6);
2427 memcpy(key, "parm_", 5);
2428 memcpy(key + 5, p, q - p);
2429 key[q - p + 5] = 0;
2430
2431 p = get_modinfo_value(f, key);
2432 key += 5;
2433 if (p == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002434 bb_error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002435 return 0;
2436 }
2437
Miles Baderae28b042002-04-01 09:34:25 +00002438#ifdef SYMBOL_PREFIX
2439 sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);
2440 strcpy (sym_name, SYMBOL_PREFIX);
2441 strcat (sym_name, key);
2442#else
2443 sym_name = key;
2444#endif
2445 sym = obj_find_symbol(f, sym_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002446
2447 /* Also check that the parameter was not resolved from the kernel. */
2448 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002449 bb_error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002450 return 0;
2451 }
2452
2453 if (isdigit(*p)) {
2454 min = strtoul(p, &p, 10);
2455 if (*p == '-')
2456 max = strtoul(p + 1, &p, 10);
2457 else
2458 max = min;
2459 } else
2460 min = max = 1;
2461
2462 contents = f->sections[sym->secidx]->contents;
2463 loc = contents + sym->value;
2464 n = (*++q != '\0');
2465
2466 while (1) {
2467 if ((*p == 's') || (*p == 'c')) {
2468 char *str;
2469
2470 /* Do C quoting if we begin with a ", else slurp the lot. */
2471 if (*q == '"') {
2472 char *r;
2473
2474 str = alloca(strlen(q));
2475 for (r = str, q++; *q != '"'; ++q, ++r) {
2476 if (*q == '\0') {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002477 bb_error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002478 key);
2479 return 0;
2480 } else if (*q == '\\')
2481 switch (*++q) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002482 case 'a':
2483 *r = '\a';
2484 break;
2485 case 'b':
2486 *r = '\b';
2487 break;
2488 case 'e':
2489 *r = '\033';
2490 break;
2491 case 'f':
2492 *r = '\f';
2493 break;
2494 case 'n':
2495 *r = '\n';
2496 break;
2497 case 'r':
2498 *r = '\r';
2499 break;
2500 case 't':
2501 *r = '\t';
2502 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002503
Eric Andersen3b1a7442003-12-24 20:30:45 +00002504 case '0':
2505 case '1':
2506 case '2':
2507 case '3':
2508 case '4':
2509 case '5':
2510 case '6':
2511 case '7':
2512 {
2513 int c = *q - '0';
2514 if (q[1] >= '0' && q[1] <= '7') {
Eric Andersen9f16d612000-06-12 23:11:16 +00002515 c = (c * 8) + *++q - '0';
Eric Andersen3b1a7442003-12-24 20:30:45 +00002516 if (q[1] >= '0' && q[1] <= '7')
2517 c = (c * 8) + *++q - '0';
2518 }
2519 *r = c;
Eric Andersen9f16d612000-06-12 23:11:16 +00002520 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002521 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002522
Eric Andersen3b1a7442003-12-24 20:30:45 +00002523 default:
2524 *r = *q;
2525 break;
2526 } else
Eric Andersen9f16d612000-06-12 23:11:16 +00002527 *r = *q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002528 }
2529 *r = '\0';
2530 ++q;
2531 } else {
2532 char *r;
2533
2534 /* In this case, the string is not quoted. We will break
2535 it using the coma (like for ints). If the user wants to
2536 include comas in a string, he just has to quote it */
2537
2538 /* Search the next coma */
2539 r = strchr(q, ',');
2540
2541 /* Found ? */
2542 if (r != (char *) NULL) {
2543 /* Recopy the current field */
2544 str = alloca(r - q + 1);
2545 memcpy(str, q, r - q);
2546
Eric Andersenaff114c2004-04-14 17:51:38 +00002547 /* I don't know if it is useful, as the previous case
2548 doesn't nul terminate the string ??? */
Eric Andersen9f16d612000-06-12 23:11:16 +00002549 str[r - q] = '\0';
2550
2551 /* Keep next fields */
2552 q = r;
2553 } else {
2554 /* last string */
2555 str = q;
2556 q = "";
2557 }
2558 }
2559
2560 if (*p == 's') {
2561 /* Normal string */
2562 obj_string_patch(f, sym->secidx, loc - contents, str);
2563 loc += tgt_sizeof_char_p;
2564 } else {
2565 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002566 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002567
2568 /* Get the size of each member */
2569 /* Probably we should do that outside the loop ? */
2570 if (!isdigit(*(p + 1))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002571 bb_error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002572 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002573 return 0;
2574 }
2575 charssize = strtoul(p + 1, (char **) NULL, 10);
2576
2577 /* Check length */
2578 if (strlen(str) >= charssize) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002579 bb_error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002580 charssize - 1);
2581 return 0;
2582 }
2583
2584 /* Copy to location */
2585 strcpy((char *) loc, str);
2586 loc += charssize;
2587 }
2588 } else {
2589 long v = strtoul(q, &q, 0);
2590 switch (*p) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002591 case 'b':
2592 *loc++ = v;
2593 break;
2594 case 'h':
2595 *(short *) loc = v;
2596 loc += tgt_sizeof_short;
2597 break;
2598 case 'i':
2599 *(int *) loc = v;
2600 loc += tgt_sizeof_int;
2601 break;
2602 case 'l':
2603 *(long *) loc = v;
2604 loc += tgt_sizeof_long;
2605 break;
2606
2607 default:
2608 bb_error_msg("unknown parameter type '%c' for %s", *p, key);
2609 return 0;
2610 }
2611 }
2612
2613retry_end_of_value:
2614 switch (*q) {
2615 case '\0':
2616 goto end_of_arg;
2617
2618 case ' ':
2619 case '\t':
2620 case '\n':
2621 case '\r':
2622 ++q;
2623 goto retry_end_of_value;
2624
2625 case ',':
2626 if (++n > max) {
2627 bb_error_msg("too many values for %s (max %d)", key, max);
2628 return 0;
2629 }
2630 ++q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002631 break;
2632
2633 default:
Eric Andersen3b1a7442003-12-24 20:30:45 +00002634 bb_error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002635 return 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002636 }
2637 }
2638
Eric Andersen3b1a7442003-12-24 20:30:45 +00002639end_of_arg:
Eric Andersen9f16d612000-06-12 23:11:16 +00002640 if (n < min) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002641 bb_error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002642 return 0;
2643 }
2644
2645 argc--, argv++;
2646 }
2647
2648 return 1;
2649}
2650
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002651#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00002652static int new_is_module_checksummed(struct obj_file *f)
2653{
2654 const char *p = get_modinfo_value(f, "using_checksums");
2655 if (p)
2656 return atoi(p);
2657 else
2658 return 0;
2659}
2660
2661/* Get the module's kernel version in the canonical integer form. */
2662
2663static int
2664new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2665{
2666 char *p, *q;
2667 int a, b, c;
2668
2669 p = get_modinfo_value(f, "kernel_version");
2670 if (p == NULL)
2671 return -1;
Eric Andersen2d342152002-06-18 05:16:25 +00002672 safe_strncpy(str, p, STRVERSIONLEN);
Eric Andersen9f16d612000-06-12 23:11:16 +00002673
2674 a = strtoul(p, &p, 10);
2675 if (*p != '.')
2676 return -1;
2677 b = strtoul(p + 1, &p, 10);
2678 if (*p != '.')
2679 return -1;
2680 c = strtoul(p + 1, &q, 10);
2681 if (p + 1 == q)
2682 return -1;
2683
2684 return a << 16 | b << 8 | c;
2685}
2686
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002687#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00002688
2689
Eric Andersen9f16d612000-06-12 23:11:16 +00002690/* Fetch the loaded modules, and all currently exported symbols. */
2691
2692static int new_get_kernel_symbols(void)
2693{
2694 char *module_names, *mn;
2695 struct external_module *modules, *m;
2696 struct new_module_symbol *syms, *s;
2697 size_t ret, bufsize, nmod, nsyms, i, j;
2698
2699 /* Collect the loaded modules. */
2700
2701 module_names = xmalloc(bufsize = 256);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002702retry_modules_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002703 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002704 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002705 module_names = xrealloc(module_names, bufsize = ret);
2706 goto retry_modules_load;
2707 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002708 bb_perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002709 return 0;
2710 }
2711
2712 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002713
2714 /* Collect the modules' symbols. */
2715
Mark Whitley94fd4802001-03-12 23:08:34 +00002716 if (nmod){
2717 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2718 memset(modules, 0, nmod * sizeof(*modules));
2719 for (i = 0, mn = module_names, m = modules;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002720 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
Mark Whitley94fd4802001-03-12 23:08:34 +00002721 struct new_module_info info;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002722
Mark Whitley94fd4802001-03-12 23:08:34 +00002723 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2724 if (errno == ENOENT) {
2725 /* The module was removed out from underneath us. */
2726 continue;
2727 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002728 bb_perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002729 return 0;
2730 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002731
Mark Whitley94fd4802001-03-12 23:08:34 +00002732 syms = xmalloc(bufsize = 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002733retry_mod_sym_load:
Mark Whitley94fd4802001-03-12 23:08:34 +00002734 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2735 switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002736 case ENOSPC:
2737 syms = xrealloc(syms, bufsize = ret);
2738 goto retry_mod_sym_load;
2739 case ENOENT:
2740 /* The module was removed out from underneath us. */
2741 continue;
2742 default:
2743 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn);
2744 return 0;
Mark Whitley94fd4802001-03-12 23:08:34 +00002745 }
2746 }
2747 nsyms = ret;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002748
Mark Whitley94fd4802001-03-12 23:08:34 +00002749 m->name = mn;
2750 m->addr = info.addr;
2751 m->nsyms = nsyms;
2752 m->syms = syms;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002753
Mark Whitley94fd4802001-03-12 23:08:34 +00002754 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2755 s->name += (unsigned long) syms;
2756 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002757 }
2758 }
2759
2760 /* Collect the kernel's symbols. */
2761
2762 syms = xmalloc(bufsize = 16 * 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002763retry_kern_sym_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002764 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002765 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002766 syms = xrealloc(syms, bufsize = ret);
2767 goto retry_kern_sym_load;
2768 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002769 bb_perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002770 return 0;
2771 }
2772 nksyms = nsyms = ret;
2773 ksyms = syms;
2774
2775 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2776 s->name += (unsigned long) syms;
2777 }
2778 return 1;
2779}
2780
2781
2782/* Return the kernel symbol checksum version, or zero if not used. */
2783
2784static int new_is_kernel_checksummed(void)
2785{
2786 struct new_module_symbol *s;
2787 size_t i;
2788
2789 /* Using_Versions is not the first symbol, but it should be in there. */
2790
2791 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2792 if (strcmp((char *) s->name, "Using_Versions") == 0)
2793 return s->value;
2794
2795 return 0;
2796}
2797
2798
2799static int new_create_this_module(struct obj_file *f, const char *m_name)
2800{
2801 struct obj_section *sec;
2802
2803 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002804 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002805 memset(sec->contents, 0, sizeof(struct new_module));
2806
Miles Baderae28b042002-04-01 09:34:25 +00002807 obj_add_symbol(f, SPFX "__this_module", -1,
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002808 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002809 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002810
2811 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
Eric Andersen3b1a7442003-12-24 20:30:45 +00002812 m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002813
2814 return 1;
2815}
2816
Eric Andersen889dd202003-01-23 04:48:34 +00002817#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2818/* add an entry to the __ksymtab section, creating it if necessary */
2819static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2820{
2821 struct obj_section *sec;
2822 ElfW(Addr) ofs;
2823
2824 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2825 * If __ksymtab is defined but not marked alloc, x out the first character
2826 * (no obj_delete routine) and create a new __ksymtab with the correct
2827 * characteristics.
2828 */
2829 sec = obj_find_section(f, "__ksymtab");
2830 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2831 *((char *)(sec->name)) = 'x'; /* override const */
2832 sec = NULL;
2833 }
2834 if (!sec)
2835 sec = obj_create_alloced_section(f, "__ksymtab",
Eric Andersen3b1a7442003-12-24 20:30:45 +00002836 tgt_sizeof_void_p, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00002837 if (!sec)
2838 return;
2839 sec->header.sh_flags |= SHF_ALLOC;
2840 sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might
Eric Andersen3b1a7442003-12-24 20:30:45 +00002841 be byte-aligned */
Eric Andersen889dd202003-01-23 04:48:34 +00002842 ofs = sec->header.sh_size;
2843 obj_symbol_patch(f, sec->idx, ofs, sym);
2844 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2845 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2846}
2847#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
Eric Andersen9f16d612000-06-12 23:11:16 +00002848
2849static int new_create_module_ksymtab(struct obj_file *f)
2850{
2851 struct obj_section *sec;
2852 int i;
2853
2854 /* We must always add the module references. */
2855
2856 if (n_ext_modules_used) {
2857 struct new_module_ref *dep;
2858 struct obj_symbol *tm;
2859
2860 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002861 (sizeof(struct new_module_ref)
2862 * n_ext_modules_used));
Eric Andersen9f16d612000-06-12 23:11:16 +00002863 if (!sec)
2864 return 0;
2865
Miles Baderae28b042002-04-01 09:34:25 +00002866 tm = obj_find_symbol(f, SPFX "__this_module");
Eric Andersen9f16d612000-06-12 23:11:16 +00002867 dep = (struct new_module_ref *) sec->contents;
2868 for (i = 0; i < n_ext_modules; ++i)
2869 if (ext_modules[i].used) {
2870 dep->dep = ext_modules[i].addr;
2871 obj_symbol_patch(f, sec->idx,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002872 (char *) &dep->ref - sec->contents, tm);
Eric Andersen9f16d612000-06-12 23:11:16 +00002873 dep->next_ref = 0;
2874 ++dep;
2875 }
2876 }
2877
Denis Vlasenkofe76cd52006-09-23 12:32:58 +00002878 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002879 size_t nsyms;
2880 int *loaded;
2881
2882 sec =
2883 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002884 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00002885
2886 /* We don't want to export symbols residing in sections that
2887 aren't loaded. There are a number of these created so that
2888 we make sure certain module options don't appear twice. */
2889
2890 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2891 while (--i >= 0)
2892 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2893
2894 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2895 struct obj_symbol *sym;
2896 for (sym = f->symtab[i]; sym; sym = sym->next)
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00002897 if (ELF_ST_BIND(sym->info) != STB_LOCAL
Eric Andersen3b1a7442003-12-24 20:30:45 +00002898 && sym->secidx <= SHN_HIRESERVE
2899 && (sym->secidx >= SHN_LORESERVE
2900 || loaded[sym->secidx])) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002901 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2902
2903 obj_symbol_patch(f, sec->idx, ofs, sym);
2904 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002905 sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002906
2907 nsyms++;
2908 }
2909 }
2910
2911 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2912 }
2913
2914 return 1;
2915}
2916
2917
2918static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00002919new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
Eric Andersen9f16d612000-06-12 23:11:16 +00002920{
2921 struct new_module *module;
2922 struct obj_section *sec;
2923 void *image;
2924 int ret;
2925 tgt_long m_addr;
2926
2927 sec = obj_find_section(f, ".this");
Eric Andersenc7bda1c2004-03-15 08:29:22 +00002928 if (!sec || !sec->contents) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002929 bb_perror_msg_and_die("corrupt module %s?",m_name);
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002930 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002931 module = (struct new_module *) sec->contents;
2932 m_addr = sec->header.sh_addr;
2933
2934 module->size_of_struct = sizeof(*module);
2935 module->size = m_size;
2936 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2937
2938 sec = obj_find_section(f, "__ksymtab");
2939 if (sec && sec->header.sh_size) {
2940 module->syms = sec->header.sh_addr;
2941 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2942 }
2943
2944 if (n_ext_modules_used) {
2945 sec = obj_find_section(f, ".kmodtab");
2946 module->deps = sec->header.sh_addr;
2947 module->ndeps = n_ext_modules_used;
2948 }
2949
2950 module->init =
Miles Baderae28b042002-04-01 09:34:25 +00002951 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002952 module->cleanup =
Miles Baderae28b042002-04-01 09:34:25 +00002953 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002954
2955 sec = obj_find_section(f, "__ex_table");
2956 if (sec) {
2957 module->ex_table_start = sec->header.sh_addr;
2958 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2959 }
2960
2961 sec = obj_find_section(f, ".text.init");
2962 if (sec) {
2963 module->runsize = sec->header.sh_addr - m_addr;
2964 }
2965 sec = obj_find_section(f, ".data.init");
2966 if (sec) {
2967 if (!module->runsize ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002968 module->runsize > sec->header.sh_addr - m_addr)
2969 module->runsize = sec->header.sh_addr - m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00002970 }
Eric Andersen8ae319a2001-05-21 16:09:18 +00002971 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2972 if (sec && sec->header.sh_size) {
2973 module->archdata_start = (void*)sec->header.sh_addr;
2974 module->archdata_end = module->archdata_start + sec->header.sh_size;
2975 }
2976 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2977 if (sec && sec->header.sh_size) {
2978 module->kallsyms_start = (void*)sec->header.sh_addr;
2979 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2980 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002981
Eric Andersen9f16d612000-06-12 23:11:16 +00002982 /* Whew! All of the initialization is complete. Collect the final
2983 module image and give it to the kernel. */
2984
2985 image = xmalloc(m_size);
2986 obj_create_image(f, image);
2987
Eric Andersencb3b9b12004-06-22 11:50:52 +00002988 ret = init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002989 if (ret)
Manuel Novoa III cad53642003-03-19 09:13:01 +00002990 bb_perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002991
2992 free(image);
2993
2994 return ret == 0;
2995}
2996
Eric Andersen9f16d612000-06-12 23:11:16 +00002997
2998/*======================================================================*/
2999
Eric Andersen044228d2001-07-17 01:12:36 +00003000static int
Eric Andersen9f16d612000-06-12 23:11:16 +00003001obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3002 const char *string)
3003{
3004 struct obj_string_patch *p;
3005 struct obj_section *strsec;
3006 size_t len = strlen(string) + 1;
3007 char *loc;
3008
3009 p = xmalloc(sizeof(*p));
3010 p->next = f->string_patches;
3011 p->reloc_secidx = secidx;
3012 p->reloc_offset = offset;
3013 f->string_patches = p;
3014
3015 strsec = obj_find_section(f, ".kstrtab");
3016 if (strsec == NULL) {
3017 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
3018 p->string_offset = 0;
3019 loc = strsec->contents;
3020 } else {
3021 p->string_offset = strsec->header.sh_size;
3022 loc = obj_extend_section(strsec, len);
3023 }
3024 memcpy(loc, string, len);
3025
3026 return 1;
3027}
3028
Eric Andersen044228d2001-07-17 01:12:36 +00003029static int
Eric Andersen9f16d612000-06-12 23:11:16 +00003030obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
3031 struct obj_symbol *sym)
3032{
3033 struct obj_symbol_patch *p;
3034
3035 p = xmalloc(sizeof(*p));
3036 p->next = f->symbol_patches;
3037 p->reloc_secidx = secidx;
3038 p->reloc_offset = offset;
3039 p->sym = sym;
3040 f->symbol_patches = p;
3041
3042 return 1;
3043}
3044
Eric Andersen044228d2001-07-17 01:12:36 +00003045static int obj_check_undefineds(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00003046{
3047 unsigned long i;
3048 int ret = 1;
3049
3050 for (i = 0; i < HASH_BUCKETS; ++i) {
3051 struct obj_symbol *sym;
3052 for (sym = f->symtab[i]; sym; sym = sym->next)
3053 if (sym->secidx == SHN_UNDEF) {
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003054 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003055 sym->secidx = SHN_ABS;
3056 sym->value = 0;
3057 } else {
Eric Andersenb493dec2002-07-02 19:14:23 +00003058 if (!flag_quiet) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003059 bb_error_msg("unresolved symbol %s", sym->name);
Eric Andersenb493dec2002-07-02 19:14:23 +00003060 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003061 ret = 0;
3062 }
3063 }
3064 }
3065
3066 return ret;
3067}
3068
Eric Andersen044228d2001-07-17 01:12:36 +00003069static void obj_allocate_commons(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00003070{
3071 struct common_entry {
3072 struct common_entry *next;
3073 struct obj_symbol *sym;
3074 } *common_head = NULL;
3075
3076 unsigned long i;
3077
3078 for (i = 0; i < HASH_BUCKETS; ++i) {
3079 struct obj_symbol *sym;
3080 for (sym = f->symtab[i]; sym; sym = sym->next)
3081 if (sym->secidx == SHN_COMMON) {
3082 /* Collect all COMMON symbols and sort them by size so as to
3083 minimize space wasted by alignment requirements. */
3084 {
3085 struct common_entry **p, *n;
3086 for (p = &common_head; *p; p = &(*p)->next)
3087 if (sym->size <= (*p)->sym->size)
3088 break;
3089
3090 n = alloca(sizeof(*n));
3091 n->next = *p;
3092 n->sym = sym;
3093 *p = n;
3094 }
3095 }
3096 }
3097
3098 for (i = 1; i < f->local_symtab_size; ++i) {
3099 struct obj_symbol *sym = f->local_symtab[i];
3100 if (sym && sym->secidx == SHN_COMMON) {
3101 struct common_entry **p, *n;
3102 for (p = &common_head; *p; p = &(*p)->next)
3103 if (sym == (*p)->sym)
3104 break;
3105 else if (sym->size < (*p)->sym->size) {
3106 n = alloca(sizeof(*n));
3107 n->next = *p;
3108 n->sym = sym;
3109 *p = n;
3110 break;
3111 }
3112 }
3113 }
3114
3115 if (common_head) {
3116 /* Find the bss section. */
3117 for (i = 0; i < f->header.e_shnum; ++i)
3118 if (f->sections[i]->header.sh_type == SHT_NOBITS)
3119 break;
3120
3121 /* If for some reason there hadn't been one, create one. */
3122 if (i == f->header.e_shnum) {
3123 struct obj_section *sec;
3124
3125 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
3126 f->sections[i] = sec = arch_new_section();
3127 f->header.e_shnum = i + 1;
3128
3129 memset(sec, 0, sizeof(*sec));
3130 sec->header.sh_type = SHT_PROGBITS;
3131 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
3132 sec->name = ".bss";
3133 sec->idx = i;
3134 }
3135
3136 /* Allocate the COMMONS. */
3137 {
3138 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
3139 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
3140 struct common_entry *c;
3141
3142 for (c = common_head; c; c = c->next) {
3143 ElfW(Addr) align = c->sym->value;
3144
3145 if (align > max_align)
3146 max_align = align;
3147 if (bss_size & (align - 1))
3148 bss_size = (bss_size | (align - 1)) + 1;
3149
3150 c->sym->secidx = i;
3151 c->sym->value = bss_size;
3152
3153 bss_size += c->sym->size;
3154 }
3155
3156 f->sections[i]->header.sh_size = bss_size;
3157 f->sections[i]->header.sh_addralign = max_align;
3158 }
3159 }
3160
3161 /* For the sake of patch relocation and parameter initialization,
3162 allocate zeroed data for NOBITS sections now. Note that after
3163 this we cannot assume NOBITS are really empty. */
3164 for (i = 0; i < f->header.e_shnum; ++i) {
3165 struct obj_section *s = f->sections[i];
3166 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00003167 if (s->header.sh_size != 0)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003168 s->contents = memset(xmalloc(s->header.sh_size),
3169 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00003170 else
3171 s->contents = NULL;
3172
Eric Andersen9f16d612000-06-12 23:11:16 +00003173 s->header.sh_type = SHT_PROGBITS;
3174 }
3175 }
3176}
3177
Eric Andersen044228d2001-07-17 01:12:36 +00003178static unsigned long obj_load_size(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00003179{
3180 unsigned long dot = 0;
3181 struct obj_section *sec;
3182
3183 /* Finalize the positions of the sections relative to one another. */
3184
3185 for (sec = f->load_order; sec; sec = sec->load_next) {
3186 ElfW(Addr) align;
3187
3188 align = sec->header.sh_addralign;
3189 if (align && (dot & (align - 1)))
3190 dot = (dot | (align - 1)) + 1;
3191
3192 sec->header.sh_addr = dot;
3193 dot += sec->header.sh_size;
3194 }
3195
3196 return dot;
3197}
3198
Eric Andersen044228d2001-07-17 01:12:36 +00003199static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
Eric Andersen9f16d612000-06-12 23:11:16 +00003200{
3201 int i, n = f->header.e_shnum;
3202 int ret = 1;
3203
3204 /* Finalize the addresses of the sections. */
3205
3206 f->baseaddr = base;
3207 for (i = 0; i < n; ++i)
3208 f->sections[i]->header.sh_addr += base;
3209
3210 /* And iterate over all of the relocations. */
3211
3212 for (i = 0; i < n; ++i) {
3213 struct obj_section *relsec, *symsec, *targsec, *strsec;
3214 ElfW(RelM) * rel, *relend;
3215 ElfW(Sym) * symtab;
3216 const char *strtab;
3217
3218 relsec = f->sections[i];
3219 if (relsec->header.sh_type != SHT_RELM)
3220 continue;
3221
3222 symsec = f->sections[relsec->header.sh_link];
3223 targsec = f->sections[relsec->header.sh_info];
3224 strsec = f->sections[symsec->header.sh_link];
3225
3226 rel = (ElfW(RelM) *) relsec->contents;
3227 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3228 symtab = (ElfW(Sym) *) symsec->contents;
3229 strtab = (const char *) strsec->contents;
3230
3231 for (; rel < relend; ++rel) {
3232 ElfW(Addr) value = 0;
3233 struct obj_symbol *intsym = NULL;
3234 unsigned long symndx;
3235 ElfW(Sym) * extsym = 0;
3236 const char *errmsg;
3237
3238 /* Attempt to find a value to use for this relocation. */
3239
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003240 symndx = ELF_R_SYM(rel->r_info);
Eric Andersen9f16d612000-06-12 23:11:16 +00003241 if (symndx) {
3242 /* Note we've already checked for undefined symbols. */
3243
3244 extsym = &symtab[symndx];
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003245 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003246 /* Local symbols we look up in the local table to be sure
3247 we get the one that is really intended. */
3248 intsym = f->local_symtab[symndx];
3249 } else {
3250 /* Others we look up in the hash table. */
3251 const char *name;
3252 if (extsym->st_name)
3253 name = strtab + extsym->st_name;
3254 else
3255 name = f->sections[extsym->st_shndx]->name;
3256 intsym = obj_find_symbol(f, name);
3257 }
3258
3259 value = obj_symbol_final_value(f, intsym);
3260 intsym->referenced = 1;
3261 }
3262#if SHT_RELM == SHT_RELA
3263#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3264 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
3265 if (!extsym || !extsym->st_name ||
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003266 ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
Eric Andersen9f16d612000-06-12 23:11:16 +00003267#endif
3268 value += rel->r_addend;
3269#endif
3270
3271 /* Do it! */
3272 switch (arch_apply_relocation
3273 (f, targsec, symsec, intsym, rel, value)) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003274 case obj_reloc_ok:
3275 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003276
Eric Andersen3b1a7442003-12-24 20:30:45 +00003277 case obj_reloc_overflow:
3278 errmsg = "Relocation overflow";
3279 goto bad_reloc;
3280 case obj_reloc_dangerous:
3281 errmsg = "Dangerous relocation";
3282 goto bad_reloc;
3283 case obj_reloc_unhandled:
3284 errmsg = "Unhandled relocation";
3285bad_reloc:
3286 if (extsym) {
3287 bb_error_msg("%s of type %ld for %s", errmsg,
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003288 (long) ELF_R_TYPE(rel->r_info),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003289 strtab + extsym->st_name);
3290 } else {
3291 bb_error_msg("%s of type %ld", errmsg,
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003292 (long) ELF_R_TYPE(rel->r_info));
Eric Andersen3b1a7442003-12-24 20:30:45 +00003293 }
3294 ret = 0;
3295 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003296 }
3297 }
3298 }
3299
3300 /* Finally, take care of the patches. */
3301
3302 if (f->string_patches) {
3303 struct obj_string_patch *p;
3304 struct obj_section *strsec;
3305 ElfW(Addr) strsec_base;
3306 strsec = obj_find_section(f, ".kstrtab");
3307 strsec_base = strsec->header.sh_addr;
3308
3309 for (p = f->string_patches; p; p = p->next) {
3310 struct obj_section *targsec = f->sections[p->reloc_secidx];
3311 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3312 = strsec_base + p->string_offset;
3313 }
3314 }
3315
3316 if (f->symbol_patches) {
3317 struct obj_symbol_patch *p;
3318
3319 for (p = f->symbol_patches; p; p = p->next) {
3320 struct obj_section *targsec = f->sections[p->reloc_secidx];
3321 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3322 = obj_symbol_final_value(f, p->sym);
3323 }
3324 }
3325
3326 return ret;
3327}
3328
Eric Andersen044228d2001-07-17 01:12:36 +00003329static int obj_create_image(struct obj_file *f, char *image)
Eric Andersen9f16d612000-06-12 23:11:16 +00003330{
3331 struct obj_section *sec;
3332 ElfW(Addr) base = f->baseaddr;
3333
3334 for (sec = f->load_order; sec; sec = sec->load_next) {
3335 char *secimg;
3336
Eric Andersen2bf658d2001-02-24 20:01:53 +00003337 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00003338 continue;
3339
3340 secimg = image + (sec->header.sh_addr - base);
3341
3342 /* Note that we allocated data for NOBITS sections earlier. */
3343 memcpy(secimg, sec->contents, sec->header.sh_size);
3344 }
3345
3346 return 1;
3347}
3348
3349/*======================================================================*/
3350
Eric Andersen044228d2001-07-17 01:12:36 +00003351static struct obj_file *obj_load(FILE * fp, int loadprogbits)
Eric Andersen9f16d612000-06-12 23:11:16 +00003352{
3353 struct obj_file *f;
3354 ElfW(Shdr) * section_headers;
3355 int shnum, i;
3356 char *shstrtab;
3357
3358 /* Read the file header. */
3359
3360 f = arch_new_file();
3361 memset(f, 0, sizeof(*f));
3362 f->symbol_cmp = strcmp;
3363 f->symbol_hash = obj_elf_hash;
3364 f->load_order_search_start = &f->load_order;
3365
3366 fseek(fp, 0, SEEK_SET);
3367 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003368 bb_perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00003369 return NULL;
3370 }
3371
3372 if (f->header.e_ident[EI_MAG0] != ELFMAG0
Eric Andersen3b1a7442003-12-24 20:30:45 +00003373 || f->header.e_ident[EI_MAG1] != ELFMAG1
3374 || f->header.e_ident[EI_MAG2] != ELFMAG2
3375 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003376 bb_error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00003377 return NULL;
3378 }
3379 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Rob Landley0bafd472006-03-25 02:49:28 +00003380 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN
Bernhard Reutner-Fischerdeda6a52006-06-03 19:35:15 +00003381 ? ELFDATA2MSB : ELFDATA2LSB)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003382 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3383 || !MATCH_MACHINE(f->header.e_machine)) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003384 bb_error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00003385 return NULL;
3386 }
3387 if (f->header.e_type != ET_REL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003388 bb_error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00003389 return NULL;
3390 }
3391
3392 /* Read the section headers. */
3393
3394 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003395 bb_error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003396 (unsigned long) f->header.e_shentsize,
3397 (unsigned long) sizeof(ElfW(Shdr)));
3398 return NULL;
3399 }
3400
3401 shnum = f->header.e_shnum;
3402 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3403 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3404
3405 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3406 fseek(fp, f->header.e_shoff, SEEK_SET);
3407 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003408 bb_perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00003409 return NULL;
3410 }
3411
3412 /* Read the section data. */
3413
3414 for (i = 0; i < shnum; ++i) {
3415 struct obj_section *sec;
3416
3417 f->sections[i] = sec = arch_new_section();
3418 memset(sec, 0, sizeof(*sec));
3419
3420 sec->header = section_headers[i];
3421 sec->idx = i;
3422
Eric Andersen2bf658d2001-02-24 20:01:53 +00003423 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003424 case SHT_NULL:
3425 case SHT_NOTE:
3426 case SHT_NOBITS:
3427 /* ignore */
Eric Andersen8ae319a2001-05-21 16:09:18 +00003428 break;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003429
3430 case SHT_PROGBITS:
3431#if LOADBITS
3432 if (!loadprogbits) {
3433 sec->contents = NULL;
3434 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003435 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003436#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003437 case SHT_SYMTAB:
3438 case SHT_STRTAB:
3439 case SHT_RELM:
3440 if (sec->header.sh_size > 0) {
3441 sec->contents = xmalloc(sec->header.sh_size);
3442 fseek(fp, sec->header.sh_offset, SEEK_SET);
3443 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3444 bb_perror_msg("error reading ELF section data");
3445 return NULL;
3446 }
3447 } else {
3448 sec->contents = NULL;
3449 }
3450 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003451
3452#if SHT_RELM == SHT_REL
Eric Andersen3b1a7442003-12-24 20:30:45 +00003453 case SHT_RELA:
3454 bb_error_msg("RELA relocations not supported on this architecture");
3455 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003456#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00003457 case SHT_REL:
3458 bb_error_msg("REL relocations not supported on this architecture");
3459 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003460#endif
3461
Eric Andersen3b1a7442003-12-24 20:30:45 +00003462 default:
3463 if (sec->header.sh_type >= SHT_LOPROC) {
3464 /* Assume processor specific section types are debug
3465 info and can safely be ignored. If this is ever not
3466 the case (Hello MIPS?), don't put ifdefs here but
3467 create an arch_load_proc_section(). */
3468 break;
3469 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003470
Eric Andersen3b1a7442003-12-24 20:30:45 +00003471 bb_error_msg("can't handle sections of type %ld",
3472 (long) sec->header.sh_type);
3473 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003474 }
3475 }
3476
3477 /* Do what sort of interpretation as needed by each section. */
3478
3479 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3480
3481 for (i = 0; i < shnum; ++i) {
3482 struct obj_section *sec = f->sections[i];
3483 sec->name = shstrtab + sec->header.sh_name;
3484 }
3485
3486 for (i = 0; i < shnum; ++i) {
3487 struct obj_section *sec = f->sections[i];
3488
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003489 /* .modinfo should be contents only but gcc has no attribute for that.
3490 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3491 */
3492 if (strcmp(sec->name, ".modinfo") == 0)
3493 sec->header.sh_flags &= ~SHF_ALLOC;
3494
Eric Andersen9f16d612000-06-12 23:11:16 +00003495 if (sec->header.sh_flags & SHF_ALLOC)
3496 obj_insert_section_load_order(f, sec);
3497
3498 switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003499 case SHT_SYMTAB:
3500 {
3501 unsigned long nsym, j;
3502 char *strtab;
3503 ElfW(Sym) * sym;
Eric Andersen9f16d612000-06-12 23:11:16 +00003504
Eric Andersen3b1a7442003-12-24 20:30:45 +00003505 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3506 bb_error_msg("symbol size mismatch: %lu != %lu",
3507 (unsigned long) sec->header.sh_entsize,
3508 (unsigned long) sizeof(ElfW(Sym)));
3509 return NULL;
3510 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003511
Eric Andersen3b1a7442003-12-24 20:30:45 +00003512 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3513 strtab = f->sections[sec->header.sh_link]->contents;
3514 sym = (ElfW(Sym) *) sec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00003515
Eric Andersen3b1a7442003-12-24 20:30:45 +00003516 /* Allocate space for a table of local symbols. */
3517 j = f->local_symtab_size = sec->header.sh_info;
Rob Landley081e3842006-08-03 20:07:35 +00003518 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003519
Eric Andersen3b1a7442003-12-24 20:30:45 +00003520 /* Insert all symbols into the hash table. */
3521 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3522 ElfW(Addr) val = sym->st_value;
3523 const char *name;
3524 if (sym->st_name)
3525 name = strtab + sym->st_name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003526 else if (sym->st_shndx < shnum)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003527 name = f->sections[sym->st_shndx]->name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003528 else
3529 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00003530
Eric Andersenbf833552003-08-13 19:56:33 +00003531#if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003532 /*
3533 * For sh64 it is possible that the target of a branch
3534 * requires a mode switch (32 to 16 and back again).
3535 *
3536 * This is implied by the lsb being set in the target
3537 * address for SHmedia mode and clear for SHcompact.
3538 */
3539 val |= sym->st_other & 4;
Eric Andersenbf833552003-08-13 19:56:33 +00003540#endif
3541
Eric Andersen3b1a7442003-12-24 20:30:45 +00003542 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3543 val, sym->st_size);
3544 }
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003545 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00003546 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003547
Eric Andersen3b1a7442003-12-24 20:30:45 +00003548 case SHT_RELM:
3549 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3550 bb_error_msg("relocation entry size mismatch: %lu != %lu",
3551 (unsigned long) sec->header.sh_entsize,
3552 (unsigned long) sizeof(ElfW(RelM)));
3553 return NULL;
3554 }
3555 break;
3556 /* XXX Relocation code from modutils-2.3.19 is not here.
3557 * Why? That's about 20 lines of code from obj/obj_load.c,
3558 * which gets done in a second pass through the sections.
3559 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003560 }
3561 }
3562
3563 return f;
3564}
3565
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003566#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersen8ae319a2001-05-21 16:09:18 +00003567/*
3568 * load the unloaded sections directly into the memory allocated by
3569 * kernel for the module
3570 */
3571
Eric Andersenac5dbd12001-08-22 05:26:08 +00003572static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase)
Eric Andersen8ae319a2001-05-21 16:09:18 +00003573{
Eric Andersen8ae319a2001-05-21 16:09:18 +00003574 ElfW(Addr) base = f->baseaddr;
3575 struct obj_section* sec;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003576
Eric Andersen8ae319a2001-05-21 16:09:18 +00003577 for (sec = f->load_order; sec; sec = sec->load_next) {
3578
3579 /* section already loaded? */
3580 if (sec->contents != NULL)
3581 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003582
Eric Andersen8ae319a2001-05-21 16:09:18 +00003583 if (sec->header.sh_size == 0)
3584 continue;
3585
3586 sec->contents = imagebase + (sec->header.sh_addr - base);
3587 fseek(fp, sec->header.sh_offset, SEEK_SET);
3588 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Denis Vlasenko6d655be2006-09-06 19:02:46 +00003589 bb_perror_msg("error reading ELF section data");
Eric Andersen8ae319a2001-05-21 16:09:18 +00003590 return 0;
3591 }
3592
3593 }
3594 return 1;
3595}
3596#endif
3597
Eric Andersen9f16d612000-06-12 23:11:16 +00003598static void hide_special_symbols(struct obj_file *f)
3599{
3600 static const char *const specials[] = {
Miles Baderae28b042002-04-01 09:34:25 +00003601 SPFX "cleanup_module",
3602 SPFX "init_module",
3603 SPFX "kernel_version",
Eric Andersen9f16d612000-06-12 23:11:16 +00003604 NULL
3605 };
3606
3607 struct obj_symbol *sym;
3608 const char *const *p;
3609
3610 for (p = specials; *p; ++p)
3611 if ((sym = obj_find_symbol(f, *p)) != NULL)
3612 sym->info =
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003613 ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
Eric Andersen9f16d612000-06-12 23:11:16 +00003614}
3615
Glenn L McGrath759515c2003-08-30 06:00:33 +00003616
Eric Andersen71ae64b2002-10-10 04:20:21 +00003617#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Eric Andersen166fa462002-09-16 05:30:24 +00003618static int obj_gpl_license(struct obj_file *f, const char **license)
3619{
3620 struct obj_section *sec;
3621 /* This list must match *exactly* the list of allowable licenses in
3622 * linux/include/linux/module.h. Checking for leading "GPL" will not
3623 * work, somebody will use "GPL sucks, this is proprietary".
3624 */
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +00003625 static const char * const gpl_licenses[] = {
Eric Andersen166fa462002-09-16 05:30:24 +00003626 "GPL",
3627 "GPL v2",
3628 "GPL and additional rights",
3629 "Dual BSD/GPL",
3630 "Dual MPL/GPL",
3631 };
Eric Andersen9f16d612000-06-12 23:11:16 +00003632
Eric Andersen166fa462002-09-16 05:30:24 +00003633 if ((sec = obj_find_section(f, ".modinfo"))) {
3634 const char *value, *ptr, *endptr;
3635 ptr = sec->contents;
3636 endptr = ptr + sec->header.sh_size;
3637 while (ptr < endptr) {
3638 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) {
3639 int i;
3640 if (license)
3641 *license = value+1;
3642 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3643 if (strcmp(value+1, gpl_licenses[i]) == 0)
3644 return(0);
3645 }
3646 return(2);
3647 }
3648 if (strchr(ptr, '\0'))
3649 ptr = strchr(ptr, '\0') + 1;
3650 else
3651 ptr = endptr;
3652 }
3653 }
3654 return(1);
3655}
3656
3657#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3658#define TAINT_PROPRIETORY_MODULE (1<<0)
3659#define TAINT_FORCED_MODULE (1<<1)
3660#define TAINT_UNSAFE_SMP (1<<2)
Mike Frysingerfa17c4b2005-10-02 07:14:06 +00003661#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
Eric Andersen166fa462002-09-16 05:30:24 +00003662
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003663static void set_tainted(struct obj_file *f, int fd, char *m_name,
Eric Andersen166fa462002-09-16 05:30:24 +00003664 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3665{
3666 char buf[80];
3667 int oldval;
3668 static int first = 1;
3669 if (fd < 0 && !kernel_has_tainted)
3670 return; /* New modutils on old kernel */
3671 printf("Warning: loading %s will taint the kernel: %s%s\n",
3672 m_name, text1, text2);
3673 if (first) {
3674 printf(" See %s for information about tainted modules\n", TAINT_URL);
3675 first = 0;
3676 }
3677 if (fd >= 0) {
3678 read(fd, buf, sizeof(buf)-1);
3679 buf[sizeof(buf)-1] = '\0';
3680 oldval = strtoul(buf, NULL, 10);
3681 sprintf(buf, "%d\n", oldval | taint);
3682 write(fd, buf, strlen(buf));
3683 }
3684}
3685
3686/* Check if loading this module will taint the kernel. */
3687static void check_tainted_module(struct obj_file *f, char *m_name)
3688{
3689 static const char tainted_file[] = TAINT_FILENAME;
3690 int fd, kernel_has_tainted;
3691 const char *ptr;
3692
3693 kernel_has_tainted = 1;
3694 if ((fd = open(tainted_file, O_RDWR)) < 0) {
3695 if (errno == ENOENT)
3696 kernel_has_tainted = 0;
3697 else if (errno == EACCES)
3698 kernel_has_tainted = 1;
3699 else {
3700 perror(tainted_file);
3701 kernel_has_tainted = 0;
3702 }
3703 }
3704
3705 switch (obj_gpl_license(f, &ptr)) {
3706 case 0:
3707 break;
3708 case 1:
3709 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3710 break;
3711 case 2:
3712 /* The module has a non-GPL license so we pretend that the
3713 * kernel always has a taint flag to get a warning even on
3714 * kernels without the proc flag.
3715 */
3716 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3717 break;
3718 default:
3719 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3720 break;
3721 }
3722
3723 if (flag_force_load)
3724 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3725
3726 if (fd >= 0)
3727 close(fd);
3728}
Eric Andersen71ae64b2002-10-10 04:20:21 +00003729#else /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
3730#define check_tainted_module(x, y) do { } while(0);
3731#endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
Eric Andersen9f16d612000-06-12 23:11:16 +00003732
Eric Andersen889dd202003-01-23 04:48:34 +00003733#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3734/* add module source, timestamp, kernel version and a symbol for the
3735 * start of some sections. this info is used by ksymoops to do better
3736 * debugging.
3737 */
3738static int
3739get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3740{
3741#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00003742 return new_get_module_version(f, str);
Eric Andersen889dd202003-01-23 04:48:34 +00003743#else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003744 strncpy(str, "???", sizeof(str));
3745 return -1;
Eric Andersen889dd202003-01-23 04:48:34 +00003746#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
3747}
3748
3749/* add module source, timestamp, kernel version and a symbol for the
3750 * start of some sections. this info is used by ksymoops to do better
3751 * debugging.
3752 */
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003753static void
Eric Andersen889dd202003-01-23 04:48:34 +00003754add_ksymoops_symbols(struct obj_file *f, const char *filename,
3755 const char *m_name)
3756{
3757 static const char symprefix[] = "__insmod_";
3758 struct obj_section *sec;
3759 struct obj_symbol *sym;
3760 char *name, *absolute_filename;
3761 char str[STRVERSIONLEN], real[PATH_MAX];
3762 int i, l, lm_name, lfilename, use_ksymtab, version;
3763 struct stat statbuf;
3764
3765 static const char *section_names[] = {
3766 ".text",
3767 ".rodata",
3768 ".data",
Peter Kjellerstedt540769d2005-03-30 16:36:40 +00003769 ".bss",
3770 ".sbss"
Eric Andersen889dd202003-01-23 04:48:34 +00003771 };
3772
3773 if (realpath(filename, real)) {
Rob Landleyd921b2e2006-08-03 15:41:12 +00003774 absolute_filename = xstrdup(real);
Eric Andersen889dd202003-01-23 04:48:34 +00003775 }
3776 else {
3777 int save_errno = errno;
Manuel Novoa III cad53642003-03-19 09:13:01 +00003778 bb_error_msg("cannot get realpath for %s", filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003779 errno = save_errno;
3780 perror("");
Rob Landleyd921b2e2006-08-03 15:41:12 +00003781 absolute_filename = xstrdup(filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003782 }
3783
3784 lm_name = strlen(m_name);
3785 lfilename = strlen(absolute_filename);
3786
3787 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3788 * are not to be exported. otherwise leave ksymtab alone for now, the
3789 * "export all symbols" compatibility code will export these symbols later.
3790 */
Denis Vlasenkofe76cd52006-09-23 12:32:58 +00003791 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
Eric Andersen889dd202003-01-23 04:48:34 +00003792
3793 if ((sec = obj_find_section(f, ".this"))) {
3794 /* tag the module header with the object name, last modified
3795 * timestamp and module version. worst case for module version
3796 * is 0xffffff, decimal 16777215. putting all three fields in
3797 * one symbol is less readable but saves kernel space.
3798 */
3799 l = sizeof(symprefix)+ /* "__insmod_" */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003800 lm_name+ /* module name */
3801 2+ /* "_O" */
3802 lfilename+ /* object filename */
3803 2+ /* "_M" */
3804 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */
3805 2+ /* "_V" */
3806 8+ /* version in dec */
3807 1; /* nul */
Eric Andersen889dd202003-01-23 04:48:34 +00003808 name = xmalloc(l);
3809 if (stat(absolute_filename, &statbuf) != 0)
3810 statbuf.st_mtime = 0;
3811 version = get_module_version(f, str); /* -1 if not found */
3812 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003813 symprefix, m_name, absolute_filename,
3814 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3815 version);
Eric Andersen889dd202003-01-23 04:48:34 +00003816 sym = obj_add_symbol(f, name, -1,
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003817 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003818 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003819 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003820 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003821 }
3822 free(absolute_filename);
3823#ifdef _NOT_SUPPORTED_
3824 /* record where the persistent data is going, same address as previous symbol */
3825
3826 if (f->persist) {
3827 l = sizeof(symprefix)+ /* "__insmod_" */
3828 lm_name+ /* module name */
3829 2+ /* "_P" */
3830 strlen(f->persist)+ /* data store */
3831 1; /* nul */
3832 name = xmalloc(l);
3833 snprintf(name, l, "%s%s_P%s",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003834 symprefix, m_name, f->persist);
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003835 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003836 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003837 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003838 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003839 }
3840#endif /* _NOT_SUPPORTED_ */
3841 /* tag the desired sections if size is non-zero */
3842
3843 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
3844 if ((sec = obj_find_section(f, section_names[i])) &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00003845 sec->header.sh_size) {
Eric Andersen889dd202003-01-23 04:48:34 +00003846 l = sizeof(symprefix)+ /* "__insmod_" */
3847 lm_name+ /* module name */
3848 2+ /* "_S" */
3849 strlen(sec->name)+ /* section name */
3850 2+ /* "_L" */
3851 8+ /* length in dec */
3852 1; /* nul */
3853 name = xmalloc(l);
3854 snprintf(name, l, "%s%s_S%s_L%ld",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003855 symprefix, m_name, sec->name,
3856 (long)sec->header.sh_size);
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003857 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003858 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003859 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003860 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003861 }
3862 }
3863}
3864#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3865
Eric Andersenbe65c352003-01-23 04:57:35 +00003866#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3867static void print_load_map(struct obj_file *f)
3868{
3869 struct obj_symbol *sym;
3870 struct obj_symbol **all, **p;
3871 struct obj_section *sec;
3872 int i, nsyms, *loaded;
3873
3874 /* Report on the section layout. */
3875
3876 printf("Sections: Size %-*s Align\n",
3877 (int) (2 * sizeof(void *)), "Address");
3878
3879 for (sec = f->load_order; sec; sec = sec->load_next) {
3880 int a;
3881 unsigned long tmp;
3882
3883 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3884 tmp >>= 1;
3885 if (a == -1)
3886 a = 0;
3887
3888 printf("%-15s %08lx %0*lx 2**%d\n",
3889 sec->name,
3890 (long)sec->header.sh_size,
3891 (int) (2 * sizeof(void *)),
3892 (long)sec->header.sh_addr,
3893 a);
3894 }
3895#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
3896 /* Quick reference which section indicies are loaded. */
3897
3898 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3899 while (--i >= 0)
3900 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3901
3902 /* Collect the symbols we'll be listing. */
3903
3904 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3905 for (sym = f->symtab[i]; sym; sym = sym->next)
3906 if (sym->secidx <= SHN_HIRESERVE
3907 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3908 ++nsyms;
3909
3910 all = alloca(nsyms * sizeof(struct obj_symbol *));
3911
3912 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3913 for (sym = f->symtab[i]; sym; sym = sym->next)
3914 if (sym->secidx <= SHN_HIRESERVE
3915 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3916 *p++ = sym;
3917
3918 /* And list them. */
3919 printf("\nSymbols:\n");
3920 for (p = all; p < all + nsyms; ++p) {
3921 char type = '?';
3922 unsigned long value;
3923
3924 sym = *p;
3925 if (sym->secidx == SHN_ABS) {
3926 type = 'A';
3927 value = sym->value;
3928 } else if (sym->secidx == SHN_UNDEF) {
3929 type = 'U';
3930 value = 0;
3931 } else {
3932 sec = f->sections[sym->secidx];
3933
3934 if (sec->header.sh_type == SHT_NOBITS)
3935 type = 'B';
3936 else if (sec->header.sh_flags & SHF_ALLOC) {
3937 if (sec->header.sh_flags & SHF_EXECINSTR)
3938 type = 'T';
3939 else if (sec->header.sh_flags & SHF_WRITE)
3940 type = 'D';
3941 else
3942 type = 'R';
3943 }
3944 value = sym->value + sec->header.sh_addr;
3945 }
3946
Mike Frysinger86a4bfb2005-10-02 07:02:16 +00003947 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
Eric Andersenbe65c352003-01-23 04:57:35 +00003948 type = tolower(type);
3949
3950 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3951 type, sym->name);
3952 }
3953#endif
3954}
Denis Vlasenkofe76cd52006-09-23 12:32:58 +00003955#else /* !CONFIG_FEATURE_INSMOD_LOAD_MAP */
3956void print_load_map(struct obj_file *f);
Eric Andersenbe65c352003-01-23 04:57:35 +00003957#endif
3958
Rob Landleydfba7412006-03-06 20:47:33 +00003959int insmod_main( int argc, char **argv)
Eric Andersen9f16d612000-06-12 23:11:16 +00003960{
Denis Vlasenkofe76cd52006-09-23 12:32:58 +00003961 char *opt_o;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003962 int len;
Eric Andersen5275b1e2004-06-22 20:10:53 +00003963 int k_crcs;
Eric Andersen6fb4e482002-06-06 14:24:57 +00003964 char *tmp, *tmp1;
Eric Andersen9f16d612000-06-12 23:11:16 +00003965 unsigned long m_size;
3966 ElfW(Addr) m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00003967 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003968 struct stat st;
Eric Andersen61f83052002-06-22 17:15:42 +00003969 char *m_name = 0;
Matt Kraai3e856ce2000-12-01 02:55:13 +00003970 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003971 int m_has_modinfo;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003972#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Matt Kraai063c1f52001-08-06 14:18:08 +00003973 struct utsname uts_info;
Eric Andersen9f16d612000-06-12 23:11:16 +00003974 char m_strversion[STRVERSIONLEN];
Eric Andersen5275b1e2004-06-22 20:10:53 +00003975 int m_version, m_crcs;
Eric Andersen9f16d612000-06-12 23:11:16 +00003976#endif
Eric Andersen61f83052002-06-22 17:15:42 +00003977#ifdef CONFIG_FEATURE_CLEAN_UP
3978 FILE *fp = 0;
3979#else
3980 FILE *fp;
3981#endif
Eric Andersen03d80912003-12-19 21:04:19 +00003982 int k_version = 0;
3983 struct utsname myuname;
Eric Andersen9f16d612000-06-12 23:11:16 +00003984
Erik Andersene49d5ec2000-02-08 19:58:47 +00003985 /* Parse any options */
Denis Vlasenko67b23e62006-10-03 21:00:06 +00003986 option_mask = getopt32(argc, argv, OPTION_STR, &opt_o);
Denis Vlasenkofe76cd52006-09-23 12:32:58 +00003987 if (option_mask & OPT_o) { // -o /* name the output module */
3988 free(m_name);
3989 m_name = xstrdup(opt_o);
3990 }
Eric Andersen03d80912003-12-19 21:04:19 +00003991
Eric Andersena18aaf12001-01-24 19:07:09 +00003992 if (argv[optind] == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003993 bb_show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003994 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003995
Erik Andersene49d5ec2000-02-08 19:58:47 +00003996 /* Grab the module name */
Rob Landleyd921b2e2006-08-03 15:41:12 +00003997 tmp1 = xstrdup(argv[optind]);
Eric Andersen6fb4e482002-06-06 14:24:57 +00003998 tmp = basename(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003999 len = strlen(tmp);
4000
Eric Andersen03d80912003-12-19 21:04:19 +00004001 if (uname(&myuname) == 0) {
4002 if (myuname.release[0] == '2') {
4003 k_version = myuname.release[2] - '0';
4004 }
4005 }
4006
4007#if defined(CONFIG_FEATURE_2_6_MODULES)
4008 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00004009 tmp[len - 2] == 'k' && tmp[len - 1] == 'o') {
Eric Andersen03d80912003-12-19 21:04:19 +00004010 len-=3;
4011 tmp[len] = '\0';
4012 }
4013 else
4014#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00004015 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
4016 len-=2;
4017 tmp[len] = '\0';
4018 }
Eric Andersen2d342152002-06-18 05:16:25 +00004019
Eric Andersen03d80912003-12-19 21:04:19 +00004020
4021#if defined(CONFIG_FEATURE_2_6_MODULES)
4022 if (k_version > 4)
Rob Landleyd921b2e2006-08-03 15:41:12 +00004023 m_fullName = xasprintf("%s.ko", tmp);
Eric Andersen03d80912003-12-19 21:04:19 +00004024 else
Eric Andersen03d80912003-12-19 21:04:19 +00004025#endif
Rob Landleyd921b2e2006-08-03 15:41:12 +00004026 m_fullName = xasprintf("%s.o", tmp);
Eric Andersen61f83052002-06-22 17:15:42 +00004027
Eric Andersen61f83052002-06-22 17:15:42 +00004028 if (!m_name) {
4029 m_name = tmp;
4030 } else {
4031 free(tmp1);
4032 tmp1 = 0; /* flag for free(m_name) before exit() */
4033 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00004034
Eric Andersen14d35432001-05-14 17:07:32 +00004035 /* Get a filedesc for the module. Check we we have a complete path */
Eric Andersen02b9f422001-02-15 19:07:43 +00004036 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
4037 (fp = fopen(argv[optind], "r")) == NULL) {
Eric Andersen14d35432001-05-14 17:07:32 +00004038 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
4039 * but do not error out yet if we fail to find it... */
Eric Andersen03d80912003-12-19 21:04:19 +00004040 if (k_version) { /* uname succeedd */
4041 char *module_dir;
4042 char *tmdn;
Eric Andersen2416dfc2001-05-14 20:03:04 +00004043 char real_module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00004044
Eric Andersen03d80912003-12-19 21:04:19 +00004045 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
Eric Andersen2416dfc2001-05-14 20:03:04 +00004046 /* Jump through hoops in case /lib/modules/`uname -r`
4047 * is a symlink. We do not want recursive_action to
4048 * follow symlinks, but we do want to follow the
4049 * /lib/modules/`uname -r` dir, So resolve it ourselves
4050 * if it is a link... */
Eric Andersen03d80912003-12-19 21:04:19 +00004051 if (realpath (tmdn, real_module_dir) == NULL)
4052 module_dir = tmdn;
4053 else
4054 module_dir = real_module_dir;
4055 recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen3b1a7442003-12-24 20:30:45 +00004056 check_module_name_match, 0, m_fullName);
Eric Andersen03d80912003-12-19 21:04:19 +00004057 free(tmdn);
Eric Andersen14d35432001-05-14 17:07:32 +00004058 }
4059
4060 /* Check if we have found anything yet */
Eric Andersen61f83052002-06-22 17:15:42 +00004061 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen9f16d612000-06-12 23:11:16 +00004062 {
Eric Andersen2416dfc2001-05-14 20:03:04 +00004063 char module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00004064
Eric Andersen03d80912003-12-19 21:04:19 +00004065 free(m_filename);
4066 m_filename = 0;
Eric Andersen2416dfc2001-05-14 20:03:04 +00004067 if (realpath (_PATH_MODULES, module_dir) == NULL)
4068 strcpy(module_dir, _PATH_MODULES);
Eric Andersen14d35432001-05-14 17:07:32 +00004069 /* No module found under /lib/modules/`uname -r`, this
4070 * time cast the net a bit wider. Search /lib/modules/ */
Matt Kraai1f0c4362001-12-20 23:13:26 +00004071 if (! recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen03d80912003-12-19 21:04:19 +00004072 check_module_name_match, 0, m_fullName))
Eric Andersen9f16d612000-06-12 23:11:16 +00004073 {
Eric Andersen61f83052002-06-22 17:15:42 +00004074 if (m_filename == 0
Eric Andersen03d80912003-12-19 21:04:19 +00004075 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen14d35432001-05-14 17:07:32 +00004076 {
Manuel Novoa III cad53642003-03-19 09:13:01 +00004077 bb_error_msg("%s: no module by that name found", m_fullName);
Eric Andersen61f83052002-06-22 17:15:42 +00004078 goto out;
Eric Andersen14d35432001-05-14 17:07:32 +00004079 }
4080 } else
Manuel Novoa III cad53642003-03-19 09:13:01 +00004081 bb_error_msg_and_die("%s: no module by that name found", m_fullName);
Eric Andersen14d35432001-05-14 17:07:32 +00004082 }
Eric Andersen03d80912003-12-19 21:04:19 +00004083 } else
Rob Landleyd921b2e2006-08-03 15:41:12 +00004084 m_filename = xstrdup(argv[optind]);
Erik Andersend387d011999-12-21 02:55:11 +00004085
Rob Landley999af202005-12-11 20:14:12 +00004086 if (flag_verbose)
Glenn L McGrath5c9f0d02003-12-31 23:20:10 +00004087 printf("Using %s\n", m_filename);
Erik Andersend387d011999-12-21 02:55:11 +00004088
Eric Andersene7047882003-12-11 01:42:13 +00004089#ifdef CONFIG_FEATURE_2_6_MODULES
Eric Andersen03d80912003-12-19 21:04:19 +00004090 if (k_version > 4)
4091 {
Glenn L McGrathc2942f02003-08-31 01:58:18 +00004092 optind--;
Eric Andersen03d80912003-12-19 21:04:19 +00004093 argv[optind + 1] = m_filename;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00004094 return insmod_ng_main(argc - optind, argv + optind);
Eric Andersen03d80912003-12-19 21:04:19 +00004095 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00004096#endif
4097
Eric Andersen8ae319a2001-05-21 16:09:18 +00004098 if ((f = obj_load(fp, LOADBITS)) == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +00004099 bb_perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00004100
Eric Andersen9f16d612000-06-12 23:11:16 +00004101 if (get_modinfo_value(f, "kernel_version") == NULL)
4102 m_has_modinfo = 0;
4103 else
4104 m_has_modinfo = 1;
4105
Eric Andersenbdfd0d72001-10-24 05:00:29 +00004106#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00004107 /* Version correspondence? */
Eric Andersenb493dec2002-07-02 19:14:23 +00004108 if (!flag_quiet) {
4109 if (uname(&uts_info) < 0)
4110 uts_info.release[0] = '\0';
4111 if (m_has_modinfo) {
4112 m_version = new_get_module_version(f, m_strversion);
Eric Andersenb493dec2002-07-02 19:14:23 +00004113 if (m_version == -1) {
Denis Vlasenkoa9595882006-09-29 21:30:43 +00004114 bb_error_msg("cannot find the kernel version the module was "
Eric Andersenb493dec2002-07-02 19:14:23 +00004115 "compiled for");
4116 goto out;
4117 }
4118 }
4119
4120 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
4121 if (flag_force_load) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00004122 bb_error_msg("Warning: kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00004123 "\t%s was compiled for kernel version %s\n"
4124 "\twhile this kernel is version %s",
4125 m_filename, m_strversion, uts_info.release);
4126 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00004127 bb_error_msg("kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00004128 "\t%s was compiled for kernel version %s\n"
4129 "\twhile this kernel is version %s.",
4130 m_filename, m_strversion, uts_info.release);
4131 goto out;
4132 }
Eric Andersen9f16d612000-06-12 23:11:16 +00004133 }
4134 }
4135 k_crcs = 0;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00004136#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00004137
Eric Andersencb3b9b12004-06-22 11:50:52 +00004138 if (!query_module(NULL, 0, NULL, 0, NULL)) {
Eric Andersen9f16d612000-06-12 23:11:16 +00004139 if (!new_get_kernel_symbols())
4140 goto out;
4141 k_crcs = new_is_kernel_checksummed();
Eric Andersen9f16d612000-06-12 23:11:16 +00004142 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00004143 bb_error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00004144 goto out;
Eric Andersen9f16d612000-06-12 23:11:16 +00004145 }
4146
Eric Andersenbdfd0d72001-10-24 05:00:29 +00004147#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00004148 m_crcs = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00004149 if (m_has_modinfo)
4150 m_crcs = new_is_module_checksummed(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00004151
4152 if (m_crcs != k_crcs)
4153 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00004154#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00004155
Erik Andersene49d5ec2000-02-08 19:58:47 +00004156 /* Let the module know about the kernel symbols. */
4157 add_kernel_symbols(f);
4158
Eric Andersen9f16d612000-06-12 23:11:16 +00004159 /* Allocate common symbols, symbol tables, and string tables. */
4160
Eric Andersencb3b9b12004-06-22 11:50:52 +00004161 if (!new_create_this_module(f, m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00004162 {
4163 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00004164 }
4165
Eric Andersen9f16d612000-06-12 23:11:16 +00004166 if (!obj_check_undefineds(f)) {
4167 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00004168 }
4169 obj_allocate_commons(f);
Eric Andersen166fa462002-09-16 05:30:24 +00004170 check_tainted_module(f, m_name);
Erik Andersene49d5ec2000-02-08 19:58:47 +00004171
Eric Andersen86f3d5b2001-01-24 23:59:50 +00004172 /* done with the module name, on to the optional var=value arguments */
4173 ++optind;
4174
Eric Andersen9f16d612000-06-12 23:11:16 +00004175 if (optind < argc) {
Robert Griebl809387f2004-07-20 15:43:57 +00004176 if (!new_process_module_arguments(f, argc - optind, argv + optind))
Eric Andersen9f16d612000-06-12 23:11:16 +00004177 {
4178 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00004179 }
4180 }
4181
Eric Andersen9f16d612000-06-12 23:11:16 +00004182 arch_create_got(f);
4183 hide_special_symbols(f);
4184
Eric Andersen889dd202003-01-23 04:48:34 +00004185#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
4186 add_ksymoops_symbols(f, m_filename, m_name);
4187#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
4188
Eric Andersencb3b9b12004-06-22 11:50:52 +00004189 new_create_module_ksymtab(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00004190
Erik Andersene49d5ec2000-02-08 19:58:47 +00004191 /* Find current size of the module */
4192 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00004193
4194
Erik Andersene49d5ec2000-02-08 19:58:47 +00004195 m_addr = create_module(m_name, m_size);
Eric Andersen61f83052002-06-22 17:15:42 +00004196 if (m_addr == -1) switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00004197 case EEXIST:
4198 bb_error_msg("A module named %s already exists", m_name);
4199 goto out;
4200 case ENOMEM:
4201 bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes",
4202 m_size);
4203 goto out;
4204 default:
4205 bb_perror_msg("create_module: %s", m_name);
4206 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00004207 }
Erik Andersend387d011999-12-21 02:55:11 +00004208
Eric Andersen8ae319a2001-05-21 16:09:18 +00004209#if !LOADBITS
4210 /*
4211 * the PROGBITS section was not loaded by the obj_load
4212 * now we can load them directly into the kernel memory
4213 */
Eric Andersenac5dbd12001-08-22 05:26:08 +00004214 if (!obj_load_progbits(fp, f, (char*)m_addr)) {
Eric Andersen8ae319a2001-05-21 16:09:18 +00004215 delete_module(m_name);
4216 goto out;
4217 }
Eric Andersen03d80912003-12-19 21:04:19 +00004218#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +00004219
Eric Andersen9f16d612000-06-12 23:11:16 +00004220 if (!obj_relocate(f, m_addr)) {
4221 delete_module(m_name);
4222 goto out;
4223 }
Erik Andersend387d011999-12-21 02:55:11 +00004224
Eric Andersencb3b9b12004-06-22 11:50:52 +00004225 if (!new_init_module(m_name, f, m_size))
Eric Andersen9f16d612000-06-12 23:11:16 +00004226 {
4227 delete_module(m_name);
4228 goto out;
4229 }
4230
Eric Andersenbe65c352003-01-23 04:57:35 +00004231 if(flag_print_load_map)
4232 print_load_map(f);
Eric Andersenbe65c352003-01-23 04:57:35 +00004233
Matt Kraai3e856ce2000-12-01 02:55:13 +00004234 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00004235
4236out:
Eric Andersen61f83052002-06-22 17:15:42 +00004237#ifdef CONFIG_FEATURE_CLEAN_UP
4238 if(fp)
Eric Andersen3b1a7442003-12-24 20:30:45 +00004239 fclose(fp);
Rob Landleye7c43b62006-03-01 16:39:45 +00004240 free(tmp1);
4241 if(!tmp1) {
Eric Andersen61f83052002-06-22 17:15:42 +00004242 free(m_name);
4243 }
4244 free(m_filename);
4245#endif
Eric Andersenbb245ba2000-06-19 19:53:30 +00004246 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00004247}
Eric Andersene7047882003-12-11 01:42:13 +00004248
4249
4250#endif
4251
4252
4253#ifdef CONFIG_FEATURE_2_6_MODULES
4254
4255#include <sys/mman.h>
4256#include <asm/unistd.h>
4257#include <sys/syscall.h>
4258
4259/* We use error numbers in a loose translation... */
4260static const char *moderror(int err)
4261{
4262 switch (err) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00004263 case ENOEXEC:
4264 return "Invalid module format";
4265 case ENOENT:
4266 return "Unknown symbol in module";
4267 case ESRCH:
4268 return "Module has wrong symbol version";
4269 case EINVAL:
4270 return "Invalid parameters";
4271 default:
4272 return strerror(err);
Eric Andersene7047882003-12-11 01:42:13 +00004273 }
4274}
4275
Rob Landleydfba7412006-03-06 20:47:33 +00004276int insmod_ng_main( int argc, char **argv)
Eric Andersene7047882003-12-11 01:42:13 +00004277{
4278 int i;
4279 int fd;
4280 long int ret;
4281 struct stat st;
4282 unsigned long len;
4283 void *map;
Rob Landleyd921b2e2006-08-03 15:41:12 +00004284 char *filename, *options = xstrdup("");
Eric Andersen3b1a7442003-12-24 20:30:45 +00004285
Eric Andersene7047882003-12-11 01:42:13 +00004286 filename = argv[1];
4287 if (!filename) {
4288 bb_show_usage();
4289 return -1;
4290 }
4291
4292 /* Rest is options */
4293 for (i = 2; i < argc; i++) {
4294 options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2);
4295 /* Spaces handled by "" pairs, but no way of escaping quotes */
4296 if (strchr(argv[i], ' ')) {
4297 strcat(options, "\"");
4298 strcat(options, argv[i]);
4299 strcat(options, "\"");
4300 } else {
4301 strcat(options, argv[i]);
4302 }
4303 strcat(options, " ");
4304 }
4305
Denis Vlasenkod5d614c2006-09-09 12:25:20 +00004306 fd = xopen(filename, O_RDONLY);
Eric Andersene7047882003-12-11 01:42:13 +00004307
4308 fstat(fd, &st);
4309 len = st.st_size;
Rob Landley07fffc52005-12-07 22:45:28 +00004310 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
Eric Andersene7047882003-12-11 01:42:13 +00004311 if (map == MAP_FAILED) {
4312 bb_perror_msg_and_die("cannot mmap `%s'", filename);
4313 }
4314
4315 ret = syscall(__NR_init_module, map, len, options);
4316 if (ret != 0) {
4317 bb_perror_msg_and_die("cannot insert `%s': %s (%li)",
Eric Andersen3b1a7442003-12-24 20:30:45 +00004318 filename, moderror(errno), ret);
Eric Andersene7047882003-12-11 01:42:13 +00004319 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00004320
Eric Andersene7047882003-12-11 01:42:13 +00004321 return 0;
4322}
4323
4324#endif