blob: dfb8a765ec746fb6b46c588ce762613121d6b6fd [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 *
58 * This program is free software; you can redistribute it and/or modify
59 * it under the terms of the GNU General Public License as published by
60 * the Free Software Foundation; either version 2 of the License, or
61 * (at your option) any later version.
62 *
63 * This program is distributed in the hope that it will be useful,
64 * but WITHOUT ANY WARRANTY; without even the implied warranty of
65 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
66 * General Public License for more details.
67 *
68 * You should have received a copy of the GNU General Public License
69 * along with this program; if not, write to the Free Software
70 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
71 *
72 */
73
Erik Andersen02104321999-12-17 18:57:34 +000074#include <stdlib.h>
75#include <stdio.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000076#include <stddef.h>
Erik Andersen02104321999-12-17 18:57:34 +000077#include <errno.h>
78#include <unistd.h>
79#include <dirent.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000080#include <ctype.h>
81#include <assert.h>
Eric Andersened3ef502001-01-27 08:24:39 +000082#include <string.h>
Eric Andersen999bf722000-07-09 06:59:58 +000083#include <getopt.h>
Eric Andersen166fa462002-09-16 05:30:24 +000084#include <fcntl.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000085#include <sys/utsname.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000086#include "busybox.h"
Eric Andersen9f16d612000-06-12 23:11:16 +000087
Eric Andersene7047882003-12-11 01:42:13 +000088#if !defined(CONFIG_FEATURE_2_4_MODULES) && \
Eric Andersene7047882003-12-11 01:42:13 +000089 !defined(CONFIG_FEATURE_2_6_MODULES)
90#define CONFIG_FEATURE_2_4_MODULES
91#endif
92
Eric Andersencb3b9b12004-06-22 11:50:52 +000093#if !defined(CONFIG_FEATURE_2_4_MODULES)
Eric Andersene7047882003-12-11 01:42:13 +000094#define insmod_ng_main insmod_main
95#endif
96
Eric Andersene7047882003-12-11 01:42:13 +000097#if defined(CONFIG_FEATURE_2_6_MODULES)
98extern int insmod_ng_main( int argc, char **argv);
99#endif
100
Eric Andersencb3b9b12004-06-22 11:50:52 +0000101
102#if defined(CONFIG_FEATURE_2_4_MODULES)
103
Eric Andersen64c8b172001-04-05 07:33:10 +0000104
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000105#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000106#define LOADBITS 0
Eric Andersen8ae319a2001-05-21 16:09:18 +0000107#else
108#define LOADBITS 1
109#endif
110
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000111
Mike Frysinger63654c12004-12-26 09:13:32 +0000112/* Alpha */
113#if defined(__alpha__)
114#define MATCH_MACHINE(x) (x == EM_ALPHA)
115#define SHT_RELM SHT_RELA
116#define Elf64_RelM Elf64_Rela
117#define ELFCLASSM ELFCLASS64
118#endif
119
Eric Andersen45a05132004-09-02 23:03:25 +0000120/* ARM support */
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000121#if defined(__arm__)
Eric Andersencffd5022002-05-24 06:50:15 +0000122#define MATCH_MACHINE(x) (x == EM_ARM)
123#define SHT_RELM SHT_REL
124#define Elf32_RelM Elf32_Rel
125#define ELFCLASSM ELFCLASS32
Eric Andersenc3b2dbe2003-03-13 18:57:08 +0000126#define CONFIG_USE_PLT_ENTRIES
127#define CONFIG_PLT_ENTRY_SIZE 8
128#define CONFIG_USE_GOT_ENTRIES
129#define CONFIG_GOT_ENTRY_SIZE 8
130#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000131#endif
Eric Andersenbf77f612003-01-23 06:02:39 +0000132
Eric Andersen45a05132004-09-02 23:03:25 +0000133/* CRIS */
134#if defined(__cris__)
135#define MATCH_MACHINE(x) (x == EM_CRIS)
Eric Andersenbf77f612003-01-23 06:02:39 +0000136#define SHT_RELM SHT_RELA
137#define Elf32_RelM Elf32_Rela
138#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000139#ifndef EM_CRIS
140#define EM_CRIS 76
141#define R_CRIS_NONE 0
142#define R_CRIS_32 3
143#endif
Eric Andersenbf77f612003-01-23 06:02:39 +0000144#endif
145
Mike Frysinger63654c12004-12-26 09:13:32 +0000146/* PA-RISC / HP-PA */
147#if defined(__hppa__)
148#define MATCH_MACHINE(x) (x == EM_PARISC)
149#define SHT_RELM SHT_RELA
150#if defined(__LP64__)
151#define Elf64_RelM Elf64_Rela
152#define ELFCLASSM ELFCLASS64
153#else
154#define Elf32_RelM Elf32_Rela
155#define ELFCLASSM ELFCLASS32
156#endif
157#endif
158
Eric Andersen45a05132004-09-02 23:03:25 +0000159/* H8/300 */
160#if defined(__H8300H__) || defined(__H8300S__)
161#define MATCH_MACHINE(x) (x == EM_H8_300)
162#define SHT_RELM SHT_RELA
163#define Elf32_RelM Elf32_Rela
164#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000165#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000166#define SYMBOL_PREFIX "_"
167#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000168
Eric Andersen45a05132004-09-02 23:03:25 +0000169/* x86 */
170#if defined(__i386__)
Eric Andersencffd5022002-05-24 06:50:15 +0000171#ifndef EM_486
172#define MATCH_MACHINE(x) (x == EM_386)
173#else
174#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
175#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000176#define SHT_RELM SHT_REL
177#define Elf32_RelM Elf32_Rel
178#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000179#define CONFIG_USE_GOT_ENTRIES
180#define CONFIG_GOT_ENTRY_SIZE 4
181#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000182#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000183
Eric Andersen45a05132004-09-02 23:03:25 +0000184/* IA64, aka Itanium */
185#if defined(__ia64__)
186#define MATCH_MACHINE(x) (x == EM_IA_64)
187#define SHT_RELM SHT_RELA
188#define Elf64_RelM Elf64_Rela
189#define ELFCLASSM ELFCLASS64
190#endif
191
192/* m68k */
193#if defined(__mc68000__)
Eric Andersencffd5022002-05-24 06:50:15 +0000194#define MATCH_MACHINE(x) (x == EM_68K)
195#define SHT_RELM SHT_RELA
196#define Elf32_RelM Elf32_Rela
Eric Andersen9e458f52004-03-19 12:17:04 +0000197#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000198#define CONFIG_USE_GOT_ENTRIES
199#define CONFIG_GOT_ENTRY_SIZE 4
200#define CONFIG_USE_SINGLE
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000201#endif
202
Eric Andersen45a05132004-09-02 23:03:25 +0000203/* MIPS */
Eric Andersen2bf658d2001-02-24 20:01:53 +0000204#if defined(__mips__)
Eric Andersen45a05132004-09-02 23:03:25 +0000205#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
206#define SHT_RELM SHT_REL
207#define Elf32_RelM Elf32_Rel
208#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000209/* Account for ELF spec changes. */
210#ifndef EM_MIPS_RS3_LE
211#ifdef EM_MIPS_RS4_BE
212#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
213#else
214#define EM_MIPS_RS3_LE 10
215#endif
216#endif /* !EM_MIPS_RS3_LE */
Eric Andersencffd5022002-05-24 06:50:15 +0000217#define ARCHDATAM "__dbe_table"
218#endif
219
Eric Andersen45a05132004-09-02 23:03:25 +0000220/* PowerPC */
Eric Andersencffd5022002-05-24 06:50:15 +0000221#if defined(__powerpc__)
Eric Andersen45a05132004-09-02 23:03:25 +0000222#define MATCH_MACHINE(x) (x == EM_PPC)
223#define SHT_RELM SHT_RELA
224#define Elf32_RelM Elf32_Rela
225#define ELFCLASSM ELFCLASS32
Eric Andersencffd5022002-05-24 06:50:15 +0000226#define CONFIG_USE_PLT_ENTRIES
227#define CONFIG_PLT_ENTRY_SIZE 16
228#define CONFIG_USE_PLT_LIST
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000229#define CONFIG_LIST_ARCHTYPE ElfW(Addr)
Eric Andersencffd5022002-05-24 06:50:15 +0000230#define CONFIG_USE_LIST
Eric Andersencffd5022002-05-24 06:50:15 +0000231#define ARCHDATAM "__ftr_fixup"
232#endif
233
Eric Andersen45a05132004-09-02 23:03:25 +0000234/* S390 */
235#if defined(__s390__)
236#define MATCH_MACHINE(x) (x == EM_S390)
237#define SHT_RELM SHT_RELA
238#define Elf32_RelM Elf32_Rela
239#define ELFCLASSM ELFCLASS32
240#define CONFIG_USE_PLT_ENTRIES
241#define CONFIG_PLT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000242#define CONFIG_USE_GOT_ENTRIES
Eric Andersen45a05132004-09-02 23:03:25 +0000243#define CONFIG_GOT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000244#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000245#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000246
Eric Andersen45a05132004-09-02 23:03:25 +0000247/* SuperH */
248#if defined(__sh__)
Eric Andersencffd5022002-05-24 06:50:15 +0000249#define MATCH_MACHINE(x) (x == EM_SH)
250#define SHT_RELM SHT_RELA
251#define Elf32_RelM Elf32_Rela
252#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000253#define CONFIG_USE_GOT_ENTRIES
254#define CONFIG_GOT_ENTRY_SIZE 4
255#define CONFIG_USE_SINGLE
Eric Andersenbf833552003-08-13 19:56:33 +0000256/* the SH changes have only been tested in =little endian= mode */
Eric Andersencffd5022002-05-24 06:50:15 +0000257/* I'm not sure about big endian, so let's warn: */
Eric Andersenbf833552003-08-13 19:56:33 +0000258#if defined(__sh__) && defined(__BIG_ENDIAN__)
259#error insmod.c may require changes for use on big endian SH
Eric Andersencffd5022002-05-24 06:50:15 +0000260#endif
Eric Andersen45a05132004-09-02 23:03:25 +0000261/* it may or may not work on the SH1/SH2... Error on those also */
262#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
Eric Andersenbf833552003-08-13 19:56:33 +0000263#error insmod.c may require changes for SH1 or SH2 use
Eric Andersencffd5022002-05-24 06:50:15 +0000264#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000265#endif
266
Eric Andersen45a05132004-09-02 23:03:25 +0000267/* Sparc */
268#if defined(__sparc__)
269#define MATCH_MACHINE(x) (x == EM_SPARC)
270#define SHT_RELM SHT_RELA
271#define Elf32_RelM Elf32_Rela
272#define ELFCLASSM ELFCLASS32
Miles Baderae28b042002-04-01 09:34:25 +0000273#endif
274
Eric Andersen45a05132004-09-02 23:03:25 +0000275/* v850e */
276#if defined (__v850e__)
Eric Andersencffd5022002-05-24 06:50:15 +0000277#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
278#define SHT_RELM SHT_RELA
279#define Elf32_RelM Elf32_Rela
280#define ELFCLASSM ELFCLASS32
Eric Andersen45a05132004-09-02 23:03:25 +0000281#define CONFIG_USE_PLT_ENTRIES
282#define CONFIG_PLT_ENTRY_SIZE 8
Eric Andersenee70fa52004-05-26 11:38:46 +0000283#define CONFIG_USE_SINGLE
Eric Andersen45a05132004-09-02 23:03:25 +0000284#ifndef EM_CYGNUS_V850 /* grumble */
285#define EM_CYGNUS_V850 0x9080
286#endif
Eric Andersenee70fa52004-05-26 11:38:46 +0000287#define SYMBOL_PREFIX "_"
288#endif
289
Eric Andersen45a05132004-09-02 23:03:25 +0000290/* X86_64 */
291#if defined(__x86_64__)
292#define MATCH_MACHINE(x) (x == EM_X86_64)
Mike Frysinger354b5272005-03-30 06:29:41 +0000293#define SHT_RELM SHT_RELA
294#define Elf64_RelM Elf64_Rela
Eric Andersen45a05132004-09-02 23:03:25 +0000295#define ELFCLASSM ELFCLASS64
296#endif
297
Eric Andersencffd5022002-05-24 06:50:15 +0000298#ifndef SHT_RELM
299#error Sorry, but insmod.c does not yet support this architecture...
300#endif
301
302
Eric Andersen9f16d612000-06-12 23:11:16 +0000303//----------------------------------------------------------------------------
304//--------modutils module.h, lines 45-242
305//----------------------------------------------------------------------------
306
307/* Definitions for the Linux module syscall interface.
308 Copyright 1996, 1997 Linux International.
309
310 Contributed by Richard Henderson <rth@tamu.edu>
311
312 This file is part of the Linux modutils.
313
314 This program is free software; you can redistribute it and/or modify it
315 under the terms of the GNU General Public License as published by the
316 Free Software Foundation; either version 2 of the License, or (at your
317 option) any later version.
318
319 This program is distributed in the hope that it will be useful, but
320 WITHOUT ANY WARRANTY; without even the implied warranty of
321 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
322 General Public License for more details.
323
324 You should have received a copy of the GNU General Public License
325 along with this program; if not, write to the Free Software Foundation,
326 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
327
328
329#ifndef MODUTILS_MODULE_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000330static const int MODUTILS_MODULE_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000331
Mike Frysinger63654c12004-12-26 09:13:32 +0000332#ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000333
334/*======================================================================*/
335/* For sizeof() which are related to the module platform and not to the
336 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
337
338#define tgt_sizeof_char sizeof(char)
339#define tgt_sizeof_short sizeof(short)
340#define tgt_sizeof_int sizeof(int)
341#define tgt_sizeof_long sizeof(long)
342#define tgt_sizeof_char_p sizeof(char *)
343#define tgt_sizeof_void_p sizeof(void *)
344#define tgt_long long
345
346#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
347#undef tgt_sizeof_long
348#undef tgt_sizeof_char_p
349#undef tgt_sizeof_void_p
350#undef tgt_long
Mark Whitley59ab0252001-01-23 22:30:04 +0000351static const int tgt_sizeof_long = 8;
352static const int tgt_sizeof_char_p = 8;
353static const int tgt_sizeof_void_p = 8;
Eric Andersen9f16d612000-06-12 23:11:16 +0000354#define tgt_long long long
355#endif
356
357/*======================================================================*/
358/* The structures used in Linux 2.1. */
359
360/* Note: new_module_symbol does not use tgt_long intentionally */
361struct new_module_symbol
362{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000363 unsigned long value;
364 unsigned long name;
Eric Andersen9f16d612000-06-12 23:11:16 +0000365};
366
367struct new_module_persist;
368
369struct new_module_ref
370{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000371 unsigned tgt_long dep; /* kernel addresses */
372 unsigned tgt_long ref;
373 unsigned tgt_long next_ref;
Eric Andersen9f16d612000-06-12 23:11:16 +0000374};
375
376struct new_module
377{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000378 unsigned tgt_long size_of_struct; /* == sizeof(module) */
379 unsigned tgt_long next;
380 unsigned tgt_long name;
381 unsigned tgt_long size;
Eric Andersen9f16d612000-06-12 23:11:16 +0000382
Eric Andersen3b1a7442003-12-24 20:30:45 +0000383 tgt_long usecount;
384 unsigned tgt_long flags; /* AUTOCLEAN et al */
Eric Andersen9f16d612000-06-12 23:11:16 +0000385
Eric Andersen3b1a7442003-12-24 20:30:45 +0000386 unsigned nsyms;
387 unsigned ndeps;
Eric Andersen9f16d612000-06-12 23:11:16 +0000388
Eric Andersen3b1a7442003-12-24 20:30:45 +0000389 unsigned tgt_long syms;
390 unsigned tgt_long deps;
391 unsigned tgt_long refs;
392 unsigned tgt_long init;
393 unsigned tgt_long cleanup;
394 unsigned tgt_long ex_table_start;
395 unsigned tgt_long ex_table_end;
Eric Andersen9f16d612000-06-12 23:11:16 +0000396#ifdef __alpha__
Eric Andersen3b1a7442003-12-24 20:30:45 +0000397 unsigned tgt_long gp;
Eric Andersen9f16d612000-06-12 23:11:16 +0000398#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +0000399 /* Everything after here is extension. */
400 unsigned tgt_long persist_start;
401 unsigned tgt_long persist_end;
402 unsigned tgt_long can_unload;
403 unsigned tgt_long runsize;
Eric Andersen3b1a7442003-12-24 20:30:45 +0000404 const char *kallsyms_start; /* All symbols for kernel debugging */
405 const char *kallsyms_end;
406 const char *archdata_start; /* arch specific data for module */
407 const char *archdata_end;
408 const char *kernel_data; /* Reserved for kernel internal use */
Eric Andersen9f16d612000-06-12 23:11:16 +0000409};
410
Eric Andersencffd5022002-05-24 06:50:15 +0000411#ifdef ARCHDATAM
412#define ARCHDATA_SEC_NAME ARCHDATAM
413#else
Eric Andersen8ae319a2001-05-21 16:09:18 +0000414#define ARCHDATA_SEC_NAME "__archdata"
Eric Andersencffd5022002-05-24 06:50:15 +0000415#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +0000416#define KALLSYMS_SEC_NAME "__kallsyms"
417
418
Eric Andersen9f16d612000-06-12 23:11:16 +0000419struct new_module_info
420{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000421 unsigned long addr;
422 unsigned long size;
423 unsigned long flags;
424 long usecount;
Eric Andersen9f16d612000-06-12 23:11:16 +0000425};
426
427/* Bits of module.flags. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000428static const int NEW_MOD_RUNNING = 1;
429static const int NEW_MOD_DELETED = 2;
430static const int NEW_MOD_AUTOCLEAN = 4;
431static const int NEW_MOD_VISITED = 8;
432static const int NEW_MOD_USED_ONCE = 16;
Eric Andersen9f16d612000-06-12 23:11:16 +0000433
Eric Andersencb3b9b12004-06-22 11:50:52 +0000434int init_module(const char *name, const struct new_module *);
435int query_module(const char *name, int which, void *buf,
436 size_t bufsize, size_t *ret);
Eric Andersen9f16d612000-06-12 23:11:16 +0000437
438/* Values for query_module's which. */
439
Mark Whitley59ab0252001-01-23 22:30:04 +0000440static const int QM_MODULES = 1;
441static const int QM_DEPS = 2;
442static const int QM_REFS = 3;
443static const int QM_SYMBOLS = 4;
444static const int QM_INFO = 5;
Eric Andersen9f16d612000-06-12 23:11:16 +0000445
446/*======================================================================*/
447/* The system calls unchanged between 2.0 and 2.1. */
448
449unsigned long create_module(const char *, size_t);
450int delete_module(const char *);
451
452
453#endif /* module.h */
454
455//----------------------------------------------------------------------------
456//--------end of modutils module.h
457//----------------------------------------------------------------------------
458
459
460
461//----------------------------------------------------------------------------
462//--------modutils obj.h, lines 253-462
463//----------------------------------------------------------------------------
464
465/* Elf object file loading and relocation routines.
466 Copyright 1996, 1997 Linux International.
467
468 Contributed by Richard Henderson <rth@tamu.edu>
469
470 This file is part of the Linux modutils.
471
472 This program is free software; you can redistribute it and/or modify it
473 under the terms of the GNU General Public License as published by the
474 Free Software Foundation; either version 2 of the License, or (at your
475 option) any later version.
476
477 This program is distributed in the hope that it will be useful, but
478 WITHOUT ANY WARRANTY; without even the implied warranty of
479 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
480 General Public License for more details.
481
482 You should have received a copy of the GNU General Public License
483 along with this program; if not, write to the Free Software Foundation,
484 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
485
486
487#ifndef MODUTILS_OBJ_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000488static const int MODUTILS_OBJ_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000489
Mike Frysinger63654c12004-12-26 09:13:32 +0000490#ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000491
492/* The relocatable object is manipulated using elfin types. */
493
494#include <stdio.h>
495#include <elf.h>
Eric Andersenb1591d12002-04-12 00:28:59 +0000496#include <endian.h>
497
498#if __BYTE_ORDER == __LITTLE_ENDIAN
499#define ELFDATAM ELFDATA2LSB
500#elif __BYTE_ORDER == __BIG_ENDIAN
501#define ELFDATAM ELFDATA2MSB
502#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000503
Eric Andersen9f16d612000-06-12 23:11:16 +0000504#ifndef ElfW
505# if ELFCLASSM == ELFCLASS32
506# define ElfW(x) Elf32_ ## x
507# define ELFW(x) ELF32_ ## x
508# else
509# define ElfW(x) Elf64_ ## x
510# define ELFW(x) ELF64_ ## x
511# endif
512#endif
513
Eric Andersen85e5e722003-07-22 08:56:55 +0000514/* For some reason this is missing from some ancient C libraries.... */
Eric Andersen9f16d612000-06-12 23:11:16 +0000515#ifndef ELF32_ST_INFO
516# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
517#endif
518
519#ifndef ELF64_ST_INFO
520# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
521#endif
522
523struct obj_string_patch;
524struct obj_symbol_patch;
525
526struct obj_section
527{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000528 ElfW(Shdr) header;
529 const char *name;
530 char *contents;
531 struct obj_section *load_next;
532 int idx;
Eric Andersen9f16d612000-06-12 23:11:16 +0000533};
534
535struct obj_symbol
536{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000537 struct obj_symbol *next; /* hash table link */
538 const char *name;
539 unsigned long value;
540 unsigned long size;
541 int secidx; /* the defining section index/module */
542 int info;
543 int ksymidx; /* for export to the kernel symtab */
544 int referenced; /* actually used in the link */
Eric Andersen9f16d612000-06-12 23:11:16 +0000545};
546
547/* Hardcode the hash table size. We shouldn't be needing so many
548 symbols that we begin to degrade performance, and we get a big win
549 by giving the compiler a constant divisor. */
550
551#define HASH_BUCKETS 521
552
553struct obj_file
554{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000555 ElfW(Ehdr) header;
556 ElfW(Addr) baseaddr;
557 struct obj_section **sections;
558 struct obj_section *load_order;
559 struct obj_section **load_order_search_start;
560 struct obj_string_patch *string_patches;
561 struct obj_symbol_patch *symbol_patches;
562 int (*symbol_cmp)(const char *, const char *);
563 unsigned long (*symbol_hash)(const char *);
564 unsigned long local_symtab_size;
565 struct obj_symbol **local_symtab;
566 struct obj_symbol *symtab[HASH_BUCKETS];
Eric Andersen9f16d612000-06-12 23:11:16 +0000567};
568
569enum obj_reloc
570{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000571 obj_reloc_ok,
572 obj_reloc_overflow,
573 obj_reloc_dangerous,
574 obj_reloc_unhandled
Eric Andersen9f16d612000-06-12 23:11:16 +0000575};
576
577struct obj_string_patch
578{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000579 struct obj_string_patch *next;
580 int reloc_secidx;
581 ElfW(Addr) reloc_offset;
582 ElfW(Addr) string_offset;
Eric Andersen9f16d612000-06-12 23:11:16 +0000583};
584
585struct obj_symbol_patch
586{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000587 struct obj_symbol_patch *next;
588 int reloc_secidx;
589 ElfW(Addr) reloc_offset;
590 struct obj_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000591};
592
593
594/* Generic object manipulation routines. */
595
Eric Andersen044228d2001-07-17 01:12:36 +0000596static unsigned long obj_elf_hash(const char *);
Eric Andersen9f16d612000-06-12 23:11:16 +0000597
Eric Andersen044228d2001-07-17 01:12:36 +0000598static unsigned long obj_elf_hash_n(const char *, unsigned long len);
Eric Andersen9f16d612000-06-12 23:11:16 +0000599
Eric Andersen044228d2001-07-17 01:12:36 +0000600static struct obj_symbol *obj_find_symbol (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000601 const char *name);
602
Eric Andersen044228d2001-07-17 01:12:36 +0000603static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000604 struct obj_symbol *sym);
605
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000606#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen044228d2001-07-17 01:12:36 +0000607static void obj_set_symbol_compare(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000608 int (*cmp)(const char *, const char *),
609 unsigned long (*hash)(const char *));
Eric Andersenf672c9e2001-07-31 22:51:49 +0000610#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000611
Eric Andersen044228d2001-07-17 01:12:36 +0000612static struct obj_section *obj_find_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000613 const char *name);
614
Eric Andersen044228d2001-07-17 01:12:36 +0000615static void obj_insert_section_load_order (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000616 struct obj_section *sec);
617
Eric Andersen044228d2001-07-17 01:12:36 +0000618static struct obj_section *obj_create_alloced_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000619 const char *name,
620 unsigned long align,
621 unsigned long size);
622
Eric Andersen044228d2001-07-17 01:12:36 +0000623static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000624 const char *name,
625 unsigned long align,
626 unsigned long size);
627
Eric Andersen044228d2001-07-17 01:12:36 +0000628static void *obj_extend_section (struct obj_section *sec, unsigned long more);
Eric Andersen9f16d612000-06-12 23:11:16 +0000629
Eric Andersen044228d2001-07-17 01:12:36 +0000630static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000631 const char *string);
632
Eric Andersen044228d2001-07-17 01:12:36 +0000633static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000634 struct obj_symbol *sym);
635
Eric Andersen044228d2001-07-17 01:12:36 +0000636static int obj_check_undefineds(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000637
Eric Andersen044228d2001-07-17 01:12:36 +0000638static void obj_allocate_commons(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000639
Eric Andersen044228d2001-07-17 01:12:36 +0000640static unsigned long obj_load_size (struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000641
Eric Andersen044228d2001-07-17 01:12:36 +0000642static int obj_relocate (struct obj_file *f, ElfW(Addr) base);
Eric Andersen9f16d612000-06-12 23:11:16 +0000643
Eric Andersen044228d2001-07-17 01:12:36 +0000644static struct obj_file *obj_load(FILE *f, int loadprogbits);
Eric Andersen9f16d612000-06-12 23:11:16 +0000645
Eric Andersen044228d2001-07-17 01:12:36 +0000646static int obj_create_image (struct obj_file *f, char *image);
Eric Andersen9f16d612000-06-12 23:11:16 +0000647
648/* Architecture specific manipulation routines. */
649
Eric Andersen044228d2001-07-17 01:12:36 +0000650static struct obj_file *arch_new_file (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000651
Eric Andersen044228d2001-07-17 01:12:36 +0000652static struct obj_section *arch_new_section (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000653
Eric Andersen044228d2001-07-17 01:12:36 +0000654static struct obj_symbol *arch_new_symbol (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000655
Eric Andersen044228d2001-07-17 01:12:36 +0000656static enum obj_reloc arch_apply_relocation (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000657 struct obj_section *targsec,
658 struct obj_section *symsec,
659 struct obj_symbol *sym,
660 ElfW(RelM) *rel, ElfW(Addr) value);
661
Eric Andersencffd5022002-05-24 06:50:15 +0000662static void arch_create_got (struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000663
Glenn L McGrath759515c2003-08-30 06:00:33 +0000664static int obj_gpl_license(struct obj_file *f, const char **license);
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000665
Eric Andersen9f16d612000-06-12 23:11:16 +0000666#endif /* obj.h */
667//----------------------------------------------------------------------------
668//--------end of modutils obj.h
669//----------------------------------------------------------------------------
670
671
Miles Baderae28b042002-04-01 09:34:25 +0000672/* SPFX is always a string, so it can be concatenated to string constants. */
673#ifdef SYMBOL_PREFIX
674#define SPFX SYMBOL_PREFIX
675#else
676#define SPFX ""
677#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000678
Erik Andersen02104321999-12-17 18:57:34 +0000679
Erik Andersend387d011999-12-21 02:55:11 +0000680#define _PATH_MODULES "/lib/modules"
Mark Whitley59ab0252001-01-23 22:30:04 +0000681static const int STRVERSIONLEN = 32;
Erik Andersend387d011999-12-21 02:55:11 +0000682
Eric Andersen9f16d612000-06-12 23:11:16 +0000683/*======================================================================*/
684
Eric Andersen044228d2001-07-17 01:12:36 +0000685static int flag_force_load = 0;
686static int flag_autoclean = 0;
687static int flag_verbose = 0;
Eric Andersenb493dec2002-07-02 19:14:23 +0000688static int flag_quiet = 0;
Eric Andersen044228d2001-07-17 01:12:36 +0000689static int flag_export = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000690
691
692/*======================================================================*/
693
Eric Andersencffd5022002-05-24 06:50:15 +0000694#if defined(CONFIG_USE_LIST)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000695
Eric Andersencffd5022002-05-24 06:50:15 +0000696struct arch_list_entry
Eric Andersen21adca72000-12-06 18:18:26 +0000697{
Eric Andersencffd5022002-05-24 06:50:15 +0000698 struct arch_list_entry *next;
699 CONFIG_LIST_ARCHTYPE addend;
700 int offset;
701 int inited : 1;
Eric Andersen21adca72000-12-06 18:18:26 +0000702};
Eric Andersencffd5022002-05-24 06:50:15 +0000703
Eric Andersen21adca72000-12-06 18:18:26 +0000704#endif
705
Eric Andersencffd5022002-05-24 06:50:15 +0000706#if defined(CONFIG_USE_SINGLE)
707
708struct arch_single_entry
709{
Eric Andersen9f16d612000-06-12 23:11:16 +0000710 int offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000711 int inited : 1;
712 int allocated : 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000713};
Eric Andersencffd5022002-05-24 06:50:15 +0000714
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000715#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000716
Eric Andersen2bf658d2001-02-24 20:01:53 +0000717#if defined(__mips__)
718struct mips_hi16
719{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000720 struct mips_hi16 *next;
721 Elf32_Addr *addr;
722 Elf32_Addr value;
Eric Andersen2bf658d2001-02-24 20:01:53 +0000723};
724#endif
725
Eric Andersenfe4208f2000-09-24 03:44:29 +0000726struct arch_file {
Eric Andersen9f16d612000-06-12 23:11:16 +0000727 struct obj_file root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000728#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000729 struct obj_section *plt;
Eric Andersen21adca72000-12-06 18:18:26 +0000730#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000731#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000732 struct obj_section *got;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000733#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000734#if defined(__mips__)
735 struct mips_hi16 *mips_hi16_list;
736#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000737};
738
Eric Andersenfe4208f2000-09-24 03:44:29 +0000739struct arch_symbol {
Eric Andersen9f16d612000-06-12 23:11:16 +0000740 struct obj_symbol root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000741#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000742#if defined(CONFIG_USE_PLT_LIST)
743 struct arch_list_entry *pltent;
744#else
745 struct arch_single_entry pltent;
746#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000747#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000748#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000749 struct arch_single_entry gotent;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000750#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000751};
752
753
Eric Andersen9f16d612000-06-12 23:11:16 +0000754struct external_module {
755 const char *name;
756 ElfW(Addr) addr;
757 int used;
758 size_t nsyms;
759 struct new_module_symbol *syms;
760};
761
Eric Andersen044228d2001-07-17 01:12:36 +0000762static struct new_module_symbol *ksyms;
763static size_t nksyms;
Eric Andersen9f16d612000-06-12 23:11:16 +0000764
Eric Andersen044228d2001-07-17 01:12:36 +0000765static struct external_module *ext_modules;
766static int n_ext_modules;
767static int n_ext_modules_used;
Erik Andersen02104321999-12-17 18:57:34 +0000768extern int delete_module(const char *);
Eric Andersena2a978a2001-04-05 06:08:14 +0000769
Eric Andersen61f83052002-06-22 17:15:42 +0000770static char *m_filename;
Robert Griebld378c312002-07-19 00:05:54 +0000771static char *m_fullName;
Erik Andersen02104321999-12-17 18:57:34 +0000772
Eric Andersenfe4208f2000-09-24 03:44:29 +0000773
Erik Andersen02104321999-12-17 18:57:34 +0000774
Eric Andersen9f16d612000-06-12 23:11:16 +0000775/*======================================================================*/
Erik Andersen02104321999-12-17 18:57:34 +0000776
Eric Andersen9f16d612000-06-12 23:11:16 +0000777
Eric Andersen14d35432001-05-14 17:07:32 +0000778static int check_module_name_match(const char *filename, struct stat *statbuf,
779 void *userdata)
Eric Andersen9f16d612000-06-12 23:11:16 +0000780{
Eric Andersen14d35432001-05-14 17:07:32 +0000781 char *fullname = (char *) userdata;
Eric Andersen9f16d612000-06-12 23:11:16 +0000782
Eric Andersen14d35432001-05-14 17:07:32 +0000783 if (fullname[0] == '\0')
Erik Andersene49d5ec2000-02-08 19:58:47 +0000784 return (FALSE);
785 else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000786 char *tmp, *tmp1 = bb_xstrdup(filename);
787 tmp = bb_get_last_path_component(tmp1);
Eric Andersen14d35432001-05-14 17:07:32 +0000788 if (strcmp(tmp, fullname) == 0) {
789 free(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000790 /* Stop searching if we find a match */
Manuel Novoa III cad53642003-03-19 09:13:01 +0000791 m_filename = bb_xstrdup(filename);
Eric Andersen3f47c452004-04-06 11:56:26 +0000792 return (FALSE);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000793 }
Eric Andersen14d35432001-05-14 17:07:32 +0000794 free(tmp1);
Erik Andersend387d011999-12-21 02:55:11 +0000795 }
Eric Andersen3f47c452004-04-06 11:56:26 +0000796 return (TRUE);
Erik Andersend387d011999-12-21 02:55:11 +0000797}
798
Erik Andersen02104321999-12-17 18:57:34 +0000799
Eric Andersen9f16d612000-06-12 23:11:16 +0000800/*======================================================================*/
801
Eric Andersen044228d2001-07-17 01:12:36 +0000802static struct obj_file *arch_new_file(void)
Erik Andersen02104321999-12-17 18:57:34 +0000803{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000804 struct arch_file *f;
Eric Andersen9f16d612000-06-12 23:11:16 +0000805 f = xmalloc(sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000806
Eric Andersencffd5022002-05-24 06:50:15 +0000807 memset(f, 0, sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000808
Eric Andersen9f16d612000-06-12 23:11:16 +0000809 return &f->root;
810}
811
Eric Andersen044228d2001-07-17 01:12:36 +0000812static struct obj_section *arch_new_section(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000813{
814 return xmalloc(sizeof(struct obj_section));
815}
816
Eric Andersen044228d2001-07-17 01:12:36 +0000817static struct obj_symbol *arch_new_symbol(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000818{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000819 struct arch_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000820 sym = xmalloc(sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000821
Eric Andersencffd5022002-05-24 06:50:15 +0000822 memset(sym, 0, sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000823
Eric Andersen9f16d612000-06-12 23:11:16 +0000824 return &sym->root;
825}
Eric Andersenfe4208f2000-09-24 03:44:29 +0000826
Eric Andersen044228d2001-07-17 01:12:36 +0000827static enum obj_reloc
Eric Andersen9f16d612000-06-12 23:11:16 +0000828arch_apply_relocation(struct obj_file *f,
829 struct obj_section *targsec,
830 struct obj_section *symsec,
831 struct obj_symbol *sym,
Eric Andersen21adca72000-12-06 18:18:26 +0000832 ElfW(RelM) *rel, ElfW(Addr) v)
Eric Andersen9f16d612000-06-12 23:11:16 +0000833{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000834 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersencffd5022002-05-24 06:50:15 +0000835 enum obj_reloc ret = obj_reloc_ok;
Eric Andersen21adca72000-12-06 18:18:26 +0000836 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
837 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000838#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
839 struct arch_symbol *isym = (struct arch_symbol *) sym;
840#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000841#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000842 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000843#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000844#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000845 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
Eric Andersen21adca72000-12-06 18:18:26 +0000846 unsigned long *ip;
Eric Andersencffd5022002-05-24 06:50:15 +0000847#if defined(CONFIG_USE_PLT_LIST)
848 struct arch_list_entry *pe;
849#else
850 struct arch_single_entry *pe;
Eric Andersen21adca72000-12-06 18:18:26 +0000851#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000852#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000853
854 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersenfe4208f2000-09-24 03:44:29 +0000855
Eric Andersencffd5022002-05-24 06:50:15 +0000856
857#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +0000858 case R_ARM_NONE:
859 break;
Eric Andersen9f16d612000-06-12 23:11:16 +0000860
Eric Andersen3b1a7442003-12-24 20:30:45 +0000861 case R_ARM_ABS32:
862 *loc += v;
863 break;
Miles Baderae28b042002-04-01 09:34:25 +0000864
Eric Andersen3b1a7442003-12-24 20:30:45 +0000865 case R_ARM_GOT32:
866 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +0000867
Eric Andersen3b1a7442003-12-24 20:30:45 +0000868 case R_ARM_GOTPC:
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000869 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
870 * (which is .got) similar to branch,
Eric Andersen3b1a7442003-12-24 20:30:45 +0000871 * but is full 32 bits relative */
Eric Andersencffd5022002-05-24 06:50:15 +0000872
Eric Andersen3b1a7442003-12-24 20:30:45 +0000873 assert(got);
874 *loc += got - dot;
875 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000876
Eric Andersen3b1a7442003-12-24 20:30:45 +0000877 case R_ARM_PC24:
878 case R_ARM_PLT32:
879 goto bb_use_plt;
880
881 case R_ARM_GOTOFF: /* address relative to the got */
882 assert(got);
883 *loc += v - got;
884 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000885
Eric Andersenbf77f612003-01-23 06:02:39 +0000886#elif defined(__s390__)
Eric Andersen3b1a7442003-12-24 20:30:45 +0000887 case R_390_32:
888 *(unsigned int *) loc += v;
889 break;
890 case R_390_16:
891 *(unsigned short *) loc += v;
892 break;
893 case R_390_8:
894 *(unsigned char *) loc += v;
895 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000896
Eric Andersen3b1a7442003-12-24 20:30:45 +0000897 case R_390_PC32:
898 *(unsigned int *) loc += v - dot;
899 break;
900 case R_390_PC16DBL:
901 *(unsigned short *) loc += (v - dot) >> 1;
902 break;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000903 case R_390_PC16:
Eric Andersen3b1a7442003-12-24 20:30:45 +0000904 *(unsigned short *) loc += v - dot;
905 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000906
Eric Andersen3b1a7442003-12-24 20:30:45 +0000907 case R_390_PLT32:
908 case R_390_PLT16DBL:
909 /* find the plt entry and initialize it. */
910 assert(isym != NULL);
911 pe = (struct arch_single_entry *) &isym->pltent;
912 assert(pe->allocated);
913 if (pe->inited == 0) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000914 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
Eric Andersen3b1a7442003-12-24 20:30:45 +0000915 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
916 ip[1] = 0x100607f1;
917 if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
918 ip[2] = v - 2;
919 else
920 ip[2] = v;
921 pe->inited = 1;
922 }
Eric Andersenbf77f612003-01-23 06:02:39 +0000923
Eric Andersen3b1a7442003-12-24 20:30:45 +0000924 /* Insert relative distance to target. */
925 v = plt + pe->offset - dot;
926 if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32)
927 *(unsigned int *) loc = (unsigned int) v;
928 else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
929 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
930 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000931
Eric Andersen3b1a7442003-12-24 20:30:45 +0000932 case R_390_GLOB_DAT:
933 case R_390_JMP_SLOT:
934 *loc = v;
935 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000936
Eric Andersen3b1a7442003-12-24 20:30:45 +0000937 case R_390_RELATIVE:
938 *loc += f->baseaddr;
939 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000940
Eric Andersen3b1a7442003-12-24 20:30:45 +0000941 case R_390_GOTPC:
942 assert(got != 0);
943 *(unsigned long *) loc += got - dot;
944 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000945
Eric Andersen3b1a7442003-12-24 20:30:45 +0000946 case R_390_GOT12:
947 case R_390_GOT16:
948 case R_390_GOT32:
949 assert(isym != NULL);
950 assert(got != 0);
951 if (!isym->gotent.inited)
952 {
953 isym->gotent.inited = 1;
954 *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
955 }
956 if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12)
957 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
958 else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16)
959 *(unsigned short *) loc += isym->gotent.offset;
960 else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32)
961 *(unsigned int *) loc += isym->gotent.offset;
962 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000963
Eric Andersen951df202003-10-21 06:45:29 +0000964#ifndef R_390_GOTOFF32
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000965#define R_390_GOTOFF32 R_390_GOTOFF
Eric Andersen951df202003-10-21 06:45:29 +0000966#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +0000967 case R_390_GOTOFF32:
968 assert(got != 0);
969 *loc += v - got;
970 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000971
Eric Andersencffd5022002-05-24 06:50:15 +0000972#elif defined(__i386__)
973
Eric Andersen3b1a7442003-12-24 20:30:45 +0000974 case R_386_NONE:
975 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000976
Eric Andersen3b1a7442003-12-24 20:30:45 +0000977 case R_386_32:
978 *loc += v;
979 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000980
Eric Andersen3b1a7442003-12-24 20:30:45 +0000981 case R_386_PLT32:
982 case R_386_PC32:
983 *loc += v - dot;
984 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000985
Eric Andersen3b1a7442003-12-24 20:30:45 +0000986 case R_386_GLOB_DAT:
987 case R_386_JMP_SLOT:
988 *loc = v;
989 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000990
Eric Andersen3b1a7442003-12-24 20:30:45 +0000991 case R_386_RELATIVE:
992 *loc += f->baseaddr;
993 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000994
Eric Andersen3b1a7442003-12-24 20:30:45 +0000995 case R_386_GOTPC:
996 assert(got != 0);
997 *loc += got - dot;
998 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000999
Eric Andersen3b1a7442003-12-24 20:30:45 +00001000 case R_386_GOT32:
1001 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +00001002
Eric Andersen3b1a7442003-12-24 20:30:45 +00001003 case R_386_GOTOFF:
1004 assert(got != 0);
1005 *loc += v - got;
1006 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001007
1008#elif defined(__mc68000__)
1009
Eric Andersen3b1a7442003-12-24 20:30:45 +00001010 case R_68K_NONE:
1011 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001012
Eric Andersen3b1a7442003-12-24 20:30:45 +00001013 case R_68K_32:
1014 *loc += v;
1015 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001016
Eric Andersen3b1a7442003-12-24 20:30:45 +00001017 case R_68K_8:
1018 if (v > 0xff) {
1019 ret = obj_reloc_overflow;
1020 }
1021 *(char *)loc = v;
1022 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001023
Eric Andersen3b1a7442003-12-24 20:30:45 +00001024 case R_68K_16:
1025 if (v > 0xffff) {
1026 ret = obj_reloc_overflow;
1027 }
1028 *(short *)loc = v;
1029 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001030
Eric Andersen3b1a7442003-12-24 20:30:45 +00001031 case R_68K_PC8:
1032 v -= dot;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001033 if ((Elf32_Sword)v > 0x7f ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00001034 (Elf32_Sword)v < -(Elf32_Sword)0x80) {
1035 ret = obj_reloc_overflow;
1036 }
1037 *(char *)loc = v;
1038 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001039
Eric Andersen3b1a7442003-12-24 20:30:45 +00001040 case R_68K_PC16:
1041 v -= dot;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001042 if ((Elf32_Sword)v > 0x7fff ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00001043 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1044 ret = obj_reloc_overflow;
1045 }
1046 *(short *)loc = v;
1047 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001048
Eric Andersen3b1a7442003-12-24 20:30:45 +00001049 case R_68K_PC32:
1050 *(int *)loc = v - dot;
1051 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001052
Eric Andersen3b1a7442003-12-24 20:30:45 +00001053 case R_68K_GLOB_DAT:
1054 case R_68K_JMP_SLOT:
1055 *loc = v;
1056 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001057
Eric Andersen3b1a7442003-12-24 20:30:45 +00001058 case R_68K_RELATIVE:
1059 *(int *)loc += f->baseaddr;
1060 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001061
Eric Andersen3b1a7442003-12-24 20:30:45 +00001062 case R_68K_GOT32:
1063 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +00001064
Eric Andersen16451a02004-03-19 12:16:18 +00001065#ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001066 case R_68K_GOTOFF:
1067 assert(got != 0);
1068 *loc += v - got;
1069 break;
Eric Andersen16451a02004-03-19 12:16:18 +00001070#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001071
1072#elif defined(__mips__)
1073
Eric Andersen3b1a7442003-12-24 20:30:45 +00001074 case R_MIPS_NONE:
1075 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001076
Eric Andersen3b1a7442003-12-24 20:30:45 +00001077 case R_MIPS_32:
1078 *loc += v;
1079 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001080
Eric Andersen3b1a7442003-12-24 20:30:45 +00001081 case R_MIPS_26:
1082 if (v % 4)
1083 ret = obj_reloc_dangerous;
1084 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1085 ret = obj_reloc_overflow;
1086 *loc =
1087 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1088 0x03ffffff);
1089 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001090
Eric Andersen3b1a7442003-12-24 20:30:45 +00001091 case R_MIPS_HI16:
1092 {
1093 struct mips_hi16 *n;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001094
Eric Andersen3b1a7442003-12-24 20:30:45 +00001095 /* We cannot relocate this one now because we don't know the value
1096 of the carry we need to add. Save the information, and let LO16
1097 do the actual relocation. */
1098 n = (struct mips_hi16 *) xmalloc(sizeof *n);
1099 n->addr = loc;
1100 n->value = v;
1101 n->next = ifile->mips_hi16_list;
1102 ifile->mips_hi16_list = n;
1103 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001104 }
1105
Eric Andersen3b1a7442003-12-24 20:30:45 +00001106 case R_MIPS_LO16:
1107 {
1108 unsigned long insnlo = *loc;
1109 Elf32_Addr val, vallo;
1110
1111 /* Sign extend the addend we extract from the lo insn. */
1112 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1113
1114 if (ifile->mips_hi16_list != NULL) {
1115 struct mips_hi16 *l;
1116
1117 l = ifile->mips_hi16_list;
1118 while (l != NULL) {
1119 struct mips_hi16 *next;
1120 unsigned long insn;
1121
1122 /* The value for the HI16 had best be the same. */
1123 assert(v == l->value);
1124
1125 /* Do the HI16 relocation. Note that we actually don't
1126 need to know anything about the LO16 itself, except where
1127 to find the low 16 bits of the addend needed by the LO16. */
1128 insn = *l->addr;
1129 val =
1130 ((insn & 0xffff) << 16) +
1131 vallo;
1132 val += v;
1133
1134 /* Account for the sign extension that will happen in the
1135 low bits. */
1136 val =
1137 ((val >> 16) +
1138 ((val & 0x8000) !=
1139 0)) & 0xffff;
1140
1141 insn = (insn & ~0xffff) | val;
1142 *l->addr = insn;
1143
1144 next = l->next;
1145 free(l);
1146 l = next;
1147 }
1148
1149 ifile->mips_hi16_list = NULL;
1150 }
1151
1152 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1153 val = v + vallo;
1154 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1155 *loc = insnlo;
1156 break;
1157 }
Eric Andersen2bf658d2001-02-24 20:01:53 +00001158
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001159#elif defined(__powerpc__)
Eric Andersencffd5022002-05-24 06:50:15 +00001160
Eric Andersen3b1a7442003-12-24 20:30:45 +00001161 case R_PPC_ADDR16_HA:
1162 *(unsigned short *)loc = (v + 0x8000) >> 16;
1163 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001164
Eric Andersen3b1a7442003-12-24 20:30:45 +00001165 case R_PPC_ADDR16_HI:
1166 *(unsigned short *)loc = v >> 16;
1167 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001168
Eric Andersen3b1a7442003-12-24 20:30:45 +00001169 case R_PPC_ADDR16_LO:
1170 *(unsigned short *)loc = v;
1171 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001172
Eric Andersen3b1a7442003-12-24 20:30:45 +00001173 case R_PPC_REL24:
1174 goto bb_use_plt;
Eric Andersencffd5022002-05-24 06:50:15 +00001175
Eric Andersen3b1a7442003-12-24 20:30:45 +00001176 case R_PPC_REL32:
1177 *loc = v - dot;
1178 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001179
Eric Andersen3b1a7442003-12-24 20:30:45 +00001180 case R_PPC_ADDR32:
1181 *loc = v;
1182 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001183
1184#elif defined(__sh__)
1185
Eric Andersen3b1a7442003-12-24 20:30:45 +00001186 case R_SH_NONE:
1187 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001188
Eric Andersen3b1a7442003-12-24 20:30:45 +00001189 case R_SH_DIR32:
1190 *loc += v;
1191 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001192
Eric Andersen3b1a7442003-12-24 20:30:45 +00001193 case R_SH_REL32:
1194 *loc += v - dot;
1195 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001196
Eric Andersen3b1a7442003-12-24 20:30:45 +00001197 case R_SH_PLT32:
1198 *loc = v - dot;
1199 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001200
Eric Andersen3b1a7442003-12-24 20:30:45 +00001201 case R_SH_GLOB_DAT:
1202 case R_SH_JMP_SLOT:
1203 *loc = v;
1204 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001205
Eric Andersen3b1a7442003-12-24 20:30:45 +00001206 case R_SH_RELATIVE:
1207 *loc = f->baseaddr + rel->r_addend;
1208 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001209
Eric Andersen3b1a7442003-12-24 20:30:45 +00001210 case R_SH_GOTPC:
1211 assert(got != 0);
1212 *loc = got - dot + rel->r_addend;
1213 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001214
Eric Andersen3b1a7442003-12-24 20:30:45 +00001215 case R_SH_GOT32:
1216 goto bb_use_got;
1217
1218 case R_SH_GOTOFF:
1219 assert(got != 0);
1220 *loc = v - got;
1221 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001222
Eric Andersenbf833552003-08-13 19:56:33 +00001223#if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001224 case R_SH_IMM_MEDLOW16:
1225 case R_SH_IMM_LOW16:
1226 {
1227 Elf32_Addr word;
Eric Andersenbf833552003-08-13 19:56:33 +00001228
Eric Andersen3b1a7442003-12-24 20:30:45 +00001229 if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1230 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001231
Eric Andersen3b1a7442003-12-24 20:30:45 +00001232 /*
1233 * movi and shori have the format:
1234 *
1235 * | op | imm | reg | reserved |
1236 * 31..26 25..10 9.. 4 3 .. 0
1237 *
1238 * so we simply mask and or in imm.
1239 */
1240 word = *loc & ~0x3fffc00;
1241 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001242
Eric Andersen3b1a7442003-12-24 20:30:45 +00001243 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001244
Eric Andersen3b1a7442003-12-24 20:30:45 +00001245 break;
1246 }
Eric Andersenbf833552003-08-13 19:56:33 +00001247
Eric Andersen3b1a7442003-12-24 20:30:45 +00001248 case R_SH_IMM_MEDLOW16_PCREL:
1249 case R_SH_IMM_LOW16_PCREL:
1250 {
1251 Elf32_Addr word;
Eric Andersenbf833552003-08-13 19:56:33 +00001252
Eric Andersen3b1a7442003-12-24 20:30:45 +00001253 word = *loc & ~0x3fffc00;
Eric Andersenbf833552003-08-13 19:56:33 +00001254
Eric Andersen3b1a7442003-12-24 20:30:45 +00001255 v -= dot;
Eric Andersenbf833552003-08-13 19:56:33 +00001256
Eric Andersen3b1a7442003-12-24 20:30:45 +00001257 if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1258 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001259
Eric Andersen3b1a7442003-12-24 20:30:45 +00001260 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001261
Eric Andersen3b1a7442003-12-24 20:30:45 +00001262 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001263
Eric Andersen3b1a7442003-12-24 20:30:45 +00001264 break;
1265 }
Eric Andersenbf833552003-08-13 19:56:33 +00001266#endif /* __SH5__ */
1267#endif /* __sh__ */
Eric Andersen9f16d612000-06-12 23:11:16 +00001268
Eric Andersen3b1a7442003-12-24 20:30:45 +00001269 default:
1270 printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
1271 ret = obj_reloc_unhandled;
1272 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001273
1274#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001275 case R_V850_NONE:
1276 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001277
Eric Andersen3b1a7442003-12-24 20:30:45 +00001278 case R_V850_32:
1279 /* We write two shorts instead of a long because even
1280 32-bit insns only need half-word alignment, but
1281 32-bit data needs to be long-word aligned. */
1282 v += ((unsigned short *)loc)[0];
1283 v += ((unsigned short *)loc)[1] << 16;
1284 ((unsigned short *)loc)[0] = v & 0xffff;
1285 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1286 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001287
Eric Andersen3b1a7442003-12-24 20:30:45 +00001288 case R_V850_22_PCREL:
1289 goto bb_use_plt;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001290#endif
1291
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001292#if defined (__cris__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001293 case R_CRIS_NONE:
1294 break;
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001295
Eric Andersen3b1a7442003-12-24 20:30:45 +00001296 case R_CRIS_32:
1297 /* CRIS keeps the relocation value in the r_addend field and
1298 * should not use whats in *loc at all
1299 */
1300 *loc = v;
1301 break;
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001302#endif
1303
Eric Andersena6f6a952004-05-26 12:06:38 +00001304#if defined(__H8300H__) || defined(__H8300S__)
Eric Andersenee70fa52004-05-26 11:38:46 +00001305 case R_H8_DIR24R8:
1306 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
1307 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
1308 break;
1309 case R_H8_DIR24A8:
1310 *loc += v;
1311 break;
1312 case R_H8_DIR32:
1313 case R_H8_DIR32A16:
1314 *loc += v;
1315 break;
1316 case R_H8_PCREL16:
1317 v -= dot + 2;
1318 if ((Elf32_Sword)v > 0x7fff ||
1319 (Elf32_Sword)v < -(Elf32_Sword)0x8000)
1320 ret = obj_reloc_overflow;
1321 else
1322 *(unsigned short *)loc = v;
1323 break;
1324 case R_H8_PCREL8:
1325 v -= dot + 1;
1326 if ((Elf32_Sword)v > 0x7f ||
1327 (Elf32_Sword)v < -(Elf32_Sword)0x80)
1328 ret = obj_reloc_overflow;
1329 else
1330 *(unsigned char *)loc = v;
1331 break;
1332#endif
1333
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001334#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001335
Eric Andersen3b1a7442003-12-24 20:30:45 +00001336bb_use_plt:
Eric Andersencffd5022002-05-24 06:50:15 +00001337
Eric Andersen3b1a7442003-12-24 20:30:45 +00001338 /* find the plt entry and initialize it if necessary */
1339 assert(isym != NULL);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001340
Eric Andersencffd5022002-05-24 06:50:15 +00001341#if defined(CONFIG_USE_PLT_LIST)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001342 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1343 pe = pe->next;
1344 assert(pe != NULL);
Eric Andersencffd5022002-05-24 06:50:15 +00001345#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001346 pe = &isym->pltent;
Eric Andersencffd5022002-05-24 06:50:15 +00001347#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001348
Eric Andersen3b1a7442003-12-24 20:30:45 +00001349 if (! pe->inited) {
1350 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001351
Eric Andersen3b1a7442003-12-24 20:30:45 +00001352 /* generate some machine code */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001353
1354#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001355 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1356 ip[1] = v; /* sym@ */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001357#endif
1358#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001359 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1360 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1361 ip[2] = 0x7d6903a6; /* mtctr r11 */
1362 ip[3] = 0x4e800420; /* bctr */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001363#endif
Miles Baderae28b042002-04-01 09:34:25 +00001364#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001365 /* We have to trash a register, so we assume that any control
1366 transfer more than 21-bits away must be a function call
1367 (so we can use a call-clobbered register). */
1368 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1369 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
Miles Baderae28b042002-04-01 09:34:25 +00001370#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001371 pe->inited = 1;
1372 }
Eric Andersen21adca72000-12-06 18:18:26 +00001373
Eric Andersen3b1a7442003-12-24 20:30:45 +00001374 /* relative distance to target */
1375 v -= dot;
1376 /* if the target is too far away.... */
Miles Baderae28b042002-04-01 09:34:25 +00001377#if defined (__arm__) || defined (__powerpc__)
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001378 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
Miles Baderae28b042002-04-01 09:34:25 +00001379#elif defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001380 if ((Elf32_Sword)v > 0x1fffff || (Elf32_Sword)v < (Elf32_Sword)-0x200000)
Miles Baderae28b042002-04-01 09:34:25 +00001381#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001382 /* go via the plt */
1383 v = plt + pe->offset - dot;
Miles Baderae28b042002-04-01 09:34:25 +00001384
1385#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001386 if (v & 1)
Miles Baderae28b042002-04-01 09:34:25 +00001387#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001388 if (v & 3)
Miles Baderae28b042002-04-01 09:34:25 +00001389#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001390 ret = obj_reloc_dangerous;
Eric Andersen21adca72000-12-06 18:18:26 +00001391
Eric Andersen3b1a7442003-12-24 20:30:45 +00001392 /* merge the offset into the instruction. */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001393#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001394 /* Convert to words. */
1395 v >>= 2;
Eric Andersen21adca72000-12-06 18:18:26 +00001396
Eric Andersen3b1a7442003-12-24 20:30:45 +00001397 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
Eric Andersenfe4208f2000-09-24 03:44:29 +00001398#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001399#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001400 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001401#endif
Miles Baderae28b042002-04-01 09:34:25 +00001402#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001403 /* We write two shorts instead of a long because even 32-bit insns
1404 only need half-word alignment, but the 32-bit data write needs
1405 to be long-word aligned. */
1406 ((unsigned short *)loc)[0] =
1407 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1408 | ((v >> 16) & 0x3f); /* offs high part */
1409 ((unsigned short *)loc)[1] =
1410 (v & 0xffff); /* offs low part */
Miles Baderae28b042002-04-01 09:34:25 +00001411#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001412 break;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001413#endif /* CONFIG_USE_PLT_ENTRIES */
Eric Andersenfe4208f2000-09-24 03:44:29 +00001414
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001415#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001416bb_use_got:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001417
Eric Andersen3b1a7442003-12-24 20:30:45 +00001418 assert(isym != NULL);
1419 /* needs an entry in the .got: set it, once */
1420 if (!isym->gotent.inited) {
1421 isym->gotent.inited = 1;
1422 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1423 }
1424 /* make the reloc with_respect_to_.got */
Eric Andersen21adca72000-12-06 18:18:26 +00001425#if defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001426 *loc += isym->gotent.offset + rel->r_addend;
Eric Andersenb4a26e62001-06-19 15:00:52 +00001427#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001428 *loc += isym->gotent.offset;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001429#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001430 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001431
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001432#endif /* CONFIG_USE_GOT_ENTRIES */
Eric Andersen9f16d612000-06-12 23:11:16 +00001433 }
1434
1435 return ret;
1436}
1437
Eric Andersencffd5022002-05-24 06:50:15 +00001438
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001439#if defined(CONFIG_USE_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001440
1441static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1442 int offset, int size)
1443{
1444 struct arch_list_entry *pe;
1445
1446 for (pe = *list; pe != NULL; pe = pe->next) {
1447 if (pe->addend == rel->r_addend) {
1448 break;
1449 }
1450 }
1451
1452 if (pe == NULL) {
1453 pe = xmalloc(sizeof(struct arch_list_entry));
1454 pe->next = *list;
1455 pe->addend = rel->r_addend;
1456 pe->offset = offset;
1457 pe->inited = 0;
1458 *list = pe;
1459 return size;
1460 }
1461 return 0;
1462}
1463
1464#endif
1465
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001466#if defined(CONFIG_USE_SINGLE)
Eric Andersencffd5022002-05-24 06:50:15 +00001467
1468static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
1469 int offset, int size)
1470{
1471 if (single->allocated == 0) {
1472 single->allocated = 1;
1473 single->offset = offset;
1474 single->inited = 0;
1475 return size;
1476 }
1477 return 0;
1478}
1479
1480#endif
1481
1482#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
1483
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001484static struct obj_section *arch_xsect_init(struct obj_file *f, char *name,
Eric Andersencffd5022002-05-24 06:50:15 +00001485 int offset, int size)
1486{
1487 struct obj_section *myrelsec = obj_find_section(f, name);
1488
1489 if (offset == 0) {
1490 offset += size;
1491 }
1492
1493 if (myrelsec) {
1494 obj_extend_section(myrelsec, offset);
1495 } else {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001496 myrelsec = obj_create_alloced_section(f, name,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001497 size, offset);
Eric Andersencffd5022002-05-24 06:50:15 +00001498 assert(myrelsec);
1499 }
1500
1501 return myrelsec;
1502}
1503
1504#endif
1505
1506static void arch_create_got(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00001507{
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001508#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001509 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001510 int i;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001511#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001512 int got_offset = 0, got_needed = 0, got_allocate;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001513#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001514#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001515 int plt_offset = 0, plt_needed = 0, plt_allocate;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001516#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001517 struct obj_section *relsec, *symsec, *strsec;
Eric Andersen21adca72000-12-06 18:18:26 +00001518 ElfW(RelM) *rel, *relend;
1519 ElfW(Sym) *symtab, *extsym;
1520 const char *strtab, *name;
1521 struct arch_symbol *intsym;
Eric Andersen9f16d612000-06-12 23:11:16 +00001522
Eric Andersen21adca72000-12-06 18:18:26 +00001523 for (i = 0; i < f->header.e_shnum; ++i) {
1524 relsec = f->sections[i];
1525 if (relsec->header.sh_type != SHT_RELM)
Eric Andersen9f16d612000-06-12 23:11:16 +00001526 continue;
1527
Eric Andersen21adca72000-12-06 18:18:26 +00001528 symsec = f->sections[relsec->header.sh_link];
1529 strsec = f->sections[symsec->header.sh_link];
Eric Andersen9f16d612000-06-12 23:11:16 +00001530
Eric Andersen21adca72000-12-06 18:18:26 +00001531 rel = (ElfW(RelM) *) relsec->contents;
1532 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1533 symtab = (ElfW(Sym) *) symsec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00001534 strtab = (const char *) strsec->contents;
1535
1536 for (; rel < relend; ++rel) {
Eric Andersen21adca72000-12-06 18:18:26 +00001537 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
Eric Andersen9f16d612000-06-12 23:11:16 +00001538
Eric Andersencffd5022002-05-24 06:50:15 +00001539#if defined(CONFIG_USE_GOT_ENTRIES)
1540 got_allocate = 0;
1541#endif
1542#if defined(CONFIG_USE_PLT_ENTRIES)
1543 plt_allocate = 0;
1544#endif
1545
Eric Andersen9f16d612000-06-12 23:11:16 +00001546 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersen21adca72000-12-06 18:18:26 +00001547#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001548 case R_ARM_PC24:
1549 case R_ARM_PLT32:
1550 plt_allocate = 1;
1551 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001552
Eric Andersen3b1a7442003-12-24 20:30:45 +00001553 case R_ARM_GOTOFF:
1554 case R_ARM_GOTPC:
1555 got_needed = 1;
1556 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001557
Eric Andersen3b1a7442003-12-24 20:30:45 +00001558 case R_ARM_GOT32:
1559 got_allocate = 1;
1560 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001561
Eric Andersen21adca72000-12-06 18:18:26 +00001562#elif defined(__i386__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001563 case R_386_GOTPC:
1564 case R_386_GOTOFF:
1565 got_needed = 1;
1566 continue;
Eric Andersen21adca72000-12-06 18:18:26 +00001567
Eric Andersen3b1a7442003-12-24 20:30:45 +00001568 case R_386_GOT32:
1569 got_allocate = 1;
1570 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001571
1572#elif defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001573 case R_PPC_REL24:
1574 plt_allocate = 1;
1575 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001576
1577#elif defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001578 case R_68K_GOT32:
1579 got_allocate = 1;
1580 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001581
Eric Andersen16451a02004-03-19 12:16:18 +00001582#ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001583 case R_68K_GOTOFF:
1584 got_needed = 1;
1585 continue;
Eric Andersen16451a02004-03-19 12:16:18 +00001586#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001587
1588#elif defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001589 case R_SH_GOT32:
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001590 got_allocate = 1;
Eric Andersen3b1a7442003-12-24 20:30:45 +00001591 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001592
Eric Andersen3b1a7442003-12-24 20:30:45 +00001593 case R_SH_GOTPC:
1594 case R_SH_GOTOFF:
1595 got_needed = 1;
1596 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001597
1598#elif defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001599 case R_V850_22_PCREL:
1600 plt_needed = 1;
1601 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001602
1603#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001604 default:
1605 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00001606 }
1607
Eric Andersen21adca72000-12-06 18:18:26 +00001608 if (extsym->st_name != 0) {
Eric Andersen9f16d612000-06-12 23:11:16 +00001609 name = strtab + extsym->st_name;
Eric Andersen21adca72000-12-06 18:18:26 +00001610 } else {
Eric Andersen9f16d612000-06-12 23:11:16 +00001611 name = f->sections[extsym->st_shndx]->name;
Eric Andersen21adca72000-12-06 18:18:26 +00001612 }
1613 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001614#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001615 if (got_allocate) {
1616 got_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001617 rel, &intsym->gotent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001618 got_offset, CONFIG_GOT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001619
1620 got_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001621 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001622#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001623#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001624 if (plt_allocate) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001625#if defined(CONFIG_USE_PLT_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001626 plt_offset += arch_list_add(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001627 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001628 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001629#else
1630 plt_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001631 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001632 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001633#endif
1634 plt_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001635 }
1636#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001637 }
Miles Baderae28b042002-04-01 09:34:25 +00001638 }
Eric Andersen21adca72000-12-06 18:18:26 +00001639
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001640#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001641 if (got_needed) {
1642 ifile->got = arch_xsect_init(f, ".got", got_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001643 CONFIG_GOT_ENTRY_SIZE);
Eric Andersen9f16d612000-06-12 23:11:16 +00001644 }
Eric Andersen21adca72000-12-06 18:18:26 +00001645#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001646
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001647#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001648 if (plt_needed) {
1649 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001650 CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001651 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001652#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001653
1654#endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */
Eric Andersen9f16d612000-06-12 23:11:16 +00001655}
1656
Eric Andersen9f16d612000-06-12 23:11:16 +00001657/*======================================================================*/
1658
1659/* Standard ELF hash function. */
Eric Andersen044228d2001-07-17 01:12:36 +00001660static inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
Eric Andersen9f16d612000-06-12 23:11:16 +00001661{
1662 unsigned long h = 0;
1663 unsigned long g;
1664 unsigned char ch;
1665
1666 while (n > 0) {
1667 ch = *name++;
1668 h = (h << 4) + ch;
1669 if ((g = (h & 0xf0000000)) != 0) {
1670 h ^= g >> 24;
1671 h &= ~g;
1672 }
1673 n--;
1674 }
1675 return h;
1676}
1677
Eric Andersen044228d2001-07-17 01:12:36 +00001678static unsigned long obj_elf_hash(const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001679{
1680 return obj_elf_hash_n(name, strlen(name));
1681}
1682
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001683#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00001684/* String comparison for non-co-versioned kernel and module. */
1685
1686static int ncv_strcmp(const char *a, const char *b)
1687{
1688 size_t alen = strlen(a), blen = strlen(b);
1689
1690 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1691 return strncmp(a, b, alen);
1692 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1693 return strncmp(a, b, blen);
1694 else
1695 return strcmp(a, b);
1696}
1697
1698/* String hashing for non-co-versioned kernel and module. Here
1699 we are simply forced to drop the crc from the hash. */
1700
1701static unsigned long ncv_symbol_hash(const char *str)
1702{
1703 size_t len = strlen(str);
1704 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1705 len -= 10;
1706 return obj_elf_hash_n(str, len);
1707}
1708
Eric Andersen044228d2001-07-17 01:12:36 +00001709static void
Eric Andersen9f16d612000-06-12 23:11:16 +00001710obj_set_symbol_compare(struct obj_file *f,
1711 int (*cmp) (const char *, const char *),
1712 unsigned long (*hash) (const char *))
1713{
1714 if (cmp)
1715 f->symbol_cmp = cmp;
1716 if (hash) {
1717 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1718 int i;
1719
1720 f->symbol_hash = hash;
1721
1722 memcpy(tmptab, f->symtab, sizeof(tmptab));
1723 memset(f->symtab, 0, sizeof(f->symtab));
1724
1725 for (i = 0; i < HASH_BUCKETS; ++i)
1726 for (sym = tmptab[i]; sym; sym = next) {
1727 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1728 next = sym->next;
1729 sym->next = f->symtab[h];
1730 f->symtab[h] = sym;
1731 }
1732 }
1733}
1734
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001735#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00001736
Eric Andersen044228d2001-07-17 01:12:36 +00001737static struct obj_symbol *
1738obj_add_symbol(struct obj_file *f, const char *name,
Eric Andersen9f16d612000-06-12 23:11:16 +00001739 unsigned long symidx, int info,
1740 int secidx, ElfW(Addr) value,
1741 unsigned long size)
1742{
1743 struct obj_symbol *sym;
1744 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1745 int n_type = ELFW(ST_TYPE) (info);
1746 int n_binding = ELFW(ST_BIND) (info);
1747
1748 for (sym = f->symtab[hash]; sym; sym = sym->next)
1749 if (f->symbol_cmp(sym->name, name) == 0) {
1750 int o_secidx = sym->secidx;
1751 int o_info = sym->info;
1752 int o_type = ELFW(ST_TYPE) (o_info);
1753 int o_binding = ELFW(ST_BIND) (o_info);
1754
1755 /* A redefinition! Is it legal? */
1756
1757 if (secidx == SHN_UNDEF)
1758 return sym;
1759 else if (o_secidx == SHN_UNDEF)
1760 goto found;
1761 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1762 /* Cope with local and global symbols of the same name
1763 in the same object file, as might have been created
1764 by ld -r. The only reason locals are now seen at this
1765 level at all is so that we can do semi-sensible things
1766 with parameters. */
1767
1768 struct obj_symbol *nsym, **p;
1769
1770 nsym = arch_new_symbol();
1771 nsym->next = sym->next;
1772 nsym->ksymidx = -1;
1773
1774 /* Excise the old (local) symbol from the hash chain. */
1775 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1776 continue;
1777 *p = sym = nsym;
1778 goto found;
1779 } else if (n_binding == STB_LOCAL) {
1780 /* Another symbol of the same name has already been defined.
1781 Just add this to the local table. */
1782 sym = arch_new_symbol();
1783 sym->next = NULL;
1784 sym->ksymidx = -1;
1785 f->local_symtab[symidx] = sym;
1786 goto found;
1787 } else if (n_binding == STB_WEAK)
1788 return sym;
1789 else if (o_binding == STB_WEAK)
1790 goto found;
1791 /* Don't unify COMMON symbols with object types the programmer
1792 doesn't expect. */
1793 else if (secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00001794 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00001795 return sym;
1796 else if (o_secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00001797 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00001798 goto found;
1799 else {
1800 /* Don't report an error if the symbol is coming from
1801 the kernel or some external module. */
1802 if (secidx <= SHN_HIRESERVE)
Manuel Novoa III cad53642003-03-19 09:13:01 +00001803 bb_error_msg("%s multiply defined", name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001804 return sym;
1805 }
1806 }
1807
1808 /* Completely new symbol. */
1809 sym = arch_new_symbol();
1810 sym->next = f->symtab[hash];
1811 f->symtab[hash] = sym;
1812 sym->ksymidx = -1;
1813
Eric Andersen66ca9482001-06-28 21:36:06 +00001814 if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) {
1815 if (symidx >= f->local_symtab_size)
Manuel Novoa III cad53642003-03-19 09:13:01 +00001816 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
Eric Andersen66ca9482001-06-28 21:36:06 +00001817 name, (long) symidx, (long) f->local_symtab_size);
1818 else
1819 f->local_symtab[symidx] = sym;
1820 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001821
Eric Andersen3b1a7442003-12-24 20:30:45 +00001822found:
Eric Andersen9f16d612000-06-12 23:11:16 +00001823 sym->name = name;
1824 sym->value = value;
1825 sym->size = size;
1826 sym->secidx = secidx;
1827 sym->info = info;
1828
1829 return sym;
1830}
1831
Eric Andersen044228d2001-07-17 01:12:36 +00001832static struct obj_symbol *
1833obj_find_symbol(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001834{
1835 struct obj_symbol *sym;
1836 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1837
1838 for (sym = f->symtab[hash]; sym; sym = sym->next)
1839 if (f->symbol_cmp(sym->name, name) == 0)
1840 return sym;
1841
1842 return NULL;
1843}
1844
Eric Andersen044228d2001-07-17 01:12:36 +00001845static ElfW(Addr)
Eric Andersen9f16d612000-06-12 23:11:16 +00001846 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1847{
1848 if (sym) {
1849 if (sym->secidx >= SHN_LORESERVE)
1850 return sym->value;
1851
1852 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1853 } else {
1854 /* As a special case, a NULL sym has value zero. */
1855 return 0;
1856 }
1857}
1858
Eric Andersen044228d2001-07-17 01:12:36 +00001859static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001860{
1861 int i, n = f->header.e_shnum;
1862
1863 for (i = 0; i < n; ++i)
1864 if (strcmp(f->sections[i]->name, name) == 0)
1865 return f->sections[i];
1866
1867 return NULL;
1868}
1869
1870static int obj_load_order_prio(struct obj_section *a)
1871{
1872 unsigned long af, ac;
1873
1874 af = a->header.sh_flags;
1875
1876 ac = 0;
1877 if (a->name[0] != '.' || strlen(a->name) != 10 ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00001878 strcmp(a->name + 5, ".init"))
Eric Andersen9f16d612000-06-12 23:11:16 +00001879 ac |= 32;
1880 if (af & SHF_ALLOC)
1881 ac |= 16;
1882 if (!(af & SHF_WRITE))
1883 ac |= 8;
1884 if (af & SHF_EXECINSTR)
1885 ac |= 4;
1886 if (a->header.sh_type != SHT_NOBITS)
1887 ac |= 2;
1888
1889 return ac;
1890}
1891
Eric Andersen044228d2001-07-17 01:12:36 +00001892static void
Eric Andersen9f16d612000-06-12 23:11:16 +00001893obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1894{
1895 struct obj_section **p;
1896 int prio = obj_load_order_prio(sec);
1897 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1898 if (obj_load_order_prio(*p) < prio)
1899 break;
1900 sec->load_next = *p;
1901 *p = sec;
1902}
1903
Eric Andersen044228d2001-07-17 01:12:36 +00001904static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001905 const char *name,
1906 unsigned long align,
1907 unsigned long size)
1908{
1909 int newidx = f->header.e_shnum++;
1910 struct obj_section *sec;
1911
1912 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1913 f->sections[newidx] = sec = arch_new_section();
1914
1915 memset(sec, 0, sizeof(*sec));
1916 sec->header.sh_type = SHT_PROGBITS;
1917 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1918 sec->header.sh_size = size;
1919 sec->header.sh_addralign = align;
1920 sec->name = name;
1921 sec->idx = newidx;
1922 if (size)
1923 sec->contents = xmalloc(size);
1924
1925 obj_insert_section_load_order(f, sec);
1926
1927 return sec;
1928}
1929
Eric Andersen044228d2001-07-17 01:12:36 +00001930static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001931 const char *name,
1932 unsigned long align,
1933 unsigned long size)
1934{
1935 int newidx = f->header.e_shnum++;
1936 struct obj_section *sec;
1937
1938 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1939 f->sections[newidx] = sec = arch_new_section();
1940
1941 memset(sec, 0, sizeof(*sec));
1942 sec->header.sh_type = SHT_PROGBITS;
1943 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1944 sec->header.sh_size = size;
1945 sec->header.sh_addralign = align;
1946 sec->name = name;
1947 sec->idx = newidx;
1948 if (size)
1949 sec->contents = xmalloc(size);
1950
1951 sec->load_next = f->load_order;
1952 f->load_order = sec;
1953 if (f->load_order_search_start == &f->load_order)
1954 f->load_order_search_start = &sec->load_next;
1955
1956 return sec;
1957}
1958
Eric Andersen044228d2001-07-17 01:12:36 +00001959static void *obj_extend_section(struct obj_section *sec, unsigned long more)
Eric Andersen9f16d612000-06-12 23:11:16 +00001960{
1961 unsigned long oldsize = sec->header.sh_size;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001962 if (more) {
Eric Andersen7f3b86e2001-04-26 19:29:58 +00001963 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1964 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001965 return sec->contents + oldsize;
1966}
1967
1968
Eric Andersen9f16d612000-06-12 23:11:16 +00001969/* Conditionally add the symbols from the given symbol set to the
1970 new module. */
1971
1972static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00001973add_symbols_from( struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001974 int idx, struct new_module_symbol *syms, size_t nsyms)
1975{
1976 struct new_module_symbol *s;
1977 size_t i;
1978 int used = 0;
Miles Baderae28b042002-04-01 09:34:25 +00001979#ifdef SYMBOL_PREFIX
1980 char *name_buf = 0;
1981 size_t name_alloced_size = 0;
1982#endif
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001983#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
1984 int gpl;
Eric Andersen9f16d612000-06-12 23:11:16 +00001985
Glenn L McGrath759515c2003-08-30 06:00:33 +00001986 gpl = obj_gpl_license(f, NULL) == 0;
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001987#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001988 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
Miles Baderae28b042002-04-01 09:34:25 +00001989 /* Only add symbols that are already marked external.
1990 If we override locals we may cause problems for
1991 argument initialization. We will also create a false
1992 dependency on the module. */
Eric Andersen9f16d612000-06-12 23:11:16 +00001993 struct obj_symbol *sym;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00001994 char *name;
Eric Andersen9f16d612000-06-12 23:11:16 +00001995
Glenn L McGrath759515c2003-08-30 06:00:33 +00001996 /* GPL licensed modules can use symbols exported with
1997 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
1998 * exported names. Non-GPL modules never see any GPLONLY_
1999 * symbols so they cannot fudge it by adding the prefix on
2000 * their references.
2001 */
2002 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002003#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Glenn L McGrath759515c2003-08-30 06:00:33 +00002004 if (gpl)
Eric Andersenb225e2a2004-08-28 00:43:07 +00002005 s->name += 8;
Glenn L McGrath759515c2003-08-30 06:00:33 +00002006 else
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00002007#endif
Glenn L McGrath759515c2003-08-30 06:00:33 +00002008 continue;
2009 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00002010 name = (char *)s->name;
Glenn L McGrath759515c2003-08-30 06:00:33 +00002011
Miles Baderae28b042002-04-01 09:34:25 +00002012#ifdef SYMBOL_PREFIX
2013 /* Prepend SYMBOL_PREFIX to the symbol's name (the
2014 kernel exports `C names', but module object files
2015 reference `linker names'). */
2016 size_t extra = sizeof SYMBOL_PREFIX;
2017 size_t name_size = strlen (name) + extra;
2018 if (name_size > name_alloced_size) {
2019 name_alloced_size = name_size * 2;
2020 name_buf = alloca (name_alloced_size);
2021 }
2022 strcpy (name_buf, SYMBOL_PREFIX);
2023 strcpy (name_buf + extra - 1, name);
2024 name = name_buf;
2025#endif /* SYMBOL_PREFIX */
2026
2027 sym = obj_find_symbol(f, name);
2028 if (sym && !(ELFW(ST_BIND) (sym->info) == STB_LOCAL)) {
2029#ifdef SYMBOL_PREFIX
2030 /* Put NAME_BUF into more permanent storage. */
2031 name = xmalloc (name_size);
2032 strcpy (name, name_buf);
2033#endif
2034 sym = obj_add_symbol(f, name, -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002035 ELFW(ST_INFO) (STB_GLOBAL,
2036 STT_NOTYPE),
2037 idx, s->value, 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00002038 /* Did our symbol just get installed? If so, mark the
2039 module as "used". */
2040 if (sym->secidx == idx)
2041 used = 1;
2042 }
2043 }
2044
2045 return used;
2046}
2047
2048static void add_kernel_symbols(struct obj_file *f)
2049{
2050 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00002051 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002052
2053 /* Add module symbols first. */
2054
2055 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
2056 if (m->nsyms
Eric Andersen3b1a7442003-12-24 20:30:45 +00002057 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
2058 m->nsyms)) m->used = 1, ++nused;
Eric Andersen9f16d612000-06-12 23:11:16 +00002059
2060 n_ext_modules_used = nused;
2061
2062 /* And finally the symbols from the kernel proper. */
2063
2064 if (nksyms)
2065 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2066}
2067
2068static char *get_modinfo_value(struct obj_file *f, const char *key)
2069{
2070 struct obj_section *sec;
2071 char *p, *v, *n, *ep;
2072 size_t klen = strlen(key);
2073
2074 sec = obj_find_section(f, ".modinfo");
2075 if (sec == NULL)
2076 return NULL;
2077 p = sec->contents;
2078 ep = p + sec->header.sh_size;
2079 while (p < ep) {
2080 v = strchr(p, '=');
2081 n = strchr(p, '\0');
2082 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002083 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002084 return v + 1;
2085 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002086 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002087 return n;
2088 }
2089 p = n + 1;
2090 }
2091
2092 return NULL;
2093}
2094
2095
2096/*======================================================================*/
Eric Andersen9f16d612000-06-12 23:11:16 +00002097/* Functions relating to module loading after 2.1.18. */
2098
2099static int
2100new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2101{
2102 while (argc > 0) {
Miles Baderae28b042002-04-01 09:34:25 +00002103 char *p, *q, *key, *sym_name;
Eric Andersen9f16d612000-06-12 23:11:16 +00002104 struct obj_symbol *sym;
2105 char *contents, *loc;
2106 int min, max, n;
2107
2108 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00002109 if ((q = strchr(p, '=')) == NULL) {
2110 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00002111 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002112 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002113
2114 key = alloca(q - p + 6);
2115 memcpy(key, "parm_", 5);
2116 memcpy(key + 5, p, q - p);
2117 key[q - p + 5] = 0;
2118
2119 p = get_modinfo_value(f, key);
2120 key += 5;
2121 if (p == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002122 bb_error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002123 return 0;
2124 }
2125
Miles Baderae28b042002-04-01 09:34:25 +00002126#ifdef SYMBOL_PREFIX
2127 sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);
2128 strcpy (sym_name, SYMBOL_PREFIX);
2129 strcat (sym_name, key);
2130#else
2131 sym_name = key;
2132#endif
2133 sym = obj_find_symbol(f, sym_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002134
2135 /* Also check that the parameter was not resolved from the kernel. */
2136 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002137 bb_error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002138 return 0;
2139 }
2140
2141 if (isdigit(*p)) {
2142 min = strtoul(p, &p, 10);
2143 if (*p == '-')
2144 max = strtoul(p + 1, &p, 10);
2145 else
2146 max = min;
2147 } else
2148 min = max = 1;
2149
2150 contents = f->sections[sym->secidx]->contents;
2151 loc = contents + sym->value;
2152 n = (*++q != '\0');
2153
2154 while (1) {
2155 if ((*p == 's') || (*p == 'c')) {
2156 char *str;
2157
2158 /* Do C quoting if we begin with a ", else slurp the lot. */
2159 if (*q == '"') {
2160 char *r;
2161
2162 str = alloca(strlen(q));
2163 for (r = str, q++; *q != '"'; ++q, ++r) {
2164 if (*q == '\0') {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002165 bb_error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002166 key);
2167 return 0;
2168 } else if (*q == '\\')
2169 switch (*++q) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002170 case 'a':
2171 *r = '\a';
2172 break;
2173 case 'b':
2174 *r = '\b';
2175 break;
2176 case 'e':
2177 *r = '\033';
2178 break;
2179 case 'f':
2180 *r = '\f';
2181 break;
2182 case 'n':
2183 *r = '\n';
2184 break;
2185 case 'r':
2186 *r = '\r';
2187 break;
2188 case 't':
2189 *r = '\t';
2190 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002191
Eric Andersen3b1a7442003-12-24 20:30:45 +00002192 case '0':
2193 case '1':
2194 case '2':
2195 case '3':
2196 case '4':
2197 case '5':
2198 case '6':
2199 case '7':
2200 {
2201 int c = *q - '0';
2202 if (q[1] >= '0' && q[1] <= '7') {
Eric Andersen9f16d612000-06-12 23:11:16 +00002203 c = (c * 8) + *++q - '0';
Eric Andersen3b1a7442003-12-24 20:30:45 +00002204 if (q[1] >= '0' && q[1] <= '7')
2205 c = (c * 8) + *++q - '0';
2206 }
2207 *r = c;
Eric Andersen9f16d612000-06-12 23:11:16 +00002208 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002209 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002210
Eric Andersen3b1a7442003-12-24 20:30:45 +00002211 default:
2212 *r = *q;
2213 break;
2214 } else
Eric Andersen9f16d612000-06-12 23:11:16 +00002215 *r = *q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002216 }
2217 *r = '\0';
2218 ++q;
2219 } else {
2220 char *r;
2221
2222 /* In this case, the string is not quoted. We will break
2223 it using the coma (like for ints). If the user wants to
2224 include comas in a string, he just has to quote it */
2225
2226 /* Search the next coma */
2227 r = strchr(q, ',');
2228
2229 /* Found ? */
2230 if (r != (char *) NULL) {
2231 /* Recopy the current field */
2232 str = alloca(r - q + 1);
2233 memcpy(str, q, r - q);
2234
Eric Andersenaff114c2004-04-14 17:51:38 +00002235 /* I don't know if it is useful, as the previous case
2236 doesn't nul terminate the string ??? */
Eric Andersen9f16d612000-06-12 23:11:16 +00002237 str[r - q] = '\0';
2238
2239 /* Keep next fields */
2240 q = r;
2241 } else {
2242 /* last string */
2243 str = q;
2244 q = "";
2245 }
2246 }
2247
2248 if (*p == 's') {
2249 /* Normal string */
2250 obj_string_patch(f, sym->secidx, loc - contents, str);
2251 loc += tgt_sizeof_char_p;
2252 } else {
2253 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002254 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002255
2256 /* Get the size of each member */
2257 /* Probably we should do that outside the loop ? */
2258 if (!isdigit(*(p + 1))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002259 bb_error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002260 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002261 return 0;
2262 }
2263 charssize = strtoul(p + 1, (char **) NULL, 10);
2264
2265 /* Check length */
2266 if (strlen(str) >= charssize) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002267 bb_error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002268 charssize - 1);
2269 return 0;
2270 }
2271
2272 /* Copy to location */
2273 strcpy((char *) loc, str);
2274 loc += charssize;
2275 }
2276 } else {
2277 long v = strtoul(q, &q, 0);
2278 switch (*p) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002279 case 'b':
2280 *loc++ = v;
2281 break;
2282 case 'h':
2283 *(short *) loc = v;
2284 loc += tgt_sizeof_short;
2285 break;
2286 case 'i':
2287 *(int *) loc = v;
2288 loc += tgt_sizeof_int;
2289 break;
2290 case 'l':
2291 *(long *) loc = v;
2292 loc += tgt_sizeof_long;
2293 break;
2294
2295 default:
2296 bb_error_msg("unknown parameter type '%c' for %s", *p, key);
2297 return 0;
2298 }
2299 }
2300
2301retry_end_of_value:
2302 switch (*q) {
2303 case '\0':
2304 goto end_of_arg;
2305
2306 case ' ':
2307 case '\t':
2308 case '\n':
2309 case '\r':
2310 ++q;
2311 goto retry_end_of_value;
2312
2313 case ',':
2314 if (++n > max) {
2315 bb_error_msg("too many values for %s (max %d)", key, max);
2316 return 0;
2317 }
2318 ++q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002319 break;
2320
2321 default:
Eric Andersen3b1a7442003-12-24 20:30:45 +00002322 bb_error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002323 return 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002324 }
2325 }
2326
Eric Andersen3b1a7442003-12-24 20:30:45 +00002327end_of_arg:
Eric Andersen9f16d612000-06-12 23:11:16 +00002328 if (n < min) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002329 bb_error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002330 return 0;
2331 }
2332
2333 argc--, argv++;
2334 }
2335
2336 return 1;
2337}
2338
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002339#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00002340static int new_is_module_checksummed(struct obj_file *f)
2341{
2342 const char *p = get_modinfo_value(f, "using_checksums");
2343 if (p)
2344 return atoi(p);
2345 else
2346 return 0;
2347}
2348
2349/* Get the module's kernel version in the canonical integer form. */
2350
2351static int
2352new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2353{
2354 char *p, *q;
2355 int a, b, c;
2356
2357 p = get_modinfo_value(f, "kernel_version");
2358 if (p == NULL)
2359 return -1;
Eric Andersen2d342152002-06-18 05:16:25 +00002360 safe_strncpy(str, p, STRVERSIONLEN);
Eric Andersen9f16d612000-06-12 23:11:16 +00002361
2362 a = strtoul(p, &p, 10);
2363 if (*p != '.')
2364 return -1;
2365 b = strtoul(p + 1, &p, 10);
2366 if (*p != '.')
2367 return -1;
2368 c = strtoul(p + 1, &q, 10);
2369 if (p + 1 == q)
2370 return -1;
2371
2372 return a << 16 | b << 8 | c;
2373}
2374
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002375#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00002376
2377
Eric Andersen9f16d612000-06-12 23:11:16 +00002378/* Fetch the loaded modules, and all currently exported symbols. */
2379
2380static int new_get_kernel_symbols(void)
2381{
2382 char *module_names, *mn;
2383 struct external_module *modules, *m;
2384 struct new_module_symbol *syms, *s;
2385 size_t ret, bufsize, nmod, nsyms, i, j;
2386
2387 /* Collect the loaded modules. */
2388
2389 module_names = xmalloc(bufsize = 256);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002390retry_modules_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002391 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002392 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002393 module_names = xrealloc(module_names, bufsize = ret);
2394 goto retry_modules_load;
2395 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002396 bb_perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002397 return 0;
2398 }
2399
2400 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002401
2402 /* Collect the modules' symbols. */
2403
Mark Whitley94fd4802001-03-12 23:08:34 +00002404 if (nmod){
2405 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2406 memset(modules, 0, nmod * sizeof(*modules));
2407 for (i = 0, mn = module_names, m = modules;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002408 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
Mark Whitley94fd4802001-03-12 23:08:34 +00002409 struct new_module_info info;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002410
Mark Whitley94fd4802001-03-12 23:08:34 +00002411 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2412 if (errno == ENOENT) {
2413 /* The module was removed out from underneath us. */
2414 continue;
2415 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002416 bb_perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002417 return 0;
2418 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002419
Mark Whitley94fd4802001-03-12 23:08:34 +00002420 syms = xmalloc(bufsize = 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002421retry_mod_sym_load:
Mark Whitley94fd4802001-03-12 23:08:34 +00002422 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2423 switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002424 case ENOSPC:
2425 syms = xrealloc(syms, bufsize = ret);
2426 goto retry_mod_sym_load;
2427 case ENOENT:
2428 /* The module was removed out from underneath us. */
2429 continue;
2430 default:
2431 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn);
2432 return 0;
Mark Whitley94fd4802001-03-12 23:08:34 +00002433 }
2434 }
2435 nsyms = ret;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002436
Mark Whitley94fd4802001-03-12 23:08:34 +00002437 m->name = mn;
2438 m->addr = info.addr;
2439 m->nsyms = nsyms;
2440 m->syms = syms;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002441
Mark Whitley94fd4802001-03-12 23:08:34 +00002442 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2443 s->name += (unsigned long) syms;
2444 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002445 }
2446 }
2447
2448 /* Collect the kernel's symbols. */
2449
2450 syms = xmalloc(bufsize = 16 * 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002451retry_kern_sym_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002452 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002453 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002454 syms = xrealloc(syms, bufsize = ret);
2455 goto retry_kern_sym_load;
2456 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002457 bb_perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002458 return 0;
2459 }
2460 nksyms = nsyms = ret;
2461 ksyms = syms;
2462
2463 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2464 s->name += (unsigned long) syms;
2465 }
2466 return 1;
2467}
2468
2469
2470/* Return the kernel symbol checksum version, or zero if not used. */
2471
2472static int new_is_kernel_checksummed(void)
2473{
2474 struct new_module_symbol *s;
2475 size_t i;
2476
2477 /* Using_Versions is not the first symbol, but it should be in there. */
2478
2479 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2480 if (strcmp((char *) s->name, "Using_Versions") == 0)
2481 return s->value;
2482
2483 return 0;
2484}
2485
2486
2487static int new_create_this_module(struct obj_file *f, const char *m_name)
2488{
2489 struct obj_section *sec;
2490
2491 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002492 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002493 memset(sec->contents, 0, sizeof(struct new_module));
2494
Miles Baderae28b042002-04-01 09:34:25 +00002495 obj_add_symbol(f, SPFX "__this_module", -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002496 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2497 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002498
2499 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
Eric Andersen3b1a7442003-12-24 20:30:45 +00002500 m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002501
2502 return 1;
2503}
2504
Eric Andersen889dd202003-01-23 04:48:34 +00002505#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2506/* add an entry to the __ksymtab section, creating it if necessary */
2507static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2508{
2509 struct obj_section *sec;
2510 ElfW(Addr) ofs;
2511
2512 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2513 * If __ksymtab is defined but not marked alloc, x out the first character
2514 * (no obj_delete routine) and create a new __ksymtab with the correct
2515 * characteristics.
2516 */
2517 sec = obj_find_section(f, "__ksymtab");
2518 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2519 *((char *)(sec->name)) = 'x'; /* override const */
2520 sec = NULL;
2521 }
2522 if (!sec)
2523 sec = obj_create_alloced_section(f, "__ksymtab",
Eric Andersen3b1a7442003-12-24 20:30:45 +00002524 tgt_sizeof_void_p, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00002525 if (!sec)
2526 return;
2527 sec->header.sh_flags |= SHF_ALLOC;
2528 sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might
Eric Andersen3b1a7442003-12-24 20:30:45 +00002529 be byte-aligned */
Eric Andersen889dd202003-01-23 04:48:34 +00002530 ofs = sec->header.sh_size;
2531 obj_symbol_patch(f, sec->idx, ofs, sym);
2532 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2533 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2534}
2535#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
Eric Andersen9f16d612000-06-12 23:11:16 +00002536
2537static int new_create_module_ksymtab(struct obj_file *f)
2538{
2539 struct obj_section *sec;
2540 int i;
2541
2542 /* We must always add the module references. */
2543
2544 if (n_ext_modules_used) {
2545 struct new_module_ref *dep;
2546 struct obj_symbol *tm;
2547
2548 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002549 (sizeof(struct new_module_ref)
2550 * n_ext_modules_used));
Eric Andersen9f16d612000-06-12 23:11:16 +00002551 if (!sec)
2552 return 0;
2553
Miles Baderae28b042002-04-01 09:34:25 +00002554 tm = obj_find_symbol(f, SPFX "__this_module");
Eric Andersen9f16d612000-06-12 23:11:16 +00002555 dep = (struct new_module_ref *) sec->contents;
2556 for (i = 0; i < n_ext_modules; ++i)
2557 if (ext_modules[i].used) {
2558 dep->dep = ext_modules[i].addr;
2559 obj_symbol_patch(f, sec->idx,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002560 (char *) &dep->ref - sec->contents, tm);
Eric Andersen9f16d612000-06-12 23:11:16 +00002561 dep->next_ref = 0;
2562 ++dep;
2563 }
2564 }
2565
2566 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2567 size_t nsyms;
2568 int *loaded;
2569
2570 sec =
2571 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002572 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00002573
2574 /* We don't want to export symbols residing in sections that
2575 aren't loaded. There are a number of these created so that
2576 we make sure certain module options don't appear twice. */
2577
2578 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2579 while (--i >= 0)
2580 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2581
2582 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2583 struct obj_symbol *sym;
2584 for (sym = f->symtab[i]; sym; sym = sym->next)
2585 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
Eric Andersen3b1a7442003-12-24 20:30:45 +00002586 && sym->secidx <= SHN_HIRESERVE
2587 && (sym->secidx >= SHN_LORESERVE
2588 || loaded[sym->secidx])) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002589 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2590
2591 obj_symbol_patch(f, sec->idx, ofs, sym);
2592 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002593 sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002594
2595 nsyms++;
2596 }
2597 }
2598
2599 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2600 }
2601
2602 return 1;
2603}
2604
2605
2606static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00002607new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
Eric Andersen9f16d612000-06-12 23:11:16 +00002608{
2609 struct new_module *module;
2610 struct obj_section *sec;
2611 void *image;
2612 int ret;
2613 tgt_long m_addr;
2614
2615 sec = obj_find_section(f, ".this");
Eric Andersenc7bda1c2004-03-15 08:29:22 +00002616 if (!sec || !sec->contents) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002617 bb_perror_msg_and_die("corrupt module %s?",m_name);
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002618 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002619 module = (struct new_module *) sec->contents;
2620 m_addr = sec->header.sh_addr;
2621
2622 module->size_of_struct = sizeof(*module);
2623 module->size = m_size;
2624 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2625
2626 sec = obj_find_section(f, "__ksymtab");
2627 if (sec && sec->header.sh_size) {
2628 module->syms = sec->header.sh_addr;
2629 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2630 }
2631
2632 if (n_ext_modules_used) {
2633 sec = obj_find_section(f, ".kmodtab");
2634 module->deps = sec->header.sh_addr;
2635 module->ndeps = n_ext_modules_used;
2636 }
2637
2638 module->init =
Miles Baderae28b042002-04-01 09:34:25 +00002639 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002640 module->cleanup =
Miles Baderae28b042002-04-01 09:34:25 +00002641 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002642
2643 sec = obj_find_section(f, "__ex_table");
2644 if (sec) {
2645 module->ex_table_start = sec->header.sh_addr;
2646 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2647 }
2648
2649 sec = obj_find_section(f, ".text.init");
2650 if (sec) {
2651 module->runsize = sec->header.sh_addr - m_addr;
2652 }
2653 sec = obj_find_section(f, ".data.init");
2654 if (sec) {
2655 if (!module->runsize ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002656 module->runsize > sec->header.sh_addr - m_addr)
2657 module->runsize = sec->header.sh_addr - m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00002658 }
Eric Andersen8ae319a2001-05-21 16:09:18 +00002659 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2660 if (sec && sec->header.sh_size) {
2661 module->archdata_start = (void*)sec->header.sh_addr;
2662 module->archdata_end = module->archdata_start + sec->header.sh_size;
2663 }
2664 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2665 if (sec && sec->header.sh_size) {
2666 module->kallsyms_start = (void*)sec->header.sh_addr;
2667 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2668 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002669
Eric Andersen9f16d612000-06-12 23:11:16 +00002670 /* Whew! All of the initialization is complete. Collect the final
2671 module image and give it to the kernel. */
2672
2673 image = xmalloc(m_size);
2674 obj_create_image(f, image);
2675
Eric Andersencb3b9b12004-06-22 11:50:52 +00002676 ret = init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002677 if (ret)
Manuel Novoa III cad53642003-03-19 09:13:01 +00002678 bb_perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002679
2680 free(image);
2681
2682 return ret == 0;
2683}
2684
Eric Andersen9f16d612000-06-12 23:11:16 +00002685
2686/*======================================================================*/
2687
Eric Andersen044228d2001-07-17 01:12:36 +00002688static int
Eric Andersen9f16d612000-06-12 23:11:16 +00002689obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2690 const char *string)
2691{
2692 struct obj_string_patch *p;
2693 struct obj_section *strsec;
2694 size_t len = strlen(string) + 1;
2695 char *loc;
2696
2697 p = xmalloc(sizeof(*p));
2698 p->next = f->string_patches;
2699 p->reloc_secidx = secidx;
2700 p->reloc_offset = offset;
2701 f->string_patches = p;
2702
2703 strsec = obj_find_section(f, ".kstrtab");
2704 if (strsec == NULL) {
2705 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2706 p->string_offset = 0;
2707 loc = strsec->contents;
2708 } else {
2709 p->string_offset = strsec->header.sh_size;
2710 loc = obj_extend_section(strsec, len);
2711 }
2712 memcpy(loc, string, len);
2713
2714 return 1;
2715}
2716
Eric Andersen044228d2001-07-17 01:12:36 +00002717static int
Eric Andersen9f16d612000-06-12 23:11:16 +00002718obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2719 struct obj_symbol *sym)
2720{
2721 struct obj_symbol_patch *p;
2722
2723 p = xmalloc(sizeof(*p));
2724 p->next = f->symbol_patches;
2725 p->reloc_secidx = secidx;
2726 p->reloc_offset = offset;
2727 p->sym = sym;
2728 f->symbol_patches = p;
2729
2730 return 1;
2731}
2732
Eric Andersen044228d2001-07-17 01:12:36 +00002733static int obj_check_undefineds(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002734{
2735 unsigned long i;
2736 int ret = 1;
2737
2738 for (i = 0; i < HASH_BUCKETS; ++i) {
2739 struct obj_symbol *sym;
2740 for (sym = f->symtab[i]; sym; sym = sym->next)
2741 if (sym->secidx == SHN_UNDEF) {
2742 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2743 sym->secidx = SHN_ABS;
2744 sym->value = 0;
2745 } else {
Eric Andersenb493dec2002-07-02 19:14:23 +00002746 if (!flag_quiet) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002747 bb_error_msg("unresolved symbol %s", sym->name);
Eric Andersenb493dec2002-07-02 19:14:23 +00002748 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002749 ret = 0;
2750 }
2751 }
2752 }
2753
2754 return ret;
2755}
2756
Eric Andersen044228d2001-07-17 01:12:36 +00002757static void obj_allocate_commons(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002758{
2759 struct common_entry {
2760 struct common_entry *next;
2761 struct obj_symbol *sym;
2762 } *common_head = NULL;
2763
2764 unsigned long i;
2765
2766 for (i = 0; i < HASH_BUCKETS; ++i) {
2767 struct obj_symbol *sym;
2768 for (sym = f->symtab[i]; sym; sym = sym->next)
2769 if (sym->secidx == SHN_COMMON) {
2770 /* Collect all COMMON symbols and sort them by size so as to
2771 minimize space wasted by alignment requirements. */
2772 {
2773 struct common_entry **p, *n;
2774 for (p = &common_head; *p; p = &(*p)->next)
2775 if (sym->size <= (*p)->sym->size)
2776 break;
2777
2778 n = alloca(sizeof(*n));
2779 n->next = *p;
2780 n->sym = sym;
2781 *p = n;
2782 }
2783 }
2784 }
2785
2786 for (i = 1; i < f->local_symtab_size; ++i) {
2787 struct obj_symbol *sym = f->local_symtab[i];
2788 if (sym && sym->secidx == SHN_COMMON) {
2789 struct common_entry **p, *n;
2790 for (p = &common_head; *p; p = &(*p)->next)
2791 if (sym == (*p)->sym)
2792 break;
2793 else if (sym->size < (*p)->sym->size) {
2794 n = alloca(sizeof(*n));
2795 n->next = *p;
2796 n->sym = sym;
2797 *p = n;
2798 break;
2799 }
2800 }
2801 }
2802
2803 if (common_head) {
2804 /* Find the bss section. */
2805 for (i = 0; i < f->header.e_shnum; ++i)
2806 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2807 break;
2808
2809 /* If for some reason there hadn't been one, create one. */
2810 if (i == f->header.e_shnum) {
2811 struct obj_section *sec;
2812
2813 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2814 f->sections[i] = sec = arch_new_section();
2815 f->header.e_shnum = i + 1;
2816
2817 memset(sec, 0, sizeof(*sec));
2818 sec->header.sh_type = SHT_PROGBITS;
2819 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2820 sec->name = ".bss";
2821 sec->idx = i;
2822 }
2823
2824 /* Allocate the COMMONS. */
2825 {
2826 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2827 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2828 struct common_entry *c;
2829
2830 for (c = common_head; c; c = c->next) {
2831 ElfW(Addr) align = c->sym->value;
2832
2833 if (align > max_align)
2834 max_align = align;
2835 if (bss_size & (align - 1))
2836 bss_size = (bss_size | (align - 1)) + 1;
2837
2838 c->sym->secidx = i;
2839 c->sym->value = bss_size;
2840
2841 bss_size += c->sym->size;
2842 }
2843
2844 f->sections[i]->header.sh_size = bss_size;
2845 f->sections[i]->header.sh_addralign = max_align;
2846 }
2847 }
2848
2849 /* For the sake of patch relocation and parameter initialization,
2850 allocate zeroed data for NOBITS sections now. Note that after
2851 this we cannot assume NOBITS are really empty. */
2852 for (i = 0; i < f->header.e_shnum; ++i) {
2853 struct obj_section *s = f->sections[i];
2854 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00002855 if (s->header.sh_size != 0)
Eric Andersen3b1a7442003-12-24 20:30:45 +00002856 s->contents = memset(xmalloc(s->header.sh_size),
2857 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00002858 else
2859 s->contents = NULL;
2860
Eric Andersen9f16d612000-06-12 23:11:16 +00002861 s->header.sh_type = SHT_PROGBITS;
2862 }
2863 }
2864}
2865
Eric Andersen044228d2001-07-17 01:12:36 +00002866static unsigned long obj_load_size(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002867{
2868 unsigned long dot = 0;
2869 struct obj_section *sec;
2870
2871 /* Finalize the positions of the sections relative to one another. */
2872
2873 for (sec = f->load_order; sec; sec = sec->load_next) {
2874 ElfW(Addr) align;
2875
2876 align = sec->header.sh_addralign;
2877 if (align && (dot & (align - 1)))
2878 dot = (dot | (align - 1)) + 1;
2879
2880 sec->header.sh_addr = dot;
2881 dot += sec->header.sh_size;
2882 }
2883
2884 return dot;
2885}
2886
Eric Andersen044228d2001-07-17 01:12:36 +00002887static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
Eric Andersen9f16d612000-06-12 23:11:16 +00002888{
2889 int i, n = f->header.e_shnum;
2890 int ret = 1;
2891
2892 /* Finalize the addresses of the sections. */
2893
2894 f->baseaddr = base;
2895 for (i = 0; i < n; ++i)
2896 f->sections[i]->header.sh_addr += base;
2897
2898 /* And iterate over all of the relocations. */
2899
2900 for (i = 0; i < n; ++i) {
2901 struct obj_section *relsec, *symsec, *targsec, *strsec;
2902 ElfW(RelM) * rel, *relend;
2903 ElfW(Sym) * symtab;
2904 const char *strtab;
2905
2906 relsec = f->sections[i];
2907 if (relsec->header.sh_type != SHT_RELM)
2908 continue;
2909
2910 symsec = f->sections[relsec->header.sh_link];
2911 targsec = f->sections[relsec->header.sh_info];
2912 strsec = f->sections[symsec->header.sh_link];
2913
2914 rel = (ElfW(RelM) *) relsec->contents;
2915 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2916 symtab = (ElfW(Sym) *) symsec->contents;
2917 strtab = (const char *) strsec->contents;
2918
2919 for (; rel < relend; ++rel) {
2920 ElfW(Addr) value = 0;
2921 struct obj_symbol *intsym = NULL;
2922 unsigned long symndx;
2923 ElfW(Sym) * extsym = 0;
2924 const char *errmsg;
2925
2926 /* Attempt to find a value to use for this relocation. */
2927
2928 symndx = ELFW(R_SYM) (rel->r_info);
2929 if (symndx) {
2930 /* Note we've already checked for undefined symbols. */
2931
2932 extsym = &symtab[symndx];
2933 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2934 /* Local symbols we look up in the local table to be sure
2935 we get the one that is really intended. */
2936 intsym = f->local_symtab[symndx];
2937 } else {
2938 /* Others we look up in the hash table. */
2939 const char *name;
2940 if (extsym->st_name)
2941 name = strtab + extsym->st_name;
2942 else
2943 name = f->sections[extsym->st_shndx]->name;
2944 intsym = obj_find_symbol(f, name);
2945 }
2946
2947 value = obj_symbol_final_value(f, intsym);
2948 intsym->referenced = 1;
2949 }
2950#if SHT_RELM == SHT_RELA
2951#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2952 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2953 if (!extsym || !extsym->st_name ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002954 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
Eric Andersen9f16d612000-06-12 23:11:16 +00002955#endif
2956 value += rel->r_addend;
2957#endif
2958
2959 /* Do it! */
2960 switch (arch_apply_relocation
2961 (f, targsec, symsec, intsym, rel, value)) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002962 case obj_reloc_ok:
2963 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002964
Eric Andersen3b1a7442003-12-24 20:30:45 +00002965 case obj_reloc_overflow:
2966 errmsg = "Relocation overflow";
2967 goto bad_reloc;
2968 case obj_reloc_dangerous:
2969 errmsg = "Dangerous relocation";
2970 goto bad_reloc;
2971 case obj_reloc_unhandled:
2972 errmsg = "Unhandled relocation";
2973bad_reloc:
2974 if (extsym) {
2975 bb_error_msg("%s of type %ld for %s", errmsg,
2976 (long) ELFW(R_TYPE) (rel->r_info),
2977 strtab + extsym->st_name);
2978 } else {
2979 bb_error_msg("%s of type %ld", errmsg,
2980 (long) ELFW(R_TYPE) (rel->r_info));
2981 }
2982 ret = 0;
2983 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002984 }
2985 }
2986 }
2987
2988 /* Finally, take care of the patches. */
2989
2990 if (f->string_patches) {
2991 struct obj_string_patch *p;
2992 struct obj_section *strsec;
2993 ElfW(Addr) strsec_base;
2994 strsec = obj_find_section(f, ".kstrtab");
2995 strsec_base = strsec->header.sh_addr;
2996
2997 for (p = f->string_patches; p; p = p->next) {
2998 struct obj_section *targsec = f->sections[p->reloc_secidx];
2999 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3000 = strsec_base + p->string_offset;
3001 }
3002 }
3003
3004 if (f->symbol_patches) {
3005 struct obj_symbol_patch *p;
3006
3007 for (p = f->symbol_patches; p; p = p->next) {
3008 struct obj_section *targsec = f->sections[p->reloc_secidx];
3009 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3010 = obj_symbol_final_value(f, p->sym);
3011 }
3012 }
3013
3014 return ret;
3015}
3016
Eric Andersen044228d2001-07-17 01:12:36 +00003017static int obj_create_image(struct obj_file *f, char *image)
Eric Andersen9f16d612000-06-12 23:11:16 +00003018{
3019 struct obj_section *sec;
3020 ElfW(Addr) base = f->baseaddr;
3021
3022 for (sec = f->load_order; sec; sec = sec->load_next) {
3023 char *secimg;
3024
Eric Andersen2bf658d2001-02-24 20:01:53 +00003025 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00003026 continue;
3027
3028 secimg = image + (sec->header.sh_addr - base);
3029
3030 /* Note that we allocated data for NOBITS sections earlier. */
3031 memcpy(secimg, sec->contents, sec->header.sh_size);
3032 }
3033
3034 return 1;
3035}
3036
3037/*======================================================================*/
3038
Eric Andersen044228d2001-07-17 01:12:36 +00003039static struct obj_file *obj_load(FILE * fp, int loadprogbits)
Eric Andersen9f16d612000-06-12 23:11:16 +00003040{
3041 struct obj_file *f;
3042 ElfW(Shdr) * section_headers;
3043 int shnum, i;
3044 char *shstrtab;
3045
3046 /* Read the file header. */
3047
3048 f = arch_new_file();
3049 memset(f, 0, sizeof(*f));
3050 f->symbol_cmp = strcmp;
3051 f->symbol_hash = obj_elf_hash;
3052 f->load_order_search_start = &f->load_order;
3053
3054 fseek(fp, 0, SEEK_SET);
3055 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003056 bb_perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00003057 return NULL;
3058 }
3059
3060 if (f->header.e_ident[EI_MAG0] != ELFMAG0
Eric Andersen3b1a7442003-12-24 20:30:45 +00003061 || f->header.e_ident[EI_MAG1] != ELFMAG1
3062 || f->header.e_ident[EI_MAG2] != ELFMAG2
3063 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003064 bb_error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00003065 return NULL;
3066 }
3067 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Eric Andersen3b1a7442003-12-24 20:30:45 +00003068 || f->header.e_ident[EI_DATA] != ELFDATAM
3069 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3070 || !MATCH_MACHINE(f->header.e_machine)) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003071 bb_error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00003072 return NULL;
3073 }
3074 if (f->header.e_type != ET_REL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003075 bb_error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00003076 return NULL;
3077 }
3078
3079 /* Read the section headers. */
3080
3081 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003082 bb_error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003083 (unsigned long) f->header.e_shentsize,
3084 (unsigned long) sizeof(ElfW(Shdr)));
3085 return NULL;
3086 }
3087
3088 shnum = f->header.e_shnum;
3089 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3090 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3091
3092 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3093 fseek(fp, f->header.e_shoff, SEEK_SET);
3094 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003095 bb_perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00003096 return NULL;
3097 }
3098
3099 /* Read the section data. */
3100
3101 for (i = 0; i < shnum; ++i) {
3102 struct obj_section *sec;
3103
3104 f->sections[i] = sec = arch_new_section();
3105 memset(sec, 0, sizeof(*sec));
3106
3107 sec->header = section_headers[i];
3108 sec->idx = i;
3109
Eric Andersen2bf658d2001-02-24 20:01:53 +00003110 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003111 case SHT_NULL:
3112 case SHT_NOTE:
3113 case SHT_NOBITS:
3114 /* ignore */
Eric Andersen8ae319a2001-05-21 16:09:18 +00003115 break;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003116
3117 case SHT_PROGBITS:
3118#if LOADBITS
3119 if (!loadprogbits) {
3120 sec->contents = NULL;
3121 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003122 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003123#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003124 case SHT_SYMTAB:
3125 case SHT_STRTAB:
3126 case SHT_RELM:
3127 if (sec->header.sh_size > 0) {
3128 sec->contents = xmalloc(sec->header.sh_size);
3129 fseek(fp, sec->header.sh_offset, SEEK_SET);
3130 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3131 bb_perror_msg("error reading ELF section data");
3132 return NULL;
3133 }
3134 } else {
3135 sec->contents = NULL;
3136 }
3137 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003138
3139#if SHT_RELM == SHT_REL
Eric Andersen3b1a7442003-12-24 20:30:45 +00003140 case SHT_RELA:
3141 bb_error_msg("RELA relocations not supported on this architecture");
3142 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003143#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00003144 case SHT_REL:
3145 bb_error_msg("REL relocations not supported on this architecture");
3146 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003147#endif
3148
Eric Andersen3b1a7442003-12-24 20:30:45 +00003149 default:
3150 if (sec->header.sh_type >= SHT_LOPROC) {
3151 /* Assume processor specific section types are debug
3152 info and can safely be ignored. If this is ever not
3153 the case (Hello MIPS?), don't put ifdefs here but
3154 create an arch_load_proc_section(). */
3155 break;
3156 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003157
Eric Andersen3b1a7442003-12-24 20:30:45 +00003158 bb_error_msg("can't handle sections of type %ld",
3159 (long) sec->header.sh_type);
3160 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003161 }
3162 }
3163
3164 /* Do what sort of interpretation as needed by each section. */
3165
3166 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3167
3168 for (i = 0; i < shnum; ++i) {
3169 struct obj_section *sec = f->sections[i];
3170 sec->name = shstrtab + sec->header.sh_name;
3171 }
3172
3173 for (i = 0; i < shnum; ++i) {
3174 struct obj_section *sec = f->sections[i];
3175
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003176 /* .modinfo should be contents only but gcc has no attribute for that.
3177 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3178 */
3179 if (strcmp(sec->name, ".modinfo") == 0)
3180 sec->header.sh_flags &= ~SHF_ALLOC;
3181
Eric Andersen9f16d612000-06-12 23:11:16 +00003182 if (sec->header.sh_flags & SHF_ALLOC)
3183 obj_insert_section_load_order(f, sec);
3184
3185 switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003186 case SHT_SYMTAB:
3187 {
3188 unsigned long nsym, j;
3189 char *strtab;
3190 ElfW(Sym) * sym;
Eric Andersen9f16d612000-06-12 23:11:16 +00003191
Eric Andersen3b1a7442003-12-24 20:30:45 +00003192 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3193 bb_error_msg("symbol size mismatch: %lu != %lu",
3194 (unsigned long) sec->header.sh_entsize,
3195 (unsigned long) sizeof(ElfW(Sym)));
3196 return NULL;
3197 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003198
Eric Andersen3b1a7442003-12-24 20:30:45 +00003199 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3200 strtab = f->sections[sec->header.sh_link]->contents;
3201 sym = (ElfW(Sym) *) sec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00003202
Eric Andersen3b1a7442003-12-24 20:30:45 +00003203 /* Allocate space for a table of local symbols. */
3204 j = f->local_symtab_size = sec->header.sh_info;
3205 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003206
Eric Andersen3b1a7442003-12-24 20:30:45 +00003207 /* Insert all symbols into the hash table. */
3208 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3209 ElfW(Addr) val = sym->st_value;
3210 const char *name;
3211 if (sym->st_name)
3212 name = strtab + sym->st_name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003213 else if (sym->st_shndx < shnum)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003214 name = f->sections[sym->st_shndx]->name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003215 else
3216 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00003217
Eric Andersenbf833552003-08-13 19:56:33 +00003218#if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003219 /*
3220 * For sh64 it is possible that the target of a branch
3221 * requires a mode switch (32 to 16 and back again).
3222 *
3223 * This is implied by the lsb being set in the target
3224 * address for SHmedia mode and clear for SHcompact.
3225 */
3226 val |= sym->st_other & 4;
Eric Andersenbf833552003-08-13 19:56:33 +00003227#endif
3228
Eric Andersen3b1a7442003-12-24 20:30:45 +00003229 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3230 val, sym->st_size);
3231 }
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003232 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00003233 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003234
Eric Andersen3b1a7442003-12-24 20:30:45 +00003235 case SHT_RELM:
3236 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3237 bb_error_msg("relocation entry size mismatch: %lu != %lu",
3238 (unsigned long) sec->header.sh_entsize,
3239 (unsigned long) sizeof(ElfW(RelM)));
3240 return NULL;
3241 }
3242 break;
3243 /* XXX Relocation code from modutils-2.3.19 is not here.
3244 * Why? That's about 20 lines of code from obj/obj_load.c,
3245 * which gets done in a second pass through the sections.
3246 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003247 }
3248 }
3249
3250 return f;
3251}
3252
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003253#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersen8ae319a2001-05-21 16:09:18 +00003254/*
3255 * load the unloaded sections directly into the memory allocated by
3256 * kernel for the module
3257 */
3258
Eric Andersenac5dbd12001-08-22 05:26:08 +00003259static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase)
Eric Andersen8ae319a2001-05-21 16:09:18 +00003260{
Eric Andersen8ae319a2001-05-21 16:09:18 +00003261 ElfW(Addr) base = f->baseaddr;
3262 struct obj_section* sec;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003263
Eric Andersen8ae319a2001-05-21 16:09:18 +00003264 for (sec = f->load_order; sec; sec = sec->load_next) {
3265
3266 /* section already loaded? */
3267 if (sec->contents != NULL)
3268 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003269
Eric Andersen8ae319a2001-05-21 16:09:18 +00003270 if (sec->header.sh_size == 0)
3271 continue;
3272
3273 sec->contents = imagebase + (sec->header.sh_addr - base);
3274 fseek(fp, sec->header.sh_offset, SEEK_SET);
3275 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003276 bb_error_msg("error reading ELF section data: %s\n", strerror(errno));
Eric Andersen8ae319a2001-05-21 16:09:18 +00003277 return 0;
3278 }
3279
3280 }
3281 return 1;
3282}
3283#endif
3284
Eric Andersen9f16d612000-06-12 23:11:16 +00003285static void hide_special_symbols(struct obj_file *f)
3286{
3287 static const char *const specials[] = {
Miles Baderae28b042002-04-01 09:34:25 +00003288 SPFX "cleanup_module",
3289 SPFX "init_module",
3290 SPFX "kernel_version",
Eric Andersen9f16d612000-06-12 23:11:16 +00003291 NULL
3292 };
3293
3294 struct obj_symbol *sym;
3295 const char *const *p;
3296
3297 for (p = specials; *p; ++p)
3298 if ((sym = obj_find_symbol(f, *p)) != NULL)
3299 sym->info =
3300 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3301}
3302
Glenn L McGrath759515c2003-08-30 06:00:33 +00003303
Eric Andersen71ae64b2002-10-10 04:20:21 +00003304#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Eric Andersen166fa462002-09-16 05:30:24 +00003305static int obj_gpl_license(struct obj_file *f, const char **license)
3306{
3307 struct obj_section *sec;
3308 /* This list must match *exactly* the list of allowable licenses in
3309 * linux/include/linux/module.h. Checking for leading "GPL" will not
3310 * work, somebody will use "GPL sucks, this is proprietary".
3311 */
3312 static const char *gpl_licenses[] = {
3313 "GPL",
3314 "GPL v2",
3315 "GPL and additional rights",
3316 "Dual BSD/GPL",
3317 "Dual MPL/GPL",
3318 };
Eric Andersen9f16d612000-06-12 23:11:16 +00003319
Eric Andersen166fa462002-09-16 05:30:24 +00003320 if ((sec = obj_find_section(f, ".modinfo"))) {
3321 const char *value, *ptr, *endptr;
3322 ptr = sec->contents;
3323 endptr = ptr + sec->header.sh_size;
3324 while (ptr < endptr) {
3325 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) {
3326 int i;
3327 if (license)
3328 *license = value+1;
3329 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3330 if (strcmp(value+1, gpl_licenses[i]) == 0)
3331 return(0);
3332 }
3333 return(2);
3334 }
3335 if (strchr(ptr, '\0'))
3336 ptr = strchr(ptr, '\0') + 1;
3337 else
3338 ptr = endptr;
3339 }
3340 }
3341 return(1);
3342}
3343
3344#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3345#define TAINT_PROPRIETORY_MODULE (1<<0)
3346#define TAINT_FORCED_MODULE (1<<1)
3347#define TAINT_UNSAFE_SMP (1<<2)
3348#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3349
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003350static void set_tainted(struct obj_file *f, int fd, char *m_name,
Eric Andersen166fa462002-09-16 05:30:24 +00003351 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3352{
3353 char buf[80];
3354 int oldval;
3355 static int first = 1;
3356 if (fd < 0 && !kernel_has_tainted)
3357 return; /* New modutils on old kernel */
3358 printf("Warning: loading %s will taint the kernel: %s%s\n",
3359 m_name, text1, text2);
3360 if (first) {
3361 printf(" See %s for information about tainted modules\n", TAINT_URL);
3362 first = 0;
3363 }
3364 if (fd >= 0) {
3365 read(fd, buf, sizeof(buf)-1);
3366 buf[sizeof(buf)-1] = '\0';
3367 oldval = strtoul(buf, NULL, 10);
3368 sprintf(buf, "%d\n", oldval | taint);
3369 write(fd, buf, strlen(buf));
3370 }
3371}
3372
3373/* Check if loading this module will taint the kernel. */
3374static void check_tainted_module(struct obj_file *f, char *m_name)
3375{
3376 static const char tainted_file[] = TAINT_FILENAME;
3377 int fd, kernel_has_tainted;
3378 const char *ptr;
3379
3380 kernel_has_tainted = 1;
3381 if ((fd = open(tainted_file, O_RDWR)) < 0) {
3382 if (errno == ENOENT)
3383 kernel_has_tainted = 0;
3384 else if (errno == EACCES)
3385 kernel_has_tainted = 1;
3386 else {
3387 perror(tainted_file);
3388 kernel_has_tainted = 0;
3389 }
3390 }
3391
3392 switch (obj_gpl_license(f, &ptr)) {
3393 case 0:
3394 break;
3395 case 1:
3396 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3397 break;
3398 case 2:
3399 /* The module has a non-GPL license so we pretend that the
3400 * kernel always has a taint flag to get a warning even on
3401 * kernels without the proc flag.
3402 */
3403 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3404 break;
3405 default:
3406 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3407 break;
3408 }
3409
3410 if (flag_force_load)
3411 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3412
3413 if (fd >= 0)
3414 close(fd);
3415}
Eric Andersen71ae64b2002-10-10 04:20:21 +00003416#else /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
3417#define check_tainted_module(x, y) do { } while(0);
3418#endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
Eric Andersen9f16d612000-06-12 23:11:16 +00003419
Eric Andersen889dd202003-01-23 04:48:34 +00003420#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3421/* add module source, timestamp, kernel version and a symbol for the
3422 * start of some sections. this info is used by ksymoops to do better
3423 * debugging.
3424 */
3425static int
3426get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3427{
3428#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00003429 return new_get_module_version(f, str);
Eric Andersen889dd202003-01-23 04:48:34 +00003430#else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003431 strncpy(str, "???", sizeof(str));
3432 return -1;
Eric Andersen889dd202003-01-23 04:48:34 +00003433#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
3434}
3435
3436/* add module source, timestamp, kernel version and a symbol for the
3437 * start of some sections. this info is used by ksymoops to do better
3438 * debugging.
3439 */
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003440static void
Eric Andersen889dd202003-01-23 04:48:34 +00003441add_ksymoops_symbols(struct obj_file *f, const char *filename,
3442 const char *m_name)
3443{
3444 static const char symprefix[] = "__insmod_";
3445 struct obj_section *sec;
3446 struct obj_symbol *sym;
3447 char *name, *absolute_filename;
3448 char str[STRVERSIONLEN], real[PATH_MAX];
3449 int i, l, lm_name, lfilename, use_ksymtab, version;
3450 struct stat statbuf;
3451
3452 static const char *section_names[] = {
3453 ".text",
3454 ".rodata",
3455 ".data",
Peter Kjellerstedt540769d2005-03-30 16:36:40 +00003456 ".bss",
3457 ".sbss"
Eric Andersen889dd202003-01-23 04:48:34 +00003458 };
3459
3460 if (realpath(filename, real)) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003461 absolute_filename = bb_xstrdup(real);
Eric Andersen889dd202003-01-23 04:48:34 +00003462 }
3463 else {
3464 int save_errno = errno;
Manuel Novoa III cad53642003-03-19 09:13:01 +00003465 bb_error_msg("cannot get realpath for %s", filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003466 errno = save_errno;
3467 perror("");
Manuel Novoa III cad53642003-03-19 09:13:01 +00003468 absolute_filename = bb_xstrdup(filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003469 }
3470
3471 lm_name = strlen(m_name);
3472 lfilename = strlen(absolute_filename);
3473
3474 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3475 * are not to be exported. otherwise leave ksymtab alone for now, the
3476 * "export all symbols" compatibility code will export these symbols later.
3477 */
3478 use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export;
3479
3480 if ((sec = obj_find_section(f, ".this"))) {
3481 /* tag the module header with the object name, last modified
3482 * timestamp and module version. worst case for module version
3483 * is 0xffffff, decimal 16777215. putting all three fields in
3484 * one symbol is less readable but saves kernel space.
3485 */
3486 l = sizeof(symprefix)+ /* "__insmod_" */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003487 lm_name+ /* module name */
3488 2+ /* "_O" */
3489 lfilename+ /* object filename */
3490 2+ /* "_M" */
3491 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */
3492 2+ /* "_V" */
3493 8+ /* version in dec */
3494 1; /* nul */
Eric Andersen889dd202003-01-23 04:48:34 +00003495 name = xmalloc(l);
3496 if (stat(absolute_filename, &statbuf) != 0)
3497 statbuf.st_mtime = 0;
3498 version = get_module_version(f, str); /* -1 if not found */
3499 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003500 symprefix, m_name, absolute_filename,
3501 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3502 version);
Eric Andersen889dd202003-01-23 04:48:34 +00003503 sym = obj_add_symbol(f, name, -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00003504 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
3505 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003506 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003507 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003508 }
3509 free(absolute_filename);
3510#ifdef _NOT_SUPPORTED_
3511 /* record where the persistent data is going, same address as previous symbol */
3512
3513 if (f->persist) {
3514 l = sizeof(symprefix)+ /* "__insmod_" */
3515 lm_name+ /* module name */
3516 2+ /* "_P" */
3517 strlen(f->persist)+ /* data store */
3518 1; /* nul */
3519 name = xmalloc(l);
3520 snprintf(name, l, "%s%s_P%s",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003521 symprefix, m_name, f->persist);
Eric Andersen889dd202003-01-23 04:48:34 +00003522 sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003523 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003524 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003525 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003526 }
3527#endif /* _NOT_SUPPORTED_ */
3528 /* tag the desired sections if size is non-zero */
3529
3530 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
3531 if ((sec = obj_find_section(f, section_names[i])) &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00003532 sec->header.sh_size) {
Eric Andersen889dd202003-01-23 04:48:34 +00003533 l = sizeof(symprefix)+ /* "__insmod_" */
3534 lm_name+ /* module name */
3535 2+ /* "_S" */
3536 strlen(sec->name)+ /* section name */
3537 2+ /* "_L" */
3538 8+ /* length in dec */
3539 1; /* nul */
3540 name = xmalloc(l);
3541 snprintf(name, l, "%s%s_S%s_L%ld",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003542 symprefix, m_name, sec->name,
3543 (long)sec->header.sh_size);
Eric Andersen889dd202003-01-23 04:48:34 +00003544 sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003545 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003546 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003547 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003548 }
3549 }
3550}
3551#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3552
Eric Andersenbe65c352003-01-23 04:57:35 +00003553#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3554static void print_load_map(struct obj_file *f)
3555{
3556 struct obj_symbol *sym;
3557 struct obj_symbol **all, **p;
3558 struct obj_section *sec;
3559 int i, nsyms, *loaded;
3560
3561 /* Report on the section layout. */
3562
3563 printf("Sections: Size %-*s Align\n",
3564 (int) (2 * sizeof(void *)), "Address");
3565
3566 for (sec = f->load_order; sec; sec = sec->load_next) {
3567 int a;
3568 unsigned long tmp;
3569
3570 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3571 tmp >>= 1;
3572 if (a == -1)
3573 a = 0;
3574
3575 printf("%-15s %08lx %0*lx 2**%d\n",
3576 sec->name,
3577 (long)sec->header.sh_size,
3578 (int) (2 * sizeof(void *)),
3579 (long)sec->header.sh_addr,
3580 a);
3581 }
3582#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
3583 /* Quick reference which section indicies are loaded. */
3584
3585 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3586 while (--i >= 0)
3587 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3588
3589 /* Collect the symbols we'll be listing. */
3590
3591 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3592 for (sym = f->symtab[i]; sym; sym = sym->next)
3593 if (sym->secidx <= SHN_HIRESERVE
3594 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3595 ++nsyms;
3596
3597 all = alloca(nsyms * sizeof(struct obj_symbol *));
3598
3599 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3600 for (sym = f->symtab[i]; sym; sym = sym->next)
3601 if (sym->secidx <= SHN_HIRESERVE
3602 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3603 *p++ = sym;
3604
3605 /* And list them. */
3606 printf("\nSymbols:\n");
3607 for (p = all; p < all + nsyms; ++p) {
3608 char type = '?';
3609 unsigned long value;
3610
3611 sym = *p;
3612 if (sym->secidx == SHN_ABS) {
3613 type = 'A';
3614 value = sym->value;
3615 } else if (sym->secidx == SHN_UNDEF) {
3616 type = 'U';
3617 value = 0;
3618 } else {
3619 sec = f->sections[sym->secidx];
3620
3621 if (sec->header.sh_type == SHT_NOBITS)
3622 type = 'B';
3623 else if (sec->header.sh_flags & SHF_ALLOC) {
3624 if (sec->header.sh_flags & SHF_EXECINSTR)
3625 type = 'T';
3626 else if (sec->header.sh_flags & SHF_WRITE)
3627 type = 'D';
3628 else
3629 type = 'R';
3630 }
3631 value = sym->value + sec->header.sh_addr;
3632 }
3633
3634 if (ELFW(ST_BIND) (sym->info) == STB_LOCAL)
3635 type = tolower(type);
3636
3637 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3638 type, sym->name);
3639 }
3640#endif
3641}
3642
3643#endif
3644
Eric Andersen9f16d612000-06-12 23:11:16 +00003645extern int insmod_main( int argc, char **argv)
3646{
Eric Andersena18aaf12001-01-24 19:07:09 +00003647 int opt;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003648 int len;
Eric Andersen5275b1e2004-06-22 20:10:53 +00003649 int k_crcs;
Eric Andersen6fb4e482002-06-06 14:24:57 +00003650 char *tmp, *tmp1;
Eric Andersen9f16d612000-06-12 23:11:16 +00003651 unsigned long m_size;
3652 ElfW(Addr) m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00003653 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003654 struct stat st;
Eric Andersen61f83052002-06-22 17:15:42 +00003655 char *m_name = 0;
Matt Kraai3e856ce2000-12-01 02:55:13 +00003656 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003657 int m_has_modinfo;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003658#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Matt Kraai063c1f52001-08-06 14:18:08 +00003659 struct utsname uts_info;
Eric Andersen9f16d612000-06-12 23:11:16 +00003660 char m_strversion[STRVERSIONLEN];
Eric Andersen5275b1e2004-06-22 20:10:53 +00003661 int m_version, m_crcs;
Eric Andersen9f16d612000-06-12 23:11:16 +00003662#endif
Eric Andersen61f83052002-06-22 17:15:42 +00003663#ifdef CONFIG_FEATURE_CLEAN_UP
3664 FILE *fp = 0;
3665#else
3666 FILE *fp;
3667#endif
Eric Andersenbe65c352003-01-23 04:57:35 +00003668#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3669 int flag_print_load_map = 0;
3670#endif
Eric Andersen03d80912003-12-19 21:04:19 +00003671 int k_version = 0;
3672 struct utsname myuname;
Eric Andersen9f16d612000-06-12 23:11:16 +00003673
Erik Andersene49d5ec2000-02-08 19:58:47 +00003674 /* Parse any options */
Eric Andersenbe65c352003-01-23 04:57:35 +00003675#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
Eric Andersen3b1a7442003-12-24 20:30:45 +00003676 while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0)
Eric Andersenbe65c352003-01-23 04:57:35 +00003677#else
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003678 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0)
Eric Andersenbe65c352003-01-23 04:57:35 +00003679#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003680 {
3681 switch (opt) {
3682 case 'f': /* force loading */
3683 flag_force_load = 1;
3684 break;
3685 case 'k': /* module loaded by kerneld, auto-cleanable */
3686 flag_autoclean = 1;
3687 break;
3688 case 's': /* log to syslog */
3689 /* log to syslog -- not supported */
3690 /* but kernel needs this for request_module(), */
3691 /* as this calls: modprobe -k -s -- <module> */
3692 /* so silently ignore this flag */
3693 break;
3694 case 'v': /* verbose output */
3695 flag_verbose = 1;
3696 break;
3697 case 'q': /* silent */
3698 flag_quiet = 1;
3699 break;
3700 case 'x': /* do not export externs */
3701 flag_export = 0;
3702 break;
3703 case 'o': /* name the output module */
3704 free(m_name);
3705 m_name = bb_xstrdup(optarg);
3706 break;
3707 case 'L': /* Stub warning */
3708 /* This is needed for compatibility with modprobe.
3709 * In theory, this does locking, but we don't do
3710 * that. So be careful and plan your life around not
3711 * loading the same module 50 times concurrently. */
3712 break;
Eric Andersenbe65c352003-01-23 04:57:35 +00003713#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
Eric Andersen3b1a7442003-12-24 20:30:45 +00003714 case 'm': /* print module load map */
3715 flag_print_load_map = 1;
3716 break;
Eric Andersenbe65c352003-01-23 04:57:35 +00003717#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003718 default:
3719 bb_show_usage();
3720 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003721 }
Eric Andersen03d80912003-12-19 21:04:19 +00003722
Eric Andersena18aaf12001-01-24 19:07:09 +00003723 if (argv[optind] == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003724 bb_show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003725 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003726
Erik Andersene49d5ec2000-02-08 19:58:47 +00003727 /* Grab the module name */
Manuel Novoa III cad53642003-03-19 09:13:01 +00003728 tmp1 = bb_xstrdup(argv[optind]);
Eric Andersen6fb4e482002-06-06 14:24:57 +00003729 tmp = basename(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003730 len = strlen(tmp);
3731
Eric Andersen03d80912003-12-19 21:04:19 +00003732 if (uname(&myuname) == 0) {
3733 if (myuname.release[0] == '2') {
3734 k_version = myuname.release[2] - '0';
3735 }
3736 }
3737
3738#if defined(CONFIG_FEATURE_2_6_MODULES)
3739 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00003740 tmp[len - 2] == 'k' && tmp[len - 1] == 'o') {
Eric Andersen03d80912003-12-19 21:04:19 +00003741 len-=3;
3742 tmp[len] = '\0';
3743 }
3744 else
3745#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003746 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
3747 len-=2;
3748 tmp[len] = '\0';
3749 }
Eric Andersen2d342152002-06-18 05:16:25 +00003750
Eric Andersen03d80912003-12-19 21:04:19 +00003751
3752#if defined(CONFIG_FEATURE_2_6_MODULES)
3753 if (k_version > 4)
3754 bb_xasprintf(&m_fullName, "%s.ko", tmp);
3755 else
Eric Andersen03d80912003-12-19 21:04:19 +00003756#endif
Eric Andersen66e21fd2004-01-05 23:49:37 +00003757 bb_xasprintf(&m_fullName, "%s.o", tmp);
Eric Andersen61f83052002-06-22 17:15:42 +00003758
Eric Andersen61f83052002-06-22 17:15:42 +00003759 if (!m_name) {
3760 m_name = tmp;
3761 } else {
3762 free(tmp1);
3763 tmp1 = 0; /* flag for free(m_name) before exit() */
3764 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003765
Eric Andersen14d35432001-05-14 17:07:32 +00003766 /* Get a filedesc for the module. Check we we have a complete path */
Eric Andersen02b9f422001-02-15 19:07:43 +00003767 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3768 (fp = fopen(argv[optind], "r")) == NULL) {
Eric Andersen14d35432001-05-14 17:07:32 +00003769 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
3770 * but do not error out yet if we fail to find it... */
Eric Andersen03d80912003-12-19 21:04:19 +00003771 if (k_version) { /* uname succeedd */
3772 char *module_dir;
3773 char *tmdn;
Eric Andersen2416dfc2001-05-14 20:03:04 +00003774 char real_module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00003775
Eric Andersen03d80912003-12-19 21:04:19 +00003776 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
Eric Andersen2416dfc2001-05-14 20:03:04 +00003777 /* Jump through hoops in case /lib/modules/`uname -r`
3778 * is a symlink. We do not want recursive_action to
3779 * follow symlinks, but we do want to follow the
3780 * /lib/modules/`uname -r` dir, So resolve it ourselves
3781 * if it is a link... */
Eric Andersen03d80912003-12-19 21:04:19 +00003782 if (realpath (tmdn, real_module_dir) == NULL)
3783 module_dir = tmdn;
3784 else
3785 module_dir = real_module_dir;
3786 recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen3b1a7442003-12-24 20:30:45 +00003787 check_module_name_match, 0, m_fullName);
Eric Andersen03d80912003-12-19 21:04:19 +00003788 free(tmdn);
Eric Andersen14d35432001-05-14 17:07:32 +00003789 }
3790
3791 /* Check if we have found anything yet */
Eric Andersen61f83052002-06-22 17:15:42 +00003792 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen9f16d612000-06-12 23:11:16 +00003793 {
Eric Andersen2416dfc2001-05-14 20:03:04 +00003794 char module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00003795
Eric Andersen03d80912003-12-19 21:04:19 +00003796 free(m_filename);
3797 m_filename = 0;
Eric Andersen2416dfc2001-05-14 20:03:04 +00003798 if (realpath (_PATH_MODULES, module_dir) == NULL)
3799 strcpy(module_dir, _PATH_MODULES);
Eric Andersen14d35432001-05-14 17:07:32 +00003800 /* No module found under /lib/modules/`uname -r`, this
3801 * time cast the net a bit wider. Search /lib/modules/ */
Matt Kraai1f0c4362001-12-20 23:13:26 +00003802 if (! recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen03d80912003-12-19 21:04:19 +00003803 check_module_name_match, 0, m_fullName))
Eric Andersen9f16d612000-06-12 23:11:16 +00003804 {
Eric Andersen61f83052002-06-22 17:15:42 +00003805 if (m_filename == 0
Eric Andersen03d80912003-12-19 21:04:19 +00003806 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen14d35432001-05-14 17:07:32 +00003807 {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003808 bb_error_msg("%s: no module by that name found", m_fullName);
Eric Andersen61f83052002-06-22 17:15:42 +00003809 goto out;
Eric Andersen14d35432001-05-14 17:07:32 +00003810 }
3811 } else
Manuel Novoa III cad53642003-03-19 09:13:01 +00003812 bb_error_msg_and_die("%s: no module by that name found", m_fullName);
Eric Andersen14d35432001-05-14 17:07:32 +00003813 }
Eric Andersen03d80912003-12-19 21:04:19 +00003814 } else
Manuel Novoa III cad53642003-03-19 09:13:01 +00003815 m_filename = bb_xstrdup(argv[optind]);
Erik Andersend387d011999-12-21 02:55:11 +00003816
Glenn L McGrath5c9f0d02003-12-31 23:20:10 +00003817 if (!flag_quiet)
3818 printf("Using %s\n", m_filename);
Erik Andersend387d011999-12-21 02:55:11 +00003819
Eric Andersene7047882003-12-11 01:42:13 +00003820#ifdef CONFIG_FEATURE_2_6_MODULES
Eric Andersen03d80912003-12-19 21:04:19 +00003821 if (k_version > 4)
3822 {
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003823 optind--;
Eric Andersen03d80912003-12-19 21:04:19 +00003824 argv[optind + 1] = m_filename;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003825 return insmod_ng_main(argc - optind, argv + optind);
Eric Andersen03d80912003-12-19 21:04:19 +00003826 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003827#endif
3828
Eric Andersen8ae319a2001-05-21 16:09:18 +00003829 if ((f = obj_load(fp, LOADBITS)) == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +00003830 bb_perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00003831
Eric Andersen9f16d612000-06-12 23:11:16 +00003832 if (get_modinfo_value(f, "kernel_version") == NULL)
3833 m_has_modinfo = 0;
3834 else
3835 m_has_modinfo = 1;
3836
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003837#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00003838 /* Version correspondence? */
Eric Andersenb493dec2002-07-02 19:14:23 +00003839 if (!flag_quiet) {
3840 if (uname(&uts_info) < 0)
3841 uts_info.release[0] = '\0';
3842 if (m_has_modinfo) {
3843 m_version = new_get_module_version(f, m_strversion);
Eric Andersenb493dec2002-07-02 19:14:23 +00003844 if (m_version == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003845 bb_error_msg("couldn't find the kernel version the module was "
Eric Andersenb493dec2002-07-02 19:14:23 +00003846 "compiled for");
3847 goto out;
3848 }
3849 }
3850
3851 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
3852 if (flag_force_load) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003853 bb_error_msg("Warning: kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00003854 "\t%s was compiled for kernel version %s\n"
3855 "\twhile this kernel is version %s",
3856 m_filename, m_strversion, uts_info.release);
3857 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003858 bb_error_msg("kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00003859 "\t%s was compiled for kernel version %s\n"
3860 "\twhile this kernel is version %s.",
3861 m_filename, m_strversion, uts_info.release);
3862 goto out;
3863 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003864 }
3865 }
3866 k_crcs = 0;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003867#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00003868
Eric Andersencb3b9b12004-06-22 11:50:52 +00003869 if (!query_module(NULL, 0, NULL, 0, NULL)) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003870 if (!new_get_kernel_symbols())
3871 goto out;
3872 k_crcs = new_is_kernel_checksummed();
Eric Andersen9f16d612000-06-12 23:11:16 +00003873 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003874 bb_error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003875 goto out;
Eric Andersen9f16d612000-06-12 23:11:16 +00003876 }
3877
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003878#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00003879 m_crcs = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00003880 if (m_has_modinfo)
3881 m_crcs = new_is_module_checksummed(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00003882
3883 if (m_crcs != k_crcs)
3884 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003885#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00003886
Erik Andersene49d5ec2000-02-08 19:58:47 +00003887 /* Let the module know about the kernel symbols. */
3888 add_kernel_symbols(f);
3889
Eric Andersen9f16d612000-06-12 23:11:16 +00003890 /* Allocate common symbols, symbol tables, and string tables. */
3891
Eric Andersencb3b9b12004-06-22 11:50:52 +00003892 if (!new_create_this_module(f, m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00003893 {
3894 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003895 }
3896
Eric Andersen9f16d612000-06-12 23:11:16 +00003897 if (!obj_check_undefineds(f)) {
3898 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003899 }
3900 obj_allocate_commons(f);
Eric Andersen166fa462002-09-16 05:30:24 +00003901 check_tainted_module(f, m_name);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003902
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003903 /* done with the module name, on to the optional var=value arguments */
3904 ++optind;
3905
Eric Andersen9f16d612000-06-12 23:11:16 +00003906 if (optind < argc) {
Robert Griebl809387f2004-07-20 15:43:57 +00003907 if (!new_process_module_arguments(f, argc - optind, argv + optind))
Eric Andersen9f16d612000-06-12 23:11:16 +00003908 {
3909 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003910 }
3911 }
3912
Eric Andersen9f16d612000-06-12 23:11:16 +00003913 arch_create_got(f);
3914 hide_special_symbols(f);
3915
Eric Andersen889dd202003-01-23 04:48:34 +00003916#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3917 add_ksymoops_symbols(f, m_filename, m_name);
3918#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3919
Eric Andersencb3b9b12004-06-22 11:50:52 +00003920 new_create_module_ksymtab(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00003921
Erik Andersene49d5ec2000-02-08 19:58:47 +00003922 /* Find current size of the module */
3923 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00003924
3925
Erik Andersene49d5ec2000-02-08 19:58:47 +00003926 m_addr = create_module(m_name, m_size);
Eric Andersen61f83052002-06-22 17:15:42 +00003927 if (m_addr == -1) switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003928 case EEXIST:
3929 bb_error_msg("A module named %s already exists", m_name);
3930 goto out;
3931 case ENOMEM:
3932 bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3933 m_size);
3934 goto out;
3935 default:
3936 bb_perror_msg("create_module: %s", m_name);
3937 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003938 }
Erik Andersend387d011999-12-21 02:55:11 +00003939
Eric Andersen8ae319a2001-05-21 16:09:18 +00003940#if !LOADBITS
3941 /*
3942 * the PROGBITS section was not loaded by the obj_load
3943 * now we can load them directly into the kernel memory
3944 */
Eric Andersenac5dbd12001-08-22 05:26:08 +00003945 if (!obj_load_progbits(fp, f, (char*)m_addr)) {
Eric Andersen8ae319a2001-05-21 16:09:18 +00003946 delete_module(m_name);
3947 goto out;
3948 }
Eric Andersen03d80912003-12-19 21:04:19 +00003949#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +00003950
Eric Andersen9f16d612000-06-12 23:11:16 +00003951 if (!obj_relocate(f, m_addr)) {
3952 delete_module(m_name);
3953 goto out;
3954 }
Erik Andersend387d011999-12-21 02:55:11 +00003955
Eric Andersencb3b9b12004-06-22 11:50:52 +00003956 if (!new_init_module(m_name, f, m_size))
Eric Andersen9f16d612000-06-12 23:11:16 +00003957 {
3958 delete_module(m_name);
3959 goto out;
3960 }
3961
Eric Andersenbe65c352003-01-23 04:57:35 +00003962#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3963 if(flag_print_load_map)
3964 print_load_map(f);
3965#endif
3966
Matt Kraai3e856ce2000-12-01 02:55:13 +00003967 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00003968
3969out:
Eric Andersen61f83052002-06-22 17:15:42 +00003970#ifdef CONFIG_FEATURE_CLEAN_UP
3971 if(fp)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003972 fclose(fp);
Eric Andersen61f83052002-06-22 17:15:42 +00003973 if(tmp1) {
3974 free(tmp1);
3975 } else {
3976 free(m_name);
3977 }
3978 free(m_filename);
3979#endif
Eric Andersenbb245ba2000-06-19 19:53:30 +00003980 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00003981}
Eric Andersene7047882003-12-11 01:42:13 +00003982
3983
3984#endif
3985
3986
3987#ifdef CONFIG_FEATURE_2_6_MODULES
3988
3989#include <sys/mman.h>
3990#include <asm/unistd.h>
3991#include <sys/syscall.h>
3992
3993/* We use error numbers in a loose translation... */
3994static const char *moderror(int err)
3995{
3996 switch (err) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003997 case ENOEXEC:
3998 return "Invalid module format";
3999 case ENOENT:
4000 return "Unknown symbol in module";
4001 case ESRCH:
4002 return "Module has wrong symbol version";
4003 case EINVAL:
4004 return "Invalid parameters";
4005 default:
4006 return strerror(err);
Eric Andersene7047882003-12-11 01:42:13 +00004007 }
4008}
4009
4010extern int insmod_ng_main( int argc, char **argv)
4011{
4012 int i;
4013 int fd;
4014 long int ret;
4015 struct stat st;
4016 unsigned long len;
4017 void *map;
4018 char *filename, *options = bb_xstrdup("");
Eric Andersen3b1a7442003-12-24 20:30:45 +00004019
Eric Andersene7047882003-12-11 01:42:13 +00004020 filename = argv[1];
4021 if (!filename) {
4022 bb_show_usage();
4023 return -1;
4024 }
4025
4026 /* Rest is options */
4027 for (i = 2; i < argc; i++) {
4028 options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2);
4029 /* Spaces handled by "" pairs, but no way of escaping quotes */
4030 if (strchr(argv[i], ' ')) {
4031 strcat(options, "\"");
4032 strcat(options, argv[i]);
4033 strcat(options, "\"");
4034 } else {
4035 strcat(options, argv[i]);
4036 }
4037 strcat(options, " ");
4038 }
4039
4040 if ((fd = open(filename, O_RDONLY, 0)) < 0) {
4041 bb_perror_msg_and_die("cannot open module `%s'", filename);
4042 }
4043
4044 fstat(fd, &st);
4045 len = st.st_size;
4046 map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
4047 if (map == MAP_FAILED) {
4048 bb_perror_msg_and_die("cannot mmap `%s'", filename);
4049 }
4050
4051 ret = syscall(__NR_init_module, map, len, options);
4052 if (ret != 0) {
4053 bb_perror_msg_and_die("cannot insert `%s': %s (%li)",
Eric Andersen3b1a7442003-12-24 20:30:45 +00004054 filename, moderror(errno), ret);
Eric Andersene7047882003-12-11 01:42:13 +00004055 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00004056
Eric Andersene7047882003-12-11 01:42:13 +00004057 return 0;
4058}
4059
4060#endif