blob: d1aa24f14c6b0738a25f06fad6cd54a4c94143f4 [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 Andersenc7bda1c2004-03-15 08:29:22 +00005 * This version of insmod supports x86, ARM, SH3/4/5, powerpc, m68k,
Eric Andersenee70fa52004-05-26 11:38:46 +00006 * MIPS, v850e, and H8/300.
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 *
Miles Bader75ce8d72002-04-01 14:25:51 +000011 * Miles Bader <miles@gnu.org> added NEC V850E support.
Miles Baderae28b042002-04-01 09:34:25 +000012 *
Eric Andersenfe4208f2000-09-24 03:44:29 +000013 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
Eric Andersen21adca72000-12-06 18:18:26 +000014 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
15 *
16 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
17 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
18 * very minor changes required to also work with StrongArm and presumably
19 * all ARM based systems.
Eric Andersenfe4208f2000-09-24 03:44:29 +000020 *
Eric Andersenee70fa52004-05-26 11:38:46 +000021 * Yoshinori Sato <ysato@users.sourceforge.jp> 19-May-2004.
22 * added Renesas H8/300 support.
23 *
Eric Andersenbf833552003-08-13 19:56:33 +000024 * Paul Mundt <lethal@linux-sh.org> 08-Aug-2003.
25 * Integrated support for sh64 (SH-5), from preliminary modutils
26 * patches from Benedict Gaster <benedict.gaster@superh.com>.
27 * Currently limited to support for 32bit ABI.
28 *
Eric Andersencffd5022002-05-24 06:50:15 +000029 * Magnus Damm <damm@opensource.se> 22-May-2002.
30 * The plt and got code are now using the same structs.
31 * Added generic linked list code to fully support PowerPC.
32 * Replaced the mess in arch_apply_relocation() with architecture blocks.
33 * The arch_create_got() function got cleaned up with architecture blocks.
34 * These blocks should be easy maintain and sync with obj_xxx.c in modutils.
35 *
Eric Andersen90fe7fe2001-02-20 20:47:08 +000036 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
Eric Andersenc7bda1c2004-03-15 08:29:22 +000037 * PowerPC specific code stolen from modutils-2.3.16,
Eric Andersen90fe7fe2001-02-20 20:47:08 +000038 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
39 * I've only tested the code on mpc8xx platforms in big-endian mode.
Eric Andersenbdfd0d72001-10-24 05:00:29 +000040 * Did some cleanup and added CONFIG_USE_xxx_ENTRIES...
Eric Andersen90fe7fe2001-02-20 20:47:08 +000041 *
Eric Andersen2bf658d2001-02-24 20:01:53 +000042 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
43 * based on modutils-2.4.2
44 * MIPS specific support for Elf loading and relocation.
45 * Copyright 1996, 1997 Linux International.
46 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
47 *
Eric Andersen9f16d612000-06-12 23:11:16 +000048 * Based almost entirely on the Linux modutils-2.3.11 implementation.
49 * Copyright 1996, 1997 Linux International.
50 * New implementation contributed by Richard Henderson <rth@tamu.edu>
51 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
52 * Restructured (and partly rewritten) by:
53 * Björn Ekwall <bj0rn@blox.se> February 1999
Erik Andersen02104321999-12-17 18:57:34 +000054 *
55 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
57 * the Free Software Foundation; either version 2 of the License, or
58 * (at your option) any later version.
59 *
60 * This program is distributed in the hope that it will be useful,
61 * but WITHOUT ANY WARRANTY; without even the implied warranty of
62 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
63 * General Public License for more details.
64 *
65 * You should have received a copy of the GNU General Public License
66 * along with this program; if not, write to the Free Software
67 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
68 *
69 */
70
Erik Andersen02104321999-12-17 18:57:34 +000071#include <stdlib.h>
72#include <stdio.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000073#include <stddef.h>
Erik Andersen02104321999-12-17 18:57:34 +000074#include <errno.h>
75#include <unistd.h>
76#include <dirent.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000077#include <ctype.h>
78#include <assert.h>
Eric Andersened3ef502001-01-27 08:24:39 +000079#include <string.h>
Eric Andersen999bf722000-07-09 06:59:58 +000080#include <getopt.h>
Eric Andersen166fa462002-09-16 05:30:24 +000081#include <fcntl.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000082#include <sys/utsname.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000083#include "busybox.h"
Eric Andersen9f16d612000-06-12 23:11:16 +000084
Eric Andersene7047882003-12-11 01:42:13 +000085#if !defined(CONFIG_FEATURE_2_4_MODULES) && \
Eric Andersene7047882003-12-11 01:42:13 +000086 !defined(CONFIG_FEATURE_2_6_MODULES)
87#define CONFIG_FEATURE_2_4_MODULES
88#endif
89
Eric Andersencb3b9b12004-06-22 11:50:52 +000090#if !defined(CONFIG_FEATURE_2_4_MODULES)
Eric Andersene7047882003-12-11 01:42:13 +000091#define insmod_ng_main insmod_main
92#endif
93
Eric Andersene7047882003-12-11 01:42:13 +000094#if defined(CONFIG_FEATURE_2_6_MODULES)
95extern int insmod_ng_main( int argc, char **argv);
96#endif
97
Eric Andersencb3b9b12004-06-22 11:50:52 +000098
99#if defined(CONFIG_FEATURE_2_4_MODULES)
100
Eric Andersen64c8b172001-04-05 07:33:10 +0000101
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000102#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000103#define LOADBITS 0
Eric Andersen8ae319a2001-05-21 16:09:18 +0000104#else
105#define LOADBITS 1
106#endif
107
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000108
109#if defined(__arm__)
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000110#define CONFIG_USE_PLT_ENTRIES
111#define CONFIG_PLT_ENTRY_SIZE 8
112#define CONFIG_USE_GOT_ENTRIES
113#define CONFIG_GOT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000114#define CONFIG_USE_SINGLE
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000115
Eric Andersencffd5022002-05-24 06:50:15 +0000116#define MATCH_MACHINE(x) (x == EM_ARM)
117#define SHT_RELM SHT_REL
118#define Elf32_RelM Elf32_Rel
119#define ELFCLASSM ELFCLASS32
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000120#endif
121
Eric Andersenbf77f612003-01-23 06:02:39 +0000122#if defined(__s390__)
Eric Andersenc3b2dbe2003-03-13 18:57:08 +0000123#define CONFIG_USE_PLT_ENTRIES
124#define CONFIG_PLT_ENTRY_SIZE 8
125#define CONFIG_USE_GOT_ENTRIES
126#define CONFIG_GOT_ENTRY_SIZE 8
127#define CONFIG_USE_SINGLE
Eric Andersenbf77f612003-01-23 06:02:39 +0000128
129#define MATCH_MACHINE(x) (x == EM_S390)
130#define SHT_RELM SHT_RELA
131#define Elf32_RelM Elf32_Rela
132#define ELFCLASSM ELFCLASS32
133#endif
134
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000135#if defined(__i386__)
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000136#define CONFIG_USE_GOT_ENTRIES
137#define CONFIG_GOT_ENTRY_SIZE 4
Eric Andersencffd5022002-05-24 06:50:15 +0000138#define CONFIG_USE_SINGLE
139
140#ifndef EM_486
141#define MATCH_MACHINE(x) (x == EM_386)
142#else
143#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
144#endif
145
146#define SHT_RELM SHT_REL
147#define Elf32_RelM Elf32_Rel
148#define ELFCLASSM ELFCLASS32
149#endif
150
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000151#if defined(__mc68000__)
Eric Andersencffd5022002-05-24 06:50:15 +0000152#define CONFIG_USE_GOT_ENTRIES
153#define CONFIG_GOT_ENTRY_SIZE 4
154#define CONFIG_USE_SINGLE
155
156#define MATCH_MACHINE(x) (x == EM_68K)
157#define SHT_RELM SHT_RELA
158#define Elf32_RelM Elf32_Rela
Eric Andersen9e458f52004-03-19 12:17:04 +0000159#define ELFCLASSM ELFCLASS32
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000160#endif
161
Eric Andersen2bf658d2001-02-24 20:01:53 +0000162#if defined(__mips__)
Eric Andersencffd5022002-05-24 06:50:15 +0000163/* Account for ELF spec changes. */
164#ifndef EM_MIPS_RS3_LE
165#ifdef EM_MIPS_RS4_BE
166#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
167#else
168#define EM_MIPS_RS3_LE 10
169#endif
170#endif /* !EM_MIPS_RS3_LE */
171
172#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
173#define SHT_RELM SHT_REL
174#define Elf32_RelM Elf32_Rel
175#define ELFCLASSM ELFCLASS32
176#define ARCHDATAM "__dbe_table"
177#endif
178
179#if defined(__powerpc__)
180#define CONFIG_USE_PLT_ENTRIES
181#define CONFIG_PLT_ENTRY_SIZE 16
182#define CONFIG_USE_PLT_LIST
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000183#define CONFIG_LIST_ARCHTYPE ElfW(Addr)
Eric Andersencffd5022002-05-24 06:50:15 +0000184#define CONFIG_USE_LIST
185
186#define MATCH_MACHINE(x) (x == EM_PPC)
187#define SHT_RELM SHT_RELA
188#define Elf32_RelM Elf32_Rela
189#define ELFCLASSM ELFCLASS32
190#define ARCHDATAM "__ftr_fixup"
191#endif
192
193#if defined(__sh__)
194#define CONFIG_USE_GOT_ENTRIES
195#define CONFIG_GOT_ENTRY_SIZE 4
196#define CONFIG_USE_SINGLE
197
198#define MATCH_MACHINE(x) (x == EM_SH)
199#define SHT_RELM SHT_RELA
200#define Elf32_RelM Elf32_Rela
201#define ELFCLASSM ELFCLASS32
202
Eric Andersenbf833552003-08-13 19:56:33 +0000203/* the SH changes have only been tested in =little endian= mode */
Eric Andersencffd5022002-05-24 06:50:15 +0000204/* I'm not sure about big endian, so let's warn: */
205
Eric Andersenbf833552003-08-13 19:56:33 +0000206#if defined(__sh__) && defined(__BIG_ENDIAN__)
207#error insmod.c may require changes for use on big endian SH
Eric Andersencffd5022002-05-24 06:50:15 +0000208#endif
209
210/* it may or may not work on the SH1/SH2... So let's error on those
211 also */
Eric Andersenbf833552003-08-13 19:56:33 +0000212#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && \
213 (defined(__sh__))
214#error insmod.c may require changes for SH1 or SH2 use
Eric Andersencffd5022002-05-24 06:50:15 +0000215#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000216#endif
217
Miles Baderae28b042002-04-01 09:34:25 +0000218#if defined (__v850e__)
219#define CONFIG_USE_PLT_ENTRIES
220#define CONFIG_PLT_ENTRY_SIZE 8
Eric Andersencffd5022002-05-24 06:50:15 +0000221#define CONFIG_USE_SINGLE
222
223#ifndef EM_CYGNUS_V850 /* grumble */
224#define EM_CYGNUS_V850 0x9080
Miles Baderae28b042002-04-01 09:34:25 +0000225#endif
226
Eric Andersencffd5022002-05-24 06:50:15 +0000227#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
228#define SHT_RELM SHT_RELA
229#define Elf32_RelM Elf32_Rela
230#define ELFCLASSM ELFCLASS32
231
232#define SYMBOL_PREFIX "_"
233#endif
234
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +0000235#if defined(__cris__)
236#ifndef EM_CRIS
237#define EM_CRIS 76
238#define R_CRIS_NONE 0
239#define R_CRIS_32 3
240#endif
241
242#define MATCH_MACHINE(x) (x == EM_CRIS)
243#define SHT_RELM SHT_RELA
244#define Elf32_RelM Elf32_Rela
245#define ELFCLASSM ELFCLASS32
246#endif
247
Eric Andersenee70fa52004-05-26 11:38:46 +0000248#if defined(__H8300H__) || defined(__H8300S__)
249#define CONFIG_USE_SINGLE
250
251#define MATCH_MACHINE(x) (x == EM_H8_300)
252#define SHT_RELM SHT_RELA
253#define Elf32_RelM Elf32_Rela
254
255#define ELFCLASSM ELFCLASS32
256#define SYMBOL_PREFIX "_"
257#endif
258
Eric Andersencffd5022002-05-24 06:50:15 +0000259#ifndef SHT_RELM
260#error Sorry, but insmod.c does not yet support this architecture...
261#endif
262
263
Eric Andersen9f16d612000-06-12 23:11:16 +0000264//----------------------------------------------------------------------------
265//--------modutils module.h, lines 45-242
266//----------------------------------------------------------------------------
267
268/* Definitions for the Linux module syscall interface.
269 Copyright 1996, 1997 Linux International.
270
271 Contributed by Richard Henderson <rth@tamu.edu>
272
273 This file is part of the Linux modutils.
274
275 This program is free software; you can redistribute it and/or modify it
276 under the terms of the GNU General Public License as published by the
277 Free Software Foundation; either version 2 of the License, or (at your
278 option) any later version.
279
280 This program is distributed in the hope that it will be useful, but
281 WITHOUT ANY WARRANTY; without even the implied warranty of
282 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
283 General Public License for more details.
284
285 You should have received a copy of the GNU General Public License
286 along with this program; if not, write to the Free Software Foundation,
287 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
288
289
290#ifndef MODUTILS_MODULE_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000291static const int MODUTILS_MODULE_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000292
Robert Griebl809387f2004-07-20 15:43:57 +0000293#ident "$Id: insmod.c,v 1.122 2004/07/20 15:43:57 sandman Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000294
295/*======================================================================*/
296/* For sizeof() which are related to the module platform and not to the
297 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
298
299#define tgt_sizeof_char sizeof(char)
300#define tgt_sizeof_short sizeof(short)
301#define tgt_sizeof_int sizeof(int)
302#define tgt_sizeof_long sizeof(long)
303#define tgt_sizeof_char_p sizeof(char *)
304#define tgt_sizeof_void_p sizeof(void *)
305#define tgt_long long
306
307#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
308#undef tgt_sizeof_long
309#undef tgt_sizeof_char_p
310#undef tgt_sizeof_void_p
311#undef tgt_long
Mark Whitley59ab0252001-01-23 22:30:04 +0000312static const int tgt_sizeof_long = 8;
313static const int tgt_sizeof_char_p = 8;
314static const int tgt_sizeof_void_p = 8;
Eric Andersen9f16d612000-06-12 23:11:16 +0000315#define tgt_long long long
316#endif
317
318/*======================================================================*/
319/* The structures used in Linux 2.1. */
320
321/* Note: new_module_symbol does not use tgt_long intentionally */
322struct new_module_symbol
323{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000324 unsigned long value;
325 unsigned long name;
Eric Andersen9f16d612000-06-12 23:11:16 +0000326};
327
328struct new_module_persist;
329
330struct new_module_ref
331{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000332 unsigned tgt_long dep; /* kernel addresses */
333 unsigned tgt_long ref;
334 unsigned tgt_long next_ref;
Eric Andersen9f16d612000-06-12 23:11:16 +0000335};
336
337struct new_module
338{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000339 unsigned tgt_long size_of_struct; /* == sizeof(module) */
340 unsigned tgt_long next;
341 unsigned tgt_long name;
342 unsigned tgt_long size;
Eric Andersen9f16d612000-06-12 23:11:16 +0000343
Eric Andersen3b1a7442003-12-24 20:30:45 +0000344 tgt_long usecount;
345 unsigned tgt_long flags; /* AUTOCLEAN et al */
Eric Andersen9f16d612000-06-12 23:11:16 +0000346
Eric Andersen3b1a7442003-12-24 20:30:45 +0000347 unsigned nsyms;
348 unsigned ndeps;
Eric Andersen9f16d612000-06-12 23:11:16 +0000349
Eric Andersen3b1a7442003-12-24 20:30:45 +0000350 unsigned tgt_long syms;
351 unsigned tgt_long deps;
352 unsigned tgt_long refs;
353 unsigned tgt_long init;
354 unsigned tgt_long cleanup;
355 unsigned tgt_long ex_table_start;
356 unsigned tgt_long ex_table_end;
Eric Andersen9f16d612000-06-12 23:11:16 +0000357#ifdef __alpha__
Eric Andersen3b1a7442003-12-24 20:30:45 +0000358 unsigned tgt_long gp;
Eric Andersen9f16d612000-06-12 23:11:16 +0000359#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +0000360 /* Everything after here is extension. */
361 unsigned tgt_long persist_start;
362 unsigned tgt_long persist_end;
363 unsigned tgt_long can_unload;
364 unsigned tgt_long runsize;
Eric Andersen3b1a7442003-12-24 20:30:45 +0000365 const char *kallsyms_start; /* All symbols for kernel debugging */
366 const char *kallsyms_end;
367 const char *archdata_start; /* arch specific data for module */
368 const char *archdata_end;
369 const char *kernel_data; /* Reserved for kernel internal use */
Eric Andersen9f16d612000-06-12 23:11:16 +0000370};
371
Eric Andersencffd5022002-05-24 06:50:15 +0000372#ifdef ARCHDATAM
373#define ARCHDATA_SEC_NAME ARCHDATAM
374#else
Eric Andersen8ae319a2001-05-21 16:09:18 +0000375#define ARCHDATA_SEC_NAME "__archdata"
Eric Andersencffd5022002-05-24 06:50:15 +0000376#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +0000377#define KALLSYMS_SEC_NAME "__kallsyms"
378
379
Eric Andersen9f16d612000-06-12 23:11:16 +0000380struct new_module_info
381{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000382 unsigned long addr;
383 unsigned long size;
384 unsigned long flags;
385 long usecount;
Eric Andersen9f16d612000-06-12 23:11:16 +0000386};
387
388/* Bits of module.flags. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000389static const int NEW_MOD_RUNNING = 1;
390static const int NEW_MOD_DELETED = 2;
391static const int NEW_MOD_AUTOCLEAN = 4;
392static const int NEW_MOD_VISITED = 8;
393static const int NEW_MOD_USED_ONCE = 16;
Eric Andersen9f16d612000-06-12 23:11:16 +0000394
Eric Andersencb3b9b12004-06-22 11:50:52 +0000395int init_module(const char *name, const struct new_module *);
396int query_module(const char *name, int which, void *buf,
397 size_t bufsize, size_t *ret);
Eric Andersen9f16d612000-06-12 23:11:16 +0000398
399/* Values for query_module's which. */
400
Mark Whitley59ab0252001-01-23 22:30:04 +0000401static const int QM_MODULES = 1;
402static const int QM_DEPS = 2;
403static const int QM_REFS = 3;
404static const int QM_SYMBOLS = 4;
405static const int QM_INFO = 5;
Eric Andersen9f16d612000-06-12 23:11:16 +0000406
407/*======================================================================*/
408/* The system calls unchanged between 2.0 and 2.1. */
409
410unsigned long create_module(const char *, size_t);
411int delete_module(const char *);
412
413
414#endif /* module.h */
415
416//----------------------------------------------------------------------------
417//--------end of modutils module.h
418//----------------------------------------------------------------------------
419
420
421
422//----------------------------------------------------------------------------
423//--------modutils obj.h, lines 253-462
424//----------------------------------------------------------------------------
425
426/* Elf object file loading and relocation routines.
427 Copyright 1996, 1997 Linux International.
428
429 Contributed by Richard Henderson <rth@tamu.edu>
430
431 This file is part of the Linux modutils.
432
433 This program is free software; you can redistribute it and/or modify it
434 under the terms of the GNU General Public License as published by the
435 Free Software Foundation; either version 2 of the License, or (at your
436 option) any later version.
437
438 This program is distributed in the hope that it will be useful, but
439 WITHOUT ANY WARRANTY; without even the implied warranty of
440 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
441 General Public License for more details.
442
443 You should have received a copy of the GNU General Public License
444 along with this program; if not, write to the Free Software Foundation,
445 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
446
447
448#ifndef MODUTILS_OBJ_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000449static const int MODUTILS_OBJ_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000450
Robert Griebl809387f2004-07-20 15:43:57 +0000451#ident "$Id: insmod.c,v 1.122 2004/07/20 15:43:57 sandman Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000452
453/* The relocatable object is manipulated using elfin types. */
454
455#include <stdio.h>
456#include <elf.h>
Eric Andersenb1591d12002-04-12 00:28:59 +0000457#include <endian.h>
458
459#if __BYTE_ORDER == __LITTLE_ENDIAN
460#define ELFDATAM ELFDATA2LSB
461#elif __BYTE_ORDER == __BIG_ENDIAN
462#define ELFDATAM ELFDATA2MSB
463#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000464
Eric Andersen9f16d612000-06-12 23:11:16 +0000465#ifndef ElfW
466# if ELFCLASSM == ELFCLASS32
467# define ElfW(x) Elf32_ ## x
468# define ELFW(x) ELF32_ ## x
469# else
470# define ElfW(x) Elf64_ ## x
471# define ELFW(x) ELF64_ ## x
472# endif
473#endif
474
Eric Andersen85e5e722003-07-22 08:56:55 +0000475/* For some reason this is missing from some ancient C libraries.... */
Eric Andersen9f16d612000-06-12 23:11:16 +0000476#ifndef ELF32_ST_INFO
477# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
478#endif
479
480#ifndef ELF64_ST_INFO
481# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
482#endif
483
484struct obj_string_patch;
485struct obj_symbol_patch;
486
487struct obj_section
488{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000489 ElfW(Shdr) header;
490 const char *name;
491 char *contents;
492 struct obj_section *load_next;
493 int idx;
Eric Andersen9f16d612000-06-12 23:11:16 +0000494};
495
496struct obj_symbol
497{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000498 struct obj_symbol *next; /* hash table link */
499 const char *name;
500 unsigned long value;
501 unsigned long size;
502 int secidx; /* the defining section index/module */
503 int info;
504 int ksymidx; /* for export to the kernel symtab */
505 int referenced; /* actually used in the link */
Eric Andersen9f16d612000-06-12 23:11:16 +0000506};
507
508/* Hardcode the hash table size. We shouldn't be needing so many
509 symbols that we begin to degrade performance, and we get a big win
510 by giving the compiler a constant divisor. */
511
512#define HASH_BUCKETS 521
513
514struct obj_file
515{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000516 ElfW(Ehdr) header;
517 ElfW(Addr) baseaddr;
518 struct obj_section **sections;
519 struct obj_section *load_order;
520 struct obj_section **load_order_search_start;
521 struct obj_string_patch *string_patches;
522 struct obj_symbol_patch *symbol_patches;
523 int (*symbol_cmp)(const char *, const char *);
524 unsigned long (*symbol_hash)(const char *);
525 unsigned long local_symtab_size;
526 struct obj_symbol **local_symtab;
527 struct obj_symbol *symtab[HASH_BUCKETS];
Eric Andersen9f16d612000-06-12 23:11:16 +0000528};
529
530enum obj_reloc
531{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000532 obj_reloc_ok,
533 obj_reloc_overflow,
534 obj_reloc_dangerous,
535 obj_reloc_unhandled
Eric Andersen9f16d612000-06-12 23:11:16 +0000536};
537
538struct obj_string_patch
539{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000540 struct obj_string_patch *next;
541 int reloc_secidx;
542 ElfW(Addr) reloc_offset;
543 ElfW(Addr) string_offset;
Eric Andersen9f16d612000-06-12 23:11:16 +0000544};
545
546struct obj_symbol_patch
547{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000548 struct obj_symbol_patch *next;
549 int reloc_secidx;
550 ElfW(Addr) reloc_offset;
551 struct obj_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000552};
553
554
555/* Generic object manipulation routines. */
556
Eric Andersen044228d2001-07-17 01:12:36 +0000557static unsigned long obj_elf_hash(const char *);
Eric Andersen9f16d612000-06-12 23:11:16 +0000558
Eric Andersen044228d2001-07-17 01:12:36 +0000559static unsigned long obj_elf_hash_n(const char *, unsigned long len);
Eric Andersen9f16d612000-06-12 23:11:16 +0000560
Eric Andersen044228d2001-07-17 01:12:36 +0000561static struct obj_symbol *obj_find_symbol (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000562 const char *name);
563
Eric Andersen044228d2001-07-17 01:12:36 +0000564static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000565 struct obj_symbol *sym);
566
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000567#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen044228d2001-07-17 01:12:36 +0000568static void obj_set_symbol_compare(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000569 int (*cmp)(const char *, const char *),
570 unsigned long (*hash)(const char *));
Eric Andersenf672c9e2001-07-31 22:51:49 +0000571#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000572
Eric Andersen044228d2001-07-17 01:12:36 +0000573static struct obj_section *obj_find_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000574 const char *name);
575
Eric Andersen044228d2001-07-17 01:12:36 +0000576static void obj_insert_section_load_order (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000577 struct obj_section *sec);
578
Eric Andersen044228d2001-07-17 01:12:36 +0000579static struct obj_section *obj_create_alloced_section (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000580 const char *name,
581 unsigned long align,
582 unsigned long size);
583
Eric Andersen044228d2001-07-17 01:12:36 +0000584static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000585 const char *name,
586 unsigned long align,
587 unsigned long size);
588
Eric Andersen044228d2001-07-17 01:12:36 +0000589static void *obj_extend_section (struct obj_section *sec, unsigned long more);
Eric Andersen9f16d612000-06-12 23:11:16 +0000590
Eric Andersen044228d2001-07-17 01:12:36 +0000591static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000592 const char *string);
593
Eric Andersen044228d2001-07-17 01:12:36 +0000594static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
Eric Andersen9f16d612000-06-12 23:11:16 +0000595 struct obj_symbol *sym);
596
Eric Andersen044228d2001-07-17 01:12:36 +0000597static int obj_check_undefineds(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000598
Eric Andersen044228d2001-07-17 01:12:36 +0000599static void obj_allocate_commons(struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000600
Eric Andersen044228d2001-07-17 01:12:36 +0000601static unsigned long obj_load_size (struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000602
Eric Andersen044228d2001-07-17 01:12:36 +0000603static int obj_relocate (struct obj_file *f, ElfW(Addr) base);
Eric Andersen9f16d612000-06-12 23:11:16 +0000604
Eric Andersen044228d2001-07-17 01:12:36 +0000605static struct obj_file *obj_load(FILE *f, int loadprogbits);
Eric Andersen9f16d612000-06-12 23:11:16 +0000606
Eric Andersen044228d2001-07-17 01:12:36 +0000607static int obj_create_image (struct obj_file *f, char *image);
Eric Andersen9f16d612000-06-12 23:11:16 +0000608
609/* Architecture specific manipulation routines. */
610
Eric Andersen044228d2001-07-17 01:12:36 +0000611static struct obj_file *arch_new_file (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000612
Eric Andersen044228d2001-07-17 01:12:36 +0000613static struct obj_section *arch_new_section (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000614
Eric Andersen044228d2001-07-17 01:12:36 +0000615static struct obj_symbol *arch_new_symbol (void);
Eric Andersen9f16d612000-06-12 23:11:16 +0000616
Eric Andersen044228d2001-07-17 01:12:36 +0000617static enum obj_reloc arch_apply_relocation (struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +0000618 struct obj_section *targsec,
619 struct obj_section *symsec,
620 struct obj_symbol *sym,
621 ElfW(RelM) *rel, ElfW(Addr) value);
622
Eric Andersencffd5022002-05-24 06:50:15 +0000623static void arch_create_got (struct obj_file *f);
Eric Andersen9f16d612000-06-12 23:11:16 +0000624
Glenn L McGrath759515c2003-08-30 06:00:33 +0000625static int obj_gpl_license(struct obj_file *f, const char **license);
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000626
Eric Andersen9f16d612000-06-12 23:11:16 +0000627#endif /* obj.h */
628//----------------------------------------------------------------------------
629//--------end of modutils obj.h
630//----------------------------------------------------------------------------
631
632
Miles Baderae28b042002-04-01 09:34:25 +0000633/* SPFX is always a string, so it can be concatenated to string constants. */
634#ifdef SYMBOL_PREFIX
635#define SPFX SYMBOL_PREFIX
636#else
637#define SPFX ""
638#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000639
Erik Andersen02104321999-12-17 18:57:34 +0000640
Erik Andersend387d011999-12-21 02:55:11 +0000641#define _PATH_MODULES "/lib/modules"
Mark Whitley59ab0252001-01-23 22:30:04 +0000642static const int STRVERSIONLEN = 32;
Erik Andersend387d011999-12-21 02:55:11 +0000643
Eric Andersen9f16d612000-06-12 23:11:16 +0000644/*======================================================================*/
645
Eric Andersen044228d2001-07-17 01:12:36 +0000646static int flag_force_load = 0;
647static int flag_autoclean = 0;
648static int flag_verbose = 0;
Eric Andersenb493dec2002-07-02 19:14:23 +0000649static int flag_quiet = 0;
Eric Andersen044228d2001-07-17 01:12:36 +0000650static int flag_export = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000651
652
653/*======================================================================*/
654
Eric Andersencffd5022002-05-24 06:50:15 +0000655#if defined(CONFIG_USE_LIST)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000656
Eric Andersencffd5022002-05-24 06:50:15 +0000657struct arch_list_entry
Eric Andersen21adca72000-12-06 18:18:26 +0000658{
Eric Andersencffd5022002-05-24 06:50:15 +0000659 struct arch_list_entry *next;
660 CONFIG_LIST_ARCHTYPE addend;
661 int offset;
662 int inited : 1;
Eric Andersen21adca72000-12-06 18:18:26 +0000663};
Eric Andersencffd5022002-05-24 06:50:15 +0000664
Eric Andersen21adca72000-12-06 18:18:26 +0000665#endif
666
Eric Andersencffd5022002-05-24 06:50:15 +0000667#if defined(CONFIG_USE_SINGLE)
668
669struct arch_single_entry
670{
Eric Andersen9f16d612000-06-12 23:11:16 +0000671 int offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000672 int inited : 1;
673 int allocated : 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000674};
Eric Andersencffd5022002-05-24 06:50:15 +0000675
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000676#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000677
Eric Andersen2bf658d2001-02-24 20:01:53 +0000678#if defined(__mips__)
679struct mips_hi16
680{
Eric Andersen3b1a7442003-12-24 20:30:45 +0000681 struct mips_hi16 *next;
682 Elf32_Addr *addr;
683 Elf32_Addr value;
Eric Andersen2bf658d2001-02-24 20:01:53 +0000684};
685#endif
686
Eric Andersenfe4208f2000-09-24 03:44:29 +0000687struct arch_file {
Eric Andersen9f16d612000-06-12 23:11:16 +0000688 struct obj_file root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000689#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000690 struct obj_section *plt;
Eric Andersen21adca72000-12-06 18:18:26 +0000691#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000692#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000693 struct obj_section *got;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000694#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000695#if defined(__mips__)
696 struct mips_hi16 *mips_hi16_list;
697#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000698};
699
Eric Andersenfe4208f2000-09-24 03:44:29 +0000700struct arch_symbol {
Eric Andersen9f16d612000-06-12 23:11:16 +0000701 struct obj_symbol root;
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000702#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000703#if defined(CONFIG_USE_PLT_LIST)
704 struct arch_list_entry *pltent;
705#else
706 struct arch_single_entry pltent;
707#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000708#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000709#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +0000710 struct arch_single_entry gotent;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000711#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000712};
713
714
Eric Andersen9f16d612000-06-12 23:11:16 +0000715struct external_module {
716 const char *name;
717 ElfW(Addr) addr;
718 int used;
719 size_t nsyms;
720 struct new_module_symbol *syms;
721};
722
Eric Andersen044228d2001-07-17 01:12:36 +0000723static struct new_module_symbol *ksyms;
724static size_t nksyms;
Eric Andersen9f16d612000-06-12 23:11:16 +0000725
Eric Andersen044228d2001-07-17 01:12:36 +0000726static struct external_module *ext_modules;
727static int n_ext_modules;
728static int n_ext_modules_used;
Erik Andersen02104321999-12-17 18:57:34 +0000729extern int delete_module(const char *);
Eric Andersena2a978a2001-04-05 06:08:14 +0000730
Eric Andersen61f83052002-06-22 17:15:42 +0000731static char *m_filename;
Robert Griebld378c312002-07-19 00:05:54 +0000732static char *m_fullName;
Erik Andersen02104321999-12-17 18:57:34 +0000733
Eric Andersenfe4208f2000-09-24 03:44:29 +0000734
Erik Andersen02104321999-12-17 18:57:34 +0000735
Eric Andersen9f16d612000-06-12 23:11:16 +0000736/*======================================================================*/
Erik Andersen02104321999-12-17 18:57:34 +0000737
Eric Andersen9f16d612000-06-12 23:11:16 +0000738
Eric Andersen14d35432001-05-14 17:07:32 +0000739static int check_module_name_match(const char *filename, struct stat *statbuf,
740 void *userdata)
Eric Andersen9f16d612000-06-12 23:11:16 +0000741{
Eric Andersen14d35432001-05-14 17:07:32 +0000742 char *fullname = (char *) userdata;
Eric Andersen9f16d612000-06-12 23:11:16 +0000743
Eric Andersen14d35432001-05-14 17:07:32 +0000744 if (fullname[0] == '\0')
Erik Andersene49d5ec2000-02-08 19:58:47 +0000745 return (FALSE);
746 else {
Manuel Novoa III cad53642003-03-19 09:13:01 +0000747 char *tmp, *tmp1 = bb_xstrdup(filename);
748 tmp = bb_get_last_path_component(tmp1);
Eric Andersen14d35432001-05-14 17:07:32 +0000749 if (strcmp(tmp, fullname) == 0) {
750 free(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000751 /* Stop searching if we find a match */
Manuel Novoa III cad53642003-03-19 09:13:01 +0000752 m_filename = bb_xstrdup(filename);
Eric Andersen3f47c452004-04-06 11:56:26 +0000753 return (FALSE);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000754 }
Eric Andersen14d35432001-05-14 17:07:32 +0000755 free(tmp1);
Erik Andersend387d011999-12-21 02:55:11 +0000756 }
Eric Andersen3f47c452004-04-06 11:56:26 +0000757 return (TRUE);
Erik Andersend387d011999-12-21 02:55:11 +0000758}
759
Erik Andersen02104321999-12-17 18:57:34 +0000760
Eric Andersen9f16d612000-06-12 23:11:16 +0000761/*======================================================================*/
762
Eric Andersen044228d2001-07-17 01:12:36 +0000763static struct obj_file *arch_new_file(void)
Erik Andersen02104321999-12-17 18:57:34 +0000764{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000765 struct arch_file *f;
Eric Andersen9f16d612000-06-12 23:11:16 +0000766 f = xmalloc(sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000767
Eric Andersencffd5022002-05-24 06:50:15 +0000768 memset(f, 0, sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000769
Eric Andersen9f16d612000-06-12 23:11:16 +0000770 return &f->root;
771}
772
Eric Andersen044228d2001-07-17 01:12:36 +0000773static struct obj_section *arch_new_section(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000774{
775 return xmalloc(sizeof(struct obj_section));
776}
777
Eric Andersen044228d2001-07-17 01:12:36 +0000778static struct obj_symbol *arch_new_symbol(void)
Eric Andersen9f16d612000-06-12 23:11:16 +0000779{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000780 struct arch_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000781 sym = xmalloc(sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000782
Eric Andersencffd5022002-05-24 06:50:15 +0000783 memset(sym, 0, sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000784
Eric Andersen9f16d612000-06-12 23:11:16 +0000785 return &sym->root;
786}
Eric Andersenfe4208f2000-09-24 03:44:29 +0000787
Eric Andersen044228d2001-07-17 01:12:36 +0000788static enum obj_reloc
Eric Andersen9f16d612000-06-12 23:11:16 +0000789arch_apply_relocation(struct obj_file *f,
790 struct obj_section *targsec,
791 struct obj_section *symsec,
792 struct obj_symbol *sym,
Eric Andersen21adca72000-12-06 18:18:26 +0000793 ElfW(RelM) *rel, ElfW(Addr) v)
Eric Andersen9f16d612000-06-12 23:11:16 +0000794{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000795 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersencffd5022002-05-24 06:50:15 +0000796 enum obj_reloc ret = obj_reloc_ok;
Eric Andersen21adca72000-12-06 18:18:26 +0000797 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
798 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
Eric Andersencffd5022002-05-24 06:50:15 +0000799#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
800 struct arch_symbol *isym = (struct arch_symbol *) sym;
801#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000802#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000803 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000804#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +0000805#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000806 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
Eric Andersen21adca72000-12-06 18:18:26 +0000807 unsigned long *ip;
Eric Andersencffd5022002-05-24 06:50:15 +0000808#if defined(CONFIG_USE_PLT_LIST)
809 struct arch_list_entry *pe;
810#else
811 struct arch_single_entry *pe;
Eric Andersen21adca72000-12-06 18:18:26 +0000812#endif
Eric Andersencffd5022002-05-24 06:50:15 +0000813#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000814
815 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersenfe4208f2000-09-24 03:44:29 +0000816
Eric Andersencffd5022002-05-24 06:50:15 +0000817
818#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +0000819 case R_ARM_NONE:
820 break;
Eric Andersen9f16d612000-06-12 23:11:16 +0000821
Eric Andersen3b1a7442003-12-24 20:30:45 +0000822 case R_ARM_ABS32:
823 *loc += v;
824 break;
Miles Baderae28b042002-04-01 09:34:25 +0000825
Eric Andersen3b1a7442003-12-24 20:30:45 +0000826 case R_ARM_GOT32:
827 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +0000828
Eric Andersen3b1a7442003-12-24 20:30:45 +0000829 case R_ARM_GOTPC:
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000830 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_
831 * (which is .got) similar to branch,
Eric Andersen3b1a7442003-12-24 20:30:45 +0000832 * but is full 32 bits relative */
Eric Andersencffd5022002-05-24 06:50:15 +0000833
Eric Andersen3b1a7442003-12-24 20:30:45 +0000834 assert(got);
835 *loc += got - dot;
836 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000837
Eric Andersen3b1a7442003-12-24 20:30:45 +0000838 case R_ARM_PC24:
839 case R_ARM_PLT32:
840 goto bb_use_plt;
841
842 case R_ARM_GOTOFF: /* address relative to the got */
843 assert(got);
844 *loc += v - got;
845 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000846
Eric Andersenbf77f612003-01-23 06:02:39 +0000847#elif defined(__s390__)
Eric Andersen3b1a7442003-12-24 20:30:45 +0000848 case R_390_32:
849 *(unsigned int *) loc += v;
850 break;
851 case R_390_16:
852 *(unsigned short *) loc += v;
853 break;
854 case R_390_8:
855 *(unsigned char *) loc += v;
856 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000857
Eric Andersen3b1a7442003-12-24 20:30:45 +0000858 case R_390_PC32:
859 *(unsigned int *) loc += v - dot;
860 break;
861 case R_390_PC16DBL:
862 *(unsigned short *) loc += (v - dot) >> 1;
863 break;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000864 case R_390_PC16:
Eric Andersen3b1a7442003-12-24 20:30:45 +0000865 *(unsigned short *) loc += v - dot;
866 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000867
Eric Andersen3b1a7442003-12-24 20:30:45 +0000868 case R_390_PLT32:
869 case R_390_PLT16DBL:
870 /* find the plt entry and initialize it. */
871 assert(isym != NULL);
872 pe = (struct arch_single_entry *) &isym->pltent;
873 assert(pe->allocated);
874 if (pe->inited == 0) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000875 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
Eric Andersen3b1a7442003-12-24 20:30:45 +0000876 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
877 ip[1] = 0x100607f1;
878 if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
879 ip[2] = v - 2;
880 else
881 ip[2] = v;
882 pe->inited = 1;
883 }
Eric Andersenbf77f612003-01-23 06:02:39 +0000884
Eric Andersen3b1a7442003-12-24 20:30:45 +0000885 /* Insert relative distance to target. */
886 v = plt + pe->offset - dot;
887 if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32)
888 *(unsigned int *) loc = (unsigned int) v;
889 else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
890 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
891 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000892
Eric Andersen3b1a7442003-12-24 20:30:45 +0000893 case R_390_GLOB_DAT:
894 case R_390_JMP_SLOT:
895 *loc = v;
896 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000897
Eric Andersen3b1a7442003-12-24 20:30:45 +0000898 case R_390_RELATIVE:
899 *loc += f->baseaddr;
900 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000901
Eric Andersen3b1a7442003-12-24 20:30:45 +0000902 case R_390_GOTPC:
903 assert(got != 0);
904 *(unsigned long *) loc += got - dot;
905 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000906
Eric Andersen3b1a7442003-12-24 20:30:45 +0000907 case R_390_GOT12:
908 case R_390_GOT16:
909 case R_390_GOT32:
910 assert(isym != NULL);
911 assert(got != 0);
912 if (!isym->gotent.inited)
913 {
914 isym->gotent.inited = 1;
915 *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
916 }
917 if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12)
918 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
919 else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16)
920 *(unsigned short *) loc += isym->gotent.offset;
921 else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32)
922 *(unsigned int *) loc += isym->gotent.offset;
923 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000924
Eric Andersen951df202003-10-21 06:45:29 +0000925#ifndef R_390_GOTOFF32
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000926#define R_390_GOTOFF32 R_390_GOTOFF
Eric Andersen951df202003-10-21 06:45:29 +0000927#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +0000928 case R_390_GOTOFF32:
929 assert(got != 0);
930 *loc += v - got;
931 break;
Eric Andersenbf77f612003-01-23 06:02:39 +0000932
Eric Andersencffd5022002-05-24 06:50:15 +0000933#elif defined(__i386__)
934
Eric Andersen3b1a7442003-12-24 20:30:45 +0000935 case R_386_NONE:
936 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000937
Eric Andersen3b1a7442003-12-24 20:30:45 +0000938 case R_386_32:
939 *loc += v;
940 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000941
Eric Andersen3b1a7442003-12-24 20:30:45 +0000942 case R_386_PLT32:
943 case R_386_PC32:
944 *loc += v - dot;
945 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000946
Eric Andersen3b1a7442003-12-24 20:30:45 +0000947 case R_386_GLOB_DAT:
948 case R_386_JMP_SLOT:
949 *loc = v;
950 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000951
Eric Andersen3b1a7442003-12-24 20:30:45 +0000952 case R_386_RELATIVE:
953 *loc += f->baseaddr;
954 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000955
Eric Andersen3b1a7442003-12-24 20:30:45 +0000956 case R_386_GOTPC:
957 assert(got != 0);
958 *loc += got - dot;
959 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000960
Eric Andersen3b1a7442003-12-24 20:30:45 +0000961 case R_386_GOT32:
962 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +0000963
Eric Andersen3b1a7442003-12-24 20:30:45 +0000964 case R_386_GOTOFF:
965 assert(got != 0);
966 *loc += v - got;
967 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000968
969#elif defined(__mc68000__)
970
Eric Andersen3b1a7442003-12-24 20:30:45 +0000971 case R_68K_NONE:
972 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000973
Eric Andersen3b1a7442003-12-24 20:30:45 +0000974 case R_68K_32:
975 *loc += v;
976 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000977
Eric Andersen3b1a7442003-12-24 20:30:45 +0000978 case R_68K_8:
979 if (v > 0xff) {
980 ret = obj_reloc_overflow;
981 }
982 *(char *)loc = v;
983 break;
Eric Andersencffd5022002-05-24 06:50:15 +0000984
Eric Andersen3b1a7442003-12-24 20:30:45 +0000985 case R_68K_16:
986 if (v > 0xffff) {
987 ret = obj_reloc_overflow;
988 }
989 *(short *)loc = v;
990 break;
Eric Andersen9f16d612000-06-12 23:11:16 +0000991
Eric Andersen3b1a7442003-12-24 20:30:45 +0000992 case R_68K_PC8:
993 v -= dot;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000994 if ((Elf32_Sword)v > 0x7f ||
Eric Andersen3b1a7442003-12-24 20:30:45 +0000995 (Elf32_Sword)v < -(Elf32_Sword)0x80) {
996 ret = obj_reloc_overflow;
997 }
998 *(char *)loc = v;
999 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001000
Eric Andersen3b1a7442003-12-24 20:30:45 +00001001 case R_68K_PC16:
1002 v -= dot;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001003 if ((Elf32_Sword)v > 0x7fff ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00001004 (Elf32_Sword)v < -(Elf32_Sword)0x8000) {
1005 ret = obj_reloc_overflow;
1006 }
1007 *(short *)loc = v;
1008 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001009
Eric Andersen3b1a7442003-12-24 20:30:45 +00001010 case R_68K_PC32:
1011 *(int *)loc = v - dot;
1012 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001013
Eric Andersen3b1a7442003-12-24 20:30:45 +00001014 case R_68K_GLOB_DAT:
1015 case R_68K_JMP_SLOT:
1016 *loc = v;
1017 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001018
Eric Andersen3b1a7442003-12-24 20:30:45 +00001019 case R_68K_RELATIVE:
1020 *(int *)loc += f->baseaddr;
1021 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001022
Eric Andersen3b1a7442003-12-24 20:30:45 +00001023 case R_68K_GOT32:
1024 goto bb_use_got;
Eric Andersencffd5022002-05-24 06:50:15 +00001025
Eric Andersen16451a02004-03-19 12:16:18 +00001026#ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001027 case R_68K_GOTOFF:
1028 assert(got != 0);
1029 *loc += v - got;
1030 break;
Eric Andersen16451a02004-03-19 12:16:18 +00001031#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001032
1033#elif defined(__mips__)
1034
Eric Andersen3b1a7442003-12-24 20:30:45 +00001035 case R_MIPS_NONE:
1036 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001037
Eric Andersen3b1a7442003-12-24 20:30:45 +00001038 case R_MIPS_32:
1039 *loc += v;
1040 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001041
Eric Andersen3b1a7442003-12-24 20:30:45 +00001042 case R_MIPS_26:
1043 if (v % 4)
1044 ret = obj_reloc_dangerous;
1045 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1046 ret = obj_reloc_overflow;
1047 *loc =
1048 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1049 0x03ffffff);
1050 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001051
Eric Andersen3b1a7442003-12-24 20:30:45 +00001052 case R_MIPS_HI16:
1053 {
1054 struct mips_hi16 *n;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001055
Eric Andersen3b1a7442003-12-24 20:30:45 +00001056 /* We cannot relocate this one now because we don't know the value
1057 of the carry we need to add. Save the information, and let LO16
1058 do the actual relocation. */
1059 n = (struct mips_hi16 *) xmalloc(sizeof *n);
1060 n->addr = loc;
1061 n->value = v;
1062 n->next = ifile->mips_hi16_list;
1063 ifile->mips_hi16_list = n;
1064 break;
Eric Andersen2bf658d2001-02-24 20:01:53 +00001065 }
1066
Eric Andersen3b1a7442003-12-24 20:30:45 +00001067 case R_MIPS_LO16:
1068 {
1069 unsigned long insnlo = *loc;
1070 Elf32_Addr val, vallo;
1071
1072 /* Sign extend the addend we extract from the lo insn. */
1073 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1074
1075 if (ifile->mips_hi16_list != NULL) {
1076 struct mips_hi16 *l;
1077
1078 l = ifile->mips_hi16_list;
1079 while (l != NULL) {
1080 struct mips_hi16 *next;
1081 unsigned long insn;
1082
1083 /* The value for the HI16 had best be the same. */
1084 assert(v == l->value);
1085
1086 /* Do the HI16 relocation. Note that we actually don't
1087 need to know anything about the LO16 itself, except where
1088 to find the low 16 bits of the addend needed by the LO16. */
1089 insn = *l->addr;
1090 val =
1091 ((insn & 0xffff) << 16) +
1092 vallo;
1093 val += v;
1094
1095 /* Account for the sign extension that will happen in the
1096 low bits. */
1097 val =
1098 ((val >> 16) +
1099 ((val & 0x8000) !=
1100 0)) & 0xffff;
1101
1102 insn = (insn & ~0xffff) | val;
1103 *l->addr = insn;
1104
1105 next = l->next;
1106 free(l);
1107 l = next;
1108 }
1109
1110 ifile->mips_hi16_list = NULL;
1111 }
1112
1113 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
1114 val = v + vallo;
1115 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1116 *loc = insnlo;
1117 break;
1118 }
Eric Andersen2bf658d2001-02-24 20:01:53 +00001119
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001120#elif defined(__powerpc__)
Eric Andersencffd5022002-05-24 06:50:15 +00001121
Eric Andersen3b1a7442003-12-24 20:30:45 +00001122 case R_PPC_ADDR16_HA:
1123 *(unsigned short *)loc = (v + 0x8000) >> 16;
1124 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001125
Eric Andersen3b1a7442003-12-24 20:30:45 +00001126 case R_PPC_ADDR16_HI:
1127 *(unsigned short *)loc = v >> 16;
1128 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001129
Eric Andersen3b1a7442003-12-24 20:30:45 +00001130 case R_PPC_ADDR16_LO:
1131 *(unsigned short *)loc = v;
1132 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001133
Eric Andersen3b1a7442003-12-24 20:30:45 +00001134 case R_PPC_REL24:
1135 goto bb_use_plt;
Eric Andersencffd5022002-05-24 06:50:15 +00001136
Eric Andersen3b1a7442003-12-24 20:30:45 +00001137 case R_PPC_REL32:
1138 *loc = v - dot;
1139 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001140
Eric Andersen3b1a7442003-12-24 20:30:45 +00001141 case R_PPC_ADDR32:
1142 *loc = v;
1143 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001144
1145#elif defined(__sh__)
1146
Eric Andersen3b1a7442003-12-24 20:30:45 +00001147 case R_SH_NONE:
1148 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001149
Eric Andersen3b1a7442003-12-24 20:30:45 +00001150 case R_SH_DIR32:
1151 *loc += v;
1152 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001153
Eric Andersen3b1a7442003-12-24 20:30:45 +00001154 case R_SH_REL32:
1155 *loc += v - dot;
1156 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001157
Eric Andersen3b1a7442003-12-24 20:30:45 +00001158 case R_SH_PLT32:
1159 *loc = v - dot;
1160 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001161
Eric Andersen3b1a7442003-12-24 20:30:45 +00001162 case R_SH_GLOB_DAT:
1163 case R_SH_JMP_SLOT:
1164 *loc = v;
1165 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001166
Eric Andersen3b1a7442003-12-24 20:30:45 +00001167 case R_SH_RELATIVE:
1168 *loc = f->baseaddr + rel->r_addend;
1169 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001170
Eric Andersen3b1a7442003-12-24 20:30:45 +00001171 case R_SH_GOTPC:
1172 assert(got != 0);
1173 *loc = got - dot + rel->r_addend;
1174 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001175
Eric Andersen3b1a7442003-12-24 20:30:45 +00001176 case R_SH_GOT32:
1177 goto bb_use_got;
1178
1179 case R_SH_GOTOFF:
1180 assert(got != 0);
1181 *loc = v - got;
1182 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001183
Eric Andersenbf833552003-08-13 19:56:33 +00001184#if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001185 case R_SH_IMM_MEDLOW16:
1186 case R_SH_IMM_LOW16:
1187 {
1188 Elf32_Addr word;
Eric Andersenbf833552003-08-13 19:56:33 +00001189
Eric Andersen3b1a7442003-12-24 20:30:45 +00001190 if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1191 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001192
Eric Andersen3b1a7442003-12-24 20:30:45 +00001193 /*
1194 * movi and shori have the format:
1195 *
1196 * | op | imm | reg | reserved |
1197 * 31..26 25..10 9.. 4 3 .. 0
1198 *
1199 * so we simply mask and or in imm.
1200 */
1201 word = *loc & ~0x3fffc00;
1202 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001203
Eric Andersen3b1a7442003-12-24 20:30:45 +00001204 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001205
Eric Andersen3b1a7442003-12-24 20:30:45 +00001206 break;
1207 }
Eric Andersenbf833552003-08-13 19:56:33 +00001208
Eric Andersen3b1a7442003-12-24 20:30:45 +00001209 case R_SH_IMM_MEDLOW16_PCREL:
1210 case R_SH_IMM_LOW16_PCREL:
1211 {
1212 Elf32_Addr word;
Eric Andersenbf833552003-08-13 19:56:33 +00001213
Eric Andersen3b1a7442003-12-24 20:30:45 +00001214 word = *loc & ~0x3fffc00;
Eric Andersenbf833552003-08-13 19:56:33 +00001215
Eric Andersen3b1a7442003-12-24 20:30:45 +00001216 v -= dot;
Eric Andersenbf833552003-08-13 19:56:33 +00001217
Eric Andersen3b1a7442003-12-24 20:30:45 +00001218 if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1219 v >>= 16;
Eric Andersenbf833552003-08-13 19:56:33 +00001220
Eric Andersen3b1a7442003-12-24 20:30:45 +00001221 word |= (v & 0xffff) << 10;
Eric Andersenbf833552003-08-13 19:56:33 +00001222
Eric Andersen3b1a7442003-12-24 20:30:45 +00001223 *loc = word;
Eric Andersenbf833552003-08-13 19:56:33 +00001224
Eric Andersen3b1a7442003-12-24 20:30:45 +00001225 break;
1226 }
Eric Andersenbf833552003-08-13 19:56:33 +00001227#endif /* __SH5__ */
1228#endif /* __sh__ */
Eric Andersen9f16d612000-06-12 23:11:16 +00001229
Eric Andersen3b1a7442003-12-24 20:30:45 +00001230 default:
1231 printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
1232 ret = obj_reloc_unhandled;
1233 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001234
1235#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001236 case R_V850_NONE:
1237 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001238
Eric Andersen3b1a7442003-12-24 20:30:45 +00001239 case R_V850_32:
1240 /* We write two shorts instead of a long because even
1241 32-bit insns only need half-word alignment, but
1242 32-bit data needs to be long-word aligned. */
1243 v += ((unsigned short *)loc)[0];
1244 v += ((unsigned short *)loc)[1] << 16;
1245 ((unsigned short *)loc)[0] = v & 0xffff;
1246 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1247 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001248
Eric Andersen3b1a7442003-12-24 20:30:45 +00001249 case R_V850_22_PCREL:
1250 goto bb_use_plt;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001251#endif
1252
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001253#if defined (__cris__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001254 case R_CRIS_NONE:
1255 break;
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001256
Eric Andersen3b1a7442003-12-24 20:30:45 +00001257 case R_CRIS_32:
1258 /* CRIS keeps the relocation value in the r_addend field and
1259 * should not use whats in *loc at all
1260 */
1261 *loc = v;
1262 break;
Manuel Novoa III 22e1ca32003-12-04 15:02:57 +00001263#endif
1264
Eric Andersena6f6a952004-05-26 12:06:38 +00001265#if defined(__H8300H__) || defined(__H8300S__)
Eric Andersenee70fa52004-05-26 11:38:46 +00001266 case R_H8_DIR24R8:
1267 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
1268 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
1269 break;
1270 case R_H8_DIR24A8:
1271 *loc += v;
1272 break;
1273 case R_H8_DIR32:
1274 case R_H8_DIR32A16:
1275 *loc += v;
1276 break;
1277 case R_H8_PCREL16:
1278 v -= dot + 2;
1279 if ((Elf32_Sword)v > 0x7fff ||
1280 (Elf32_Sword)v < -(Elf32_Sword)0x8000)
1281 ret = obj_reloc_overflow;
1282 else
1283 *(unsigned short *)loc = v;
1284 break;
1285 case R_H8_PCREL8:
1286 v -= dot + 1;
1287 if ((Elf32_Sword)v > 0x7f ||
1288 (Elf32_Sword)v < -(Elf32_Sword)0x80)
1289 ret = obj_reloc_overflow;
1290 else
1291 *(unsigned char *)loc = v;
1292 break;
1293#endif
1294
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001295#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001296
Eric Andersen3b1a7442003-12-24 20:30:45 +00001297bb_use_plt:
Eric Andersencffd5022002-05-24 06:50:15 +00001298
Eric Andersen3b1a7442003-12-24 20:30:45 +00001299 /* find the plt entry and initialize it if necessary */
1300 assert(isym != NULL);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001301
Eric Andersencffd5022002-05-24 06:50:15 +00001302#if defined(CONFIG_USE_PLT_LIST)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001303 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1304 pe = pe->next;
1305 assert(pe != NULL);
Eric Andersencffd5022002-05-24 06:50:15 +00001306#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001307 pe = &isym->pltent;
Eric Andersencffd5022002-05-24 06:50:15 +00001308#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001309
Eric Andersen3b1a7442003-12-24 20:30:45 +00001310 if (! pe->inited) {
1311 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001312
Eric Andersen3b1a7442003-12-24 20:30:45 +00001313 /* generate some machine code */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001314
1315#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001316 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
1317 ip[1] = v; /* sym@ */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001318#endif
1319#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001320 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
1321 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
1322 ip[2] = 0x7d6903a6; /* mtctr r11 */
1323 ip[3] = 0x4e800420; /* bctr */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001324#endif
Miles Baderae28b042002-04-01 09:34:25 +00001325#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001326 /* We have to trash a register, so we assume that any control
1327 transfer more than 21-bits away must be a function call
1328 (so we can use a call-clobbered register). */
1329 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
1330 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
Miles Baderae28b042002-04-01 09:34:25 +00001331#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001332 pe->inited = 1;
1333 }
Eric Andersen21adca72000-12-06 18:18:26 +00001334
Eric Andersen3b1a7442003-12-24 20:30:45 +00001335 /* relative distance to target */
1336 v -= dot;
1337 /* if the target is too far away.... */
Miles Baderae28b042002-04-01 09:34:25 +00001338#if defined (__arm__) || defined (__powerpc__)
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001339 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
Miles Baderae28b042002-04-01 09:34:25 +00001340#elif defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001341 if ((Elf32_Sword)v > 0x1fffff || (Elf32_Sword)v < (Elf32_Sword)-0x200000)
Miles Baderae28b042002-04-01 09:34:25 +00001342#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001343 /* go via the plt */
1344 v = plt + pe->offset - dot;
Miles Baderae28b042002-04-01 09:34:25 +00001345
1346#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001347 if (v & 1)
Miles Baderae28b042002-04-01 09:34:25 +00001348#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00001349 if (v & 3)
Miles Baderae28b042002-04-01 09:34:25 +00001350#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001351 ret = obj_reloc_dangerous;
Eric Andersen21adca72000-12-06 18:18:26 +00001352
Eric Andersen3b1a7442003-12-24 20:30:45 +00001353 /* merge the offset into the instruction. */
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001354#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001355 /* Convert to words. */
1356 v >>= 2;
Eric Andersen21adca72000-12-06 18:18:26 +00001357
Eric Andersen3b1a7442003-12-24 20:30:45 +00001358 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
Eric Andersenfe4208f2000-09-24 03:44:29 +00001359#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001360#if defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001361 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001362#endif
Miles Baderae28b042002-04-01 09:34:25 +00001363#if defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001364 /* We write two shorts instead of a long because even 32-bit insns
1365 only need half-word alignment, but the 32-bit data write needs
1366 to be long-word aligned. */
1367 ((unsigned short *)loc)[0] =
1368 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
1369 | ((v >> 16) & 0x3f); /* offs high part */
1370 ((unsigned short *)loc)[1] =
1371 (v & 0xffff); /* offs low part */
Miles Baderae28b042002-04-01 09:34:25 +00001372#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001373 break;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001374#endif /* CONFIG_USE_PLT_ENTRIES */
Eric Andersenfe4208f2000-09-24 03:44:29 +00001375
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001376#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001377bb_use_got:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001378
Eric Andersen3b1a7442003-12-24 20:30:45 +00001379 assert(isym != NULL);
1380 /* needs an entry in the .got: set it, once */
1381 if (!isym->gotent.inited) {
1382 isym->gotent.inited = 1;
1383 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1384 }
1385 /* make the reloc with_respect_to_.got */
Eric Andersen21adca72000-12-06 18:18:26 +00001386#if defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001387 *loc += isym->gotent.offset + rel->r_addend;
Eric Andersenb4a26e62001-06-19 15:00:52 +00001388#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001389 *loc += isym->gotent.offset;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001390#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001391 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001392
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001393#endif /* CONFIG_USE_GOT_ENTRIES */
Eric Andersen9f16d612000-06-12 23:11:16 +00001394 }
1395
1396 return ret;
1397}
1398
Eric Andersencffd5022002-05-24 06:50:15 +00001399
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001400#if defined(CONFIG_USE_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001401
1402static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1403 int offset, int size)
1404{
1405 struct arch_list_entry *pe;
1406
1407 for (pe = *list; pe != NULL; pe = pe->next) {
1408 if (pe->addend == rel->r_addend) {
1409 break;
1410 }
1411 }
1412
1413 if (pe == NULL) {
1414 pe = xmalloc(sizeof(struct arch_list_entry));
1415 pe->next = *list;
1416 pe->addend = rel->r_addend;
1417 pe->offset = offset;
1418 pe->inited = 0;
1419 *list = pe;
1420 return size;
1421 }
1422 return 0;
1423}
1424
1425#endif
1426
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001427#if defined(CONFIG_USE_SINGLE)
Eric Andersencffd5022002-05-24 06:50:15 +00001428
1429static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single,
1430 int offset, int size)
1431{
1432 if (single->allocated == 0) {
1433 single->allocated = 1;
1434 single->offset = offset;
1435 single->inited = 0;
1436 return size;
1437 }
1438 return 0;
1439}
1440
1441#endif
1442
1443#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
1444
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001445static struct obj_section *arch_xsect_init(struct obj_file *f, char *name,
Eric Andersencffd5022002-05-24 06:50:15 +00001446 int offset, int size)
1447{
1448 struct obj_section *myrelsec = obj_find_section(f, name);
1449
1450 if (offset == 0) {
1451 offset += size;
1452 }
1453
1454 if (myrelsec) {
1455 obj_extend_section(myrelsec, offset);
1456 } else {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001457 myrelsec = obj_create_alloced_section(f, name,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001458 size, offset);
Eric Andersencffd5022002-05-24 06:50:15 +00001459 assert(myrelsec);
1460 }
1461
1462 return myrelsec;
1463}
1464
1465#endif
1466
1467static void arch_create_got(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00001468{
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001469#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001470 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001471 int i;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001472#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001473 int got_offset = 0, got_needed = 0, got_allocate;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001474#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001475#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001476 int plt_offset = 0, plt_needed = 0, plt_allocate;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001477#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001478 struct obj_section *relsec, *symsec, *strsec;
Eric Andersen21adca72000-12-06 18:18:26 +00001479 ElfW(RelM) *rel, *relend;
1480 ElfW(Sym) *symtab, *extsym;
1481 const char *strtab, *name;
1482 struct arch_symbol *intsym;
Eric Andersen9f16d612000-06-12 23:11:16 +00001483
Eric Andersen21adca72000-12-06 18:18:26 +00001484 for (i = 0; i < f->header.e_shnum; ++i) {
1485 relsec = f->sections[i];
1486 if (relsec->header.sh_type != SHT_RELM)
Eric Andersen9f16d612000-06-12 23:11:16 +00001487 continue;
1488
Eric Andersen21adca72000-12-06 18:18:26 +00001489 symsec = f->sections[relsec->header.sh_link];
1490 strsec = f->sections[symsec->header.sh_link];
Eric Andersen9f16d612000-06-12 23:11:16 +00001491
Eric Andersen21adca72000-12-06 18:18:26 +00001492 rel = (ElfW(RelM) *) relsec->contents;
1493 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1494 symtab = (ElfW(Sym) *) symsec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00001495 strtab = (const char *) strsec->contents;
1496
1497 for (; rel < relend; ++rel) {
Eric Andersen21adca72000-12-06 18:18:26 +00001498 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
Eric Andersen9f16d612000-06-12 23:11:16 +00001499
Eric Andersencffd5022002-05-24 06:50:15 +00001500#if defined(CONFIG_USE_GOT_ENTRIES)
1501 got_allocate = 0;
1502#endif
1503#if defined(CONFIG_USE_PLT_ENTRIES)
1504 plt_allocate = 0;
1505#endif
1506
Eric Andersen9f16d612000-06-12 23:11:16 +00001507 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersen21adca72000-12-06 18:18:26 +00001508#if defined(__arm__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001509 case R_ARM_PC24:
1510 case R_ARM_PLT32:
1511 plt_allocate = 1;
1512 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001513
Eric Andersen3b1a7442003-12-24 20:30:45 +00001514 case R_ARM_GOTOFF:
1515 case R_ARM_GOTPC:
1516 got_needed = 1;
1517 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001518
Eric Andersen3b1a7442003-12-24 20:30:45 +00001519 case R_ARM_GOT32:
1520 got_allocate = 1;
1521 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001522
Eric Andersen21adca72000-12-06 18:18:26 +00001523#elif defined(__i386__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001524 case R_386_GOTPC:
1525 case R_386_GOTOFF:
1526 got_needed = 1;
1527 continue;
Eric Andersen21adca72000-12-06 18:18:26 +00001528
Eric Andersen3b1a7442003-12-24 20:30:45 +00001529 case R_386_GOT32:
1530 got_allocate = 1;
1531 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001532
1533#elif defined(__powerpc__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001534 case R_PPC_REL24:
1535 plt_allocate = 1;
1536 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001537
1538#elif defined(__mc68000__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001539 case R_68K_GOT32:
1540 got_allocate = 1;
1541 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001542
Eric Andersen16451a02004-03-19 12:16:18 +00001543#ifdef R_68K_GOTOFF
Eric Andersen3b1a7442003-12-24 20:30:45 +00001544 case R_68K_GOTOFF:
1545 got_needed = 1;
1546 continue;
Eric Andersen16451a02004-03-19 12:16:18 +00001547#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001548
1549#elif defined(__sh__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001550 case R_SH_GOT32:
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001551 got_allocate = 1;
Eric Andersen3b1a7442003-12-24 20:30:45 +00001552 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001553
Eric Andersen3b1a7442003-12-24 20:30:45 +00001554 case R_SH_GOTPC:
1555 case R_SH_GOTOFF:
1556 got_needed = 1;
1557 continue;
Eric Andersencffd5022002-05-24 06:50:15 +00001558
1559#elif defined (__v850e__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00001560 case R_V850_22_PCREL:
1561 plt_needed = 1;
1562 break;
Eric Andersencffd5022002-05-24 06:50:15 +00001563
1564#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00001565 default:
1566 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00001567 }
1568
Eric Andersen21adca72000-12-06 18:18:26 +00001569 if (extsym->st_name != 0) {
Eric Andersen9f16d612000-06-12 23:11:16 +00001570 name = strtab + extsym->st_name;
Eric Andersen21adca72000-12-06 18:18:26 +00001571 } else {
Eric Andersen9f16d612000-06-12 23:11:16 +00001572 name = f->sections[extsym->st_shndx]->name;
Eric Andersen21adca72000-12-06 18:18:26 +00001573 }
1574 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001575#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001576 if (got_allocate) {
1577 got_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001578 rel, &intsym->gotent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001579 got_offset, CONFIG_GOT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001580
1581 got_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001582 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001583#endif
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001584#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001585 if (plt_allocate) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001586#if defined(CONFIG_USE_PLT_LIST)
Eric Andersencffd5022002-05-24 06:50:15 +00001587 plt_offset += arch_list_add(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001588 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001589 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001590#else
1591 plt_offset += arch_single_init(
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001592 rel, &intsym->pltent,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001593 plt_offset, CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001594#endif
1595 plt_needed = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001596 }
1597#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001598 }
Miles Baderae28b042002-04-01 09:34:25 +00001599 }
Eric Andersen21adca72000-12-06 18:18:26 +00001600
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001601#if defined(CONFIG_USE_GOT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001602 if (got_needed) {
1603 ifile->got = arch_xsect_init(f, ".got", got_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001604 CONFIG_GOT_ENTRY_SIZE);
Eric Andersen9f16d612000-06-12 23:11:16 +00001605 }
Eric Andersen21adca72000-12-06 18:18:26 +00001606#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001607
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001608#if defined(CONFIG_USE_PLT_ENTRIES)
Eric Andersencffd5022002-05-24 06:50:15 +00001609 if (plt_needed) {
1610 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001611 CONFIG_PLT_ENTRY_SIZE);
Eric Andersencffd5022002-05-24 06:50:15 +00001612 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001613#endif
Eric Andersencffd5022002-05-24 06:50:15 +00001614
1615#endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */
Eric Andersen9f16d612000-06-12 23:11:16 +00001616}
1617
Eric Andersen9f16d612000-06-12 23:11:16 +00001618/*======================================================================*/
1619
1620/* Standard ELF hash function. */
Eric Andersen044228d2001-07-17 01:12:36 +00001621static inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
Eric Andersen9f16d612000-06-12 23:11:16 +00001622{
1623 unsigned long h = 0;
1624 unsigned long g;
1625 unsigned char ch;
1626
1627 while (n > 0) {
1628 ch = *name++;
1629 h = (h << 4) + ch;
1630 if ((g = (h & 0xf0000000)) != 0) {
1631 h ^= g >> 24;
1632 h &= ~g;
1633 }
1634 n--;
1635 }
1636 return h;
1637}
1638
Eric Andersen044228d2001-07-17 01:12:36 +00001639static unsigned long obj_elf_hash(const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001640{
1641 return obj_elf_hash_n(name, strlen(name));
1642}
1643
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001644#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00001645/* String comparison for non-co-versioned kernel and module. */
1646
1647static int ncv_strcmp(const char *a, const char *b)
1648{
1649 size_t alen = strlen(a), blen = strlen(b);
1650
1651 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1652 return strncmp(a, b, alen);
1653 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1654 return strncmp(a, b, blen);
1655 else
1656 return strcmp(a, b);
1657}
1658
1659/* String hashing for non-co-versioned kernel and module. Here
1660 we are simply forced to drop the crc from the hash. */
1661
1662static unsigned long ncv_symbol_hash(const char *str)
1663{
1664 size_t len = strlen(str);
1665 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1666 len -= 10;
1667 return obj_elf_hash_n(str, len);
1668}
1669
Eric Andersen044228d2001-07-17 01:12:36 +00001670static void
Eric Andersen9f16d612000-06-12 23:11:16 +00001671obj_set_symbol_compare(struct obj_file *f,
1672 int (*cmp) (const char *, const char *),
1673 unsigned long (*hash) (const char *))
1674{
1675 if (cmp)
1676 f->symbol_cmp = cmp;
1677 if (hash) {
1678 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1679 int i;
1680
1681 f->symbol_hash = hash;
1682
1683 memcpy(tmptab, f->symtab, sizeof(tmptab));
1684 memset(f->symtab, 0, sizeof(f->symtab));
1685
1686 for (i = 0; i < HASH_BUCKETS; ++i)
1687 for (sym = tmptab[i]; sym; sym = next) {
1688 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1689 next = sym->next;
1690 sym->next = f->symtab[h];
1691 f->symtab[h] = sym;
1692 }
1693 }
1694}
1695
Eric Andersenbdfd0d72001-10-24 05:00:29 +00001696#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00001697
Eric Andersen044228d2001-07-17 01:12:36 +00001698static struct obj_symbol *
1699obj_add_symbol(struct obj_file *f, const char *name,
Eric Andersen9f16d612000-06-12 23:11:16 +00001700 unsigned long symidx, int info,
1701 int secidx, ElfW(Addr) value,
1702 unsigned long size)
1703{
1704 struct obj_symbol *sym;
1705 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1706 int n_type = ELFW(ST_TYPE) (info);
1707 int n_binding = ELFW(ST_BIND) (info);
1708
1709 for (sym = f->symtab[hash]; sym; sym = sym->next)
1710 if (f->symbol_cmp(sym->name, name) == 0) {
1711 int o_secidx = sym->secidx;
1712 int o_info = sym->info;
1713 int o_type = ELFW(ST_TYPE) (o_info);
1714 int o_binding = ELFW(ST_BIND) (o_info);
1715
1716 /* A redefinition! Is it legal? */
1717
1718 if (secidx == SHN_UNDEF)
1719 return sym;
1720 else if (o_secidx == SHN_UNDEF)
1721 goto found;
1722 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1723 /* Cope with local and global symbols of the same name
1724 in the same object file, as might have been created
1725 by ld -r. The only reason locals are now seen at this
1726 level at all is so that we can do semi-sensible things
1727 with parameters. */
1728
1729 struct obj_symbol *nsym, **p;
1730
1731 nsym = arch_new_symbol();
1732 nsym->next = sym->next;
1733 nsym->ksymidx = -1;
1734
1735 /* Excise the old (local) symbol from the hash chain. */
1736 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1737 continue;
1738 *p = sym = nsym;
1739 goto found;
1740 } else if (n_binding == STB_LOCAL) {
1741 /* Another symbol of the same name has already been defined.
1742 Just add this to the local table. */
1743 sym = arch_new_symbol();
1744 sym->next = NULL;
1745 sym->ksymidx = -1;
1746 f->local_symtab[symidx] = sym;
1747 goto found;
1748 } else if (n_binding == STB_WEAK)
1749 return sym;
1750 else if (o_binding == STB_WEAK)
1751 goto found;
1752 /* Don't unify COMMON symbols with object types the programmer
1753 doesn't expect. */
1754 else if (secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00001755 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00001756 return sym;
1757 else if (o_secidx == SHN_COMMON
Eric Andersen3b1a7442003-12-24 20:30:45 +00001758 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
Eric Andersen9f16d612000-06-12 23:11:16 +00001759 goto found;
1760 else {
1761 /* Don't report an error if the symbol is coming from
1762 the kernel or some external module. */
1763 if (secidx <= SHN_HIRESERVE)
Manuel Novoa III cad53642003-03-19 09:13:01 +00001764 bb_error_msg("%s multiply defined", name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001765 return sym;
1766 }
1767 }
1768
1769 /* Completely new symbol. */
1770 sym = arch_new_symbol();
1771 sym->next = f->symtab[hash];
1772 f->symtab[hash] = sym;
1773 sym->ksymidx = -1;
1774
Eric Andersen66ca9482001-06-28 21:36:06 +00001775 if (ELFW(ST_BIND)(info) == STB_LOCAL && symidx != -1) {
1776 if (symidx >= f->local_symtab_size)
Manuel Novoa III cad53642003-03-19 09:13:01 +00001777 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
Eric Andersen66ca9482001-06-28 21:36:06 +00001778 name, (long) symidx, (long) f->local_symtab_size);
1779 else
1780 f->local_symtab[symidx] = sym;
1781 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001782
Eric Andersen3b1a7442003-12-24 20:30:45 +00001783found:
Eric Andersen9f16d612000-06-12 23:11:16 +00001784 sym->name = name;
1785 sym->value = value;
1786 sym->size = size;
1787 sym->secidx = secidx;
1788 sym->info = info;
1789
1790 return sym;
1791}
1792
Eric Andersen044228d2001-07-17 01:12:36 +00001793static struct obj_symbol *
1794obj_find_symbol(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001795{
1796 struct obj_symbol *sym;
1797 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1798
1799 for (sym = f->symtab[hash]; sym; sym = sym->next)
1800 if (f->symbol_cmp(sym->name, name) == 0)
1801 return sym;
1802
1803 return NULL;
1804}
1805
Eric Andersen044228d2001-07-17 01:12:36 +00001806static ElfW(Addr)
Eric Andersen9f16d612000-06-12 23:11:16 +00001807 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1808{
1809 if (sym) {
1810 if (sym->secidx >= SHN_LORESERVE)
1811 return sym->value;
1812
1813 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1814 } else {
1815 /* As a special case, a NULL sym has value zero. */
1816 return 0;
1817 }
1818}
1819
Eric Andersen044228d2001-07-17 01:12:36 +00001820static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001821{
1822 int i, n = f->header.e_shnum;
1823
1824 for (i = 0; i < n; ++i)
1825 if (strcmp(f->sections[i]->name, name) == 0)
1826 return f->sections[i];
1827
1828 return NULL;
1829}
1830
1831static int obj_load_order_prio(struct obj_section *a)
1832{
1833 unsigned long af, ac;
1834
1835 af = a->header.sh_flags;
1836
1837 ac = 0;
1838 if (a->name[0] != '.' || strlen(a->name) != 10 ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00001839 strcmp(a->name + 5, ".init"))
Eric Andersen9f16d612000-06-12 23:11:16 +00001840 ac |= 32;
1841 if (af & SHF_ALLOC)
1842 ac |= 16;
1843 if (!(af & SHF_WRITE))
1844 ac |= 8;
1845 if (af & SHF_EXECINSTR)
1846 ac |= 4;
1847 if (a->header.sh_type != SHT_NOBITS)
1848 ac |= 2;
1849
1850 return ac;
1851}
1852
Eric Andersen044228d2001-07-17 01:12:36 +00001853static void
Eric Andersen9f16d612000-06-12 23:11:16 +00001854obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1855{
1856 struct obj_section **p;
1857 int prio = obj_load_order_prio(sec);
1858 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1859 if (obj_load_order_prio(*p) < prio)
1860 break;
1861 sec->load_next = *p;
1862 *p = sec;
1863}
1864
Eric Andersen044228d2001-07-17 01:12:36 +00001865static struct obj_section *obj_create_alloced_section(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001866 const char *name,
1867 unsigned long align,
1868 unsigned long size)
1869{
1870 int newidx = f->header.e_shnum++;
1871 struct obj_section *sec;
1872
1873 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1874 f->sections[newidx] = sec = arch_new_section();
1875
1876 memset(sec, 0, sizeof(*sec));
1877 sec->header.sh_type = SHT_PROGBITS;
1878 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1879 sec->header.sh_size = size;
1880 sec->header.sh_addralign = align;
1881 sec->name = name;
1882 sec->idx = newidx;
1883 if (size)
1884 sec->contents = xmalloc(size);
1885
1886 obj_insert_section_load_order(f, sec);
1887
1888 return sec;
1889}
1890
Eric Andersen044228d2001-07-17 01:12:36 +00001891static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001892 const char *name,
1893 unsigned long align,
1894 unsigned long size)
1895{
1896 int newidx = f->header.e_shnum++;
1897 struct obj_section *sec;
1898
1899 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1900 f->sections[newidx] = sec = arch_new_section();
1901
1902 memset(sec, 0, sizeof(*sec));
1903 sec->header.sh_type = SHT_PROGBITS;
1904 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1905 sec->header.sh_size = size;
1906 sec->header.sh_addralign = align;
1907 sec->name = name;
1908 sec->idx = newidx;
1909 if (size)
1910 sec->contents = xmalloc(size);
1911
1912 sec->load_next = f->load_order;
1913 f->load_order = sec;
1914 if (f->load_order_search_start == &f->load_order)
1915 f->load_order_search_start = &sec->load_next;
1916
1917 return sec;
1918}
1919
Eric Andersen044228d2001-07-17 01:12:36 +00001920static void *obj_extend_section(struct obj_section *sec, unsigned long more)
Eric Andersen9f16d612000-06-12 23:11:16 +00001921{
1922 unsigned long oldsize = sec->header.sh_size;
Eric Andersenc7bda1c2004-03-15 08:29:22 +00001923 if (more) {
Eric Andersen7f3b86e2001-04-26 19:29:58 +00001924 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1925 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001926 return sec->contents + oldsize;
1927}
1928
1929
Eric Andersen9f16d612000-06-12 23:11:16 +00001930/* Conditionally add the symbols from the given symbol set to the
1931 new module. */
1932
1933static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00001934add_symbols_from( struct obj_file *f,
Eric Andersen9f16d612000-06-12 23:11:16 +00001935 int idx, struct new_module_symbol *syms, size_t nsyms)
1936{
1937 struct new_module_symbol *s;
1938 size_t i;
1939 int used = 0;
Miles Baderae28b042002-04-01 09:34:25 +00001940#ifdef SYMBOL_PREFIX
1941 char *name_buf = 0;
1942 size_t name_alloced_size = 0;
1943#endif
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001944#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
1945 int gpl;
Eric Andersen9f16d612000-06-12 23:11:16 +00001946
Glenn L McGrath759515c2003-08-30 06:00:33 +00001947 gpl = obj_gpl_license(f, NULL) == 0;
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001948#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001949 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
Miles Baderae28b042002-04-01 09:34:25 +00001950 /* Only add symbols that are already marked external.
1951 If we override locals we may cause problems for
1952 argument initialization. We will also create a false
1953 dependency on the module. */
Eric Andersen9f16d612000-06-12 23:11:16 +00001954 struct obj_symbol *sym;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00001955 char *name;
Eric Andersen9f16d612000-06-12 23:11:16 +00001956
Glenn L McGrath759515c2003-08-30 06:00:33 +00001957 /* GPL licensed modules can use symbols exported with
1958 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the
1959 * exported names. Non-GPL modules never see any GPLONLY_
1960 * symbols so they cannot fudge it by adding the prefix on
1961 * their references.
1962 */
1963 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001964#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Glenn L McGrath759515c2003-08-30 06:00:33 +00001965 if (gpl)
1966 ((char *)s->name) += 8;
1967 else
Glenn L McGrath759d7ec2003-09-03 00:42:58 +00001968#endif
Glenn L McGrath759515c2003-08-30 06:00:33 +00001969 continue;
1970 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00001971 name = (char *)s->name;
Glenn L McGrath759515c2003-08-30 06:00:33 +00001972
Miles Baderae28b042002-04-01 09:34:25 +00001973#ifdef SYMBOL_PREFIX
1974 /* Prepend SYMBOL_PREFIX to the symbol's name (the
1975 kernel exports `C names', but module object files
1976 reference `linker names'). */
1977 size_t extra = sizeof SYMBOL_PREFIX;
1978 size_t name_size = strlen (name) + extra;
1979 if (name_size > name_alloced_size) {
1980 name_alloced_size = name_size * 2;
1981 name_buf = alloca (name_alloced_size);
1982 }
1983 strcpy (name_buf, SYMBOL_PREFIX);
1984 strcpy (name_buf + extra - 1, name);
1985 name = name_buf;
1986#endif /* SYMBOL_PREFIX */
1987
1988 sym = obj_find_symbol(f, name);
1989 if (sym && !(ELFW(ST_BIND) (sym->info) == STB_LOCAL)) {
1990#ifdef SYMBOL_PREFIX
1991 /* Put NAME_BUF into more permanent storage. */
1992 name = xmalloc (name_size);
1993 strcpy (name, name_buf);
1994#endif
1995 sym = obj_add_symbol(f, name, -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00001996 ELFW(ST_INFO) (STB_GLOBAL,
1997 STT_NOTYPE),
1998 idx, s->value, 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00001999 /* Did our symbol just get installed? If so, mark the
2000 module as "used". */
2001 if (sym->secidx == idx)
2002 used = 1;
2003 }
2004 }
2005
2006 return used;
2007}
2008
2009static void add_kernel_symbols(struct obj_file *f)
2010{
2011 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00002012 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002013
2014 /* Add module symbols first. */
2015
2016 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
2017 if (m->nsyms
Eric Andersen3b1a7442003-12-24 20:30:45 +00002018 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
2019 m->nsyms)) m->used = 1, ++nused;
Eric Andersen9f16d612000-06-12 23:11:16 +00002020
2021 n_ext_modules_used = nused;
2022
2023 /* And finally the symbols from the kernel proper. */
2024
2025 if (nksyms)
2026 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2027}
2028
2029static char *get_modinfo_value(struct obj_file *f, const char *key)
2030{
2031 struct obj_section *sec;
2032 char *p, *v, *n, *ep;
2033 size_t klen = strlen(key);
2034
2035 sec = obj_find_section(f, ".modinfo");
2036 if (sec == NULL)
2037 return NULL;
2038 p = sec->contents;
2039 ep = p + sec->header.sh_size;
2040 while (p < ep) {
2041 v = strchr(p, '=');
2042 n = strchr(p, '\0');
2043 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002044 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002045 return v + 1;
2046 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00002047 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002048 return n;
2049 }
2050 p = n + 1;
2051 }
2052
2053 return NULL;
2054}
2055
2056
2057/*======================================================================*/
Eric Andersen9f16d612000-06-12 23:11:16 +00002058/* Functions relating to module loading after 2.1.18. */
2059
2060static int
2061new_process_module_arguments(struct obj_file *f, int argc, char **argv)
2062{
2063 while (argc > 0) {
Miles Baderae28b042002-04-01 09:34:25 +00002064 char *p, *q, *key, *sym_name;
Eric Andersen9f16d612000-06-12 23:11:16 +00002065 struct obj_symbol *sym;
2066 char *contents, *loc;
2067 int min, max, n;
2068
2069 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00002070 if ((q = strchr(p, '=')) == NULL) {
2071 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00002072 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002073 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002074
2075 key = alloca(q - p + 6);
2076 memcpy(key, "parm_", 5);
2077 memcpy(key + 5, p, q - p);
2078 key[q - p + 5] = 0;
2079
2080 p = get_modinfo_value(f, key);
2081 key += 5;
2082 if (p == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002083 bb_error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002084 return 0;
2085 }
2086
Miles Baderae28b042002-04-01 09:34:25 +00002087#ifdef SYMBOL_PREFIX
2088 sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);
2089 strcpy (sym_name, SYMBOL_PREFIX);
2090 strcat (sym_name, key);
2091#else
2092 sym_name = key;
2093#endif
2094 sym = obj_find_symbol(f, sym_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002095
2096 /* Also check that the parameter was not resolved from the kernel. */
2097 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002098 bb_error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002099 return 0;
2100 }
2101
2102 if (isdigit(*p)) {
2103 min = strtoul(p, &p, 10);
2104 if (*p == '-')
2105 max = strtoul(p + 1, &p, 10);
2106 else
2107 max = min;
2108 } else
2109 min = max = 1;
2110
2111 contents = f->sections[sym->secidx]->contents;
2112 loc = contents + sym->value;
2113 n = (*++q != '\0');
2114
2115 while (1) {
2116 if ((*p == 's') || (*p == 'c')) {
2117 char *str;
2118
2119 /* Do C quoting if we begin with a ", else slurp the lot. */
2120 if (*q == '"') {
2121 char *r;
2122
2123 str = alloca(strlen(q));
2124 for (r = str, q++; *q != '"'; ++q, ++r) {
2125 if (*q == '\0') {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002126 bb_error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002127 key);
2128 return 0;
2129 } else if (*q == '\\')
2130 switch (*++q) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002131 case 'a':
2132 *r = '\a';
2133 break;
2134 case 'b':
2135 *r = '\b';
2136 break;
2137 case 'e':
2138 *r = '\033';
2139 break;
2140 case 'f':
2141 *r = '\f';
2142 break;
2143 case 'n':
2144 *r = '\n';
2145 break;
2146 case 'r':
2147 *r = '\r';
2148 break;
2149 case 't':
2150 *r = '\t';
2151 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002152
Eric Andersen3b1a7442003-12-24 20:30:45 +00002153 case '0':
2154 case '1':
2155 case '2':
2156 case '3':
2157 case '4':
2158 case '5':
2159 case '6':
2160 case '7':
2161 {
2162 int c = *q - '0';
2163 if (q[1] >= '0' && q[1] <= '7') {
Eric Andersen9f16d612000-06-12 23:11:16 +00002164 c = (c * 8) + *++q - '0';
Eric Andersen3b1a7442003-12-24 20:30:45 +00002165 if (q[1] >= '0' && q[1] <= '7')
2166 c = (c * 8) + *++q - '0';
2167 }
2168 *r = c;
Eric Andersen9f16d612000-06-12 23:11:16 +00002169 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002170 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002171
Eric Andersen3b1a7442003-12-24 20:30:45 +00002172 default:
2173 *r = *q;
2174 break;
2175 } else
Eric Andersen9f16d612000-06-12 23:11:16 +00002176 *r = *q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002177 }
2178 *r = '\0';
2179 ++q;
2180 } else {
2181 char *r;
2182
2183 /* In this case, the string is not quoted. We will break
2184 it using the coma (like for ints). If the user wants to
2185 include comas in a string, he just has to quote it */
2186
2187 /* Search the next coma */
2188 r = strchr(q, ',');
2189
2190 /* Found ? */
2191 if (r != (char *) NULL) {
2192 /* Recopy the current field */
2193 str = alloca(r - q + 1);
2194 memcpy(str, q, r - q);
2195
Eric Andersenaff114c2004-04-14 17:51:38 +00002196 /* I don't know if it is useful, as the previous case
2197 doesn't nul terminate the string ??? */
Eric Andersen9f16d612000-06-12 23:11:16 +00002198 str[r - q] = '\0';
2199
2200 /* Keep next fields */
2201 q = r;
2202 } else {
2203 /* last string */
2204 str = q;
2205 q = "";
2206 }
2207 }
2208
2209 if (*p == 's') {
2210 /* Normal string */
2211 obj_string_patch(f, sym->secidx, loc - contents, str);
2212 loc += tgt_sizeof_char_p;
2213 } else {
2214 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002215 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002216
2217 /* Get the size of each member */
2218 /* Probably we should do that outside the loop ? */
2219 if (!isdigit(*(p + 1))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002220 bb_error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002221 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002222 return 0;
2223 }
2224 charssize = strtoul(p + 1, (char **) NULL, 10);
2225
2226 /* Check length */
2227 if (strlen(str) >= charssize) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002228 bb_error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002229 charssize - 1);
2230 return 0;
2231 }
2232
2233 /* Copy to location */
2234 strcpy((char *) loc, str);
2235 loc += charssize;
2236 }
2237 } else {
2238 long v = strtoul(q, &q, 0);
2239 switch (*p) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002240 case 'b':
2241 *loc++ = v;
2242 break;
2243 case 'h':
2244 *(short *) loc = v;
2245 loc += tgt_sizeof_short;
2246 break;
2247 case 'i':
2248 *(int *) loc = v;
2249 loc += tgt_sizeof_int;
2250 break;
2251 case 'l':
2252 *(long *) loc = v;
2253 loc += tgt_sizeof_long;
2254 break;
2255
2256 default:
2257 bb_error_msg("unknown parameter type '%c' for %s", *p, key);
2258 return 0;
2259 }
2260 }
2261
2262retry_end_of_value:
2263 switch (*q) {
2264 case '\0':
2265 goto end_of_arg;
2266
2267 case ' ':
2268 case '\t':
2269 case '\n':
2270 case '\r':
2271 ++q;
2272 goto retry_end_of_value;
2273
2274 case ',':
2275 if (++n > max) {
2276 bb_error_msg("too many values for %s (max %d)", key, max);
2277 return 0;
2278 }
2279 ++q;
Eric Andersen9f16d612000-06-12 23:11:16 +00002280 break;
2281
2282 default:
Eric Andersen3b1a7442003-12-24 20:30:45 +00002283 bb_error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002284 return 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00002285 }
2286 }
2287
Eric Andersen3b1a7442003-12-24 20:30:45 +00002288end_of_arg:
Eric Andersen9f16d612000-06-12 23:11:16 +00002289 if (n < min) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002290 bb_error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002291 return 0;
2292 }
2293
2294 argc--, argv++;
2295 }
2296
2297 return 1;
2298}
2299
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002300#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00002301static int new_is_module_checksummed(struct obj_file *f)
2302{
2303 const char *p = get_modinfo_value(f, "using_checksums");
2304 if (p)
2305 return atoi(p);
2306 else
2307 return 0;
2308}
2309
2310/* Get the module's kernel version in the canonical integer form. */
2311
2312static int
2313new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2314{
2315 char *p, *q;
2316 int a, b, c;
2317
2318 p = get_modinfo_value(f, "kernel_version");
2319 if (p == NULL)
2320 return -1;
Eric Andersen2d342152002-06-18 05:16:25 +00002321 safe_strncpy(str, p, STRVERSIONLEN);
Eric Andersen9f16d612000-06-12 23:11:16 +00002322
2323 a = strtoul(p, &p, 10);
2324 if (*p != '.')
2325 return -1;
2326 b = strtoul(p + 1, &p, 10);
2327 if (*p != '.')
2328 return -1;
2329 c = strtoul(p + 1, &q, 10);
2330 if (p + 1 == q)
2331 return -1;
2332
2333 return a << 16 | b << 8 | c;
2334}
2335
Eric Andersenbdfd0d72001-10-24 05:00:29 +00002336#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00002337
2338
Eric Andersen9f16d612000-06-12 23:11:16 +00002339/* Fetch the loaded modules, and all currently exported symbols. */
2340
2341static int new_get_kernel_symbols(void)
2342{
2343 char *module_names, *mn;
2344 struct external_module *modules, *m;
2345 struct new_module_symbol *syms, *s;
2346 size_t ret, bufsize, nmod, nsyms, i, j;
2347
2348 /* Collect the loaded modules. */
2349
2350 module_names = xmalloc(bufsize = 256);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002351retry_modules_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002352 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002353 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002354 module_names = xrealloc(module_names, bufsize = ret);
2355 goto retry_modules_load;
2356 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002357 bb_perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002358 return 0;
2359 }
2360
2361 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002362
2363 /* Collect the modules' symbols. */
2364
Mark Whitley94fd4802001-03-12 23:08:34 +00002365 if (nmod){
2366 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2367 memset(modules, 0, nmod * sizeof(*modules));
2368 for (i = 0, mn = module_names, m = modules;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002369 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
Mark Whitley94fd4802001-03-12 23:08:34 +00002370 struct new_module_info info;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002371
Mark Whitley94fd4802001-03-12 23:08:34 +00002372 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2373 if (errno == ENOENT) {
2374 /* The module was removed out from underneath us. */
2375 continue;
2376 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002377 bb_perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002378 return 0;
2379 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00002380
Mark Whitley94fd4802001-03-12 23:08:34 +00002381 syms = xmalloc(bufsize = 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002382retry_mod_sym_load:
Mark Whitley94fd4802001-03-12 23:08:34 +00002383 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2384 switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002385 case ENOSPC:
2386 syms = xrealloc(syms, bufsize = ret);
2387 goto retry_mod_sym_load;
2388 case ENOENT:
2389 /* The module was removed out from underneath us. */
2390 continue;
2391 default:
2392 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn);
2393 return 0;
Mark Whitley94fd4802001-03-12 23:08:34 +00002394 }
2395 }
2396 nsyms = ret;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002397
Mark Whitley94fd4802001-03-12 23:08:34 +00002398 m->name = mn;
2399 m->addr = info.addr;
2400 m->nsyms = nsyms;
2401 m->syms = syms;
Eric Andersen3b1a7442003-12-24 20:30:45 +00002402
Mark Whitley94fd4802001-03-12 23:08:34 +00002403 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2404 s->name += (unsigned long) syms;
2405 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002406 }
2407 }
2408
2409 /* Collect the kernel's symbols. */
2410
2411 syms = xmalloc(bufsize = 16 * 1024);
Eric Andersen3b1a7442003-12-24 20:30:45 +00002412retry_kern_sym_load:
Eric Andersen9f16d612000-06-12 23:11:16 +00002413 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002414 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002415 syms = xrealloc(syms, bufsize = ret);
2416 goto retry_kern_sym_load;
2417 }
Manuel Novoa III cad53642003-03-19 09:13:01 +00002418 bb_perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002419 return 0;
2420 }
2421 nksyms = nsyms = ret;
2422 ksyms = syms;
2423
2424 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2425 s->name += (unsigned long) syms;
2426 }
2427 return 1;
2428}
2429
2430
2431/* Return the kernel symbol checksum version, or zero if not used. */
2432
2433static int new_is_kernel_checksummed(void)
2434{
2435 struct new_module_symbol *s;
2436 size_t i;
2437
2438 /* Using_Versions is not the first symbol, but it should be in there. */
2439
2440 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2441 if (strcmp((char *) s->name, "Using_Versions") == 0)
2442 return s->value;
2443
2444 return 0;
2445}
2446
2447
2448static int new_create_this_module(struct obj_file *f, const char *m_name)
2449{
2450 struct obj_section *sec;
2451
2452 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002453 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002454 memset(sec->contents, 0, sizeof(struct new_module));
2455
Miles Baderae28b042002-04-01 09:34:25 +00002456 obj_add_symbol(f, SPFX "__this_module", -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002457 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2458 sizeof(struct new_module));
Eric Andersen9f16d612000-06-12 23:11:16 +00002459
2460 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
Eric Andersen3b1a7442003-12-24 20:30:45 +00002461 m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002462
2463 return 1;
2464}
2465
Eric Andersen889dd202003-01-23 04:48:34 +00002466#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2467/* add an entry to the __ksymtab section, creating it if necessary */
2468static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2469{
2470 struct obj_section *sec;
2471 ElfW(Addr) ofs;
2472
2473 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section.
2474 * If __ksymtab is defined but not marked alloc, x out the first character
2475 * (no obj_delete routine) and create a new __ksymtab with the correct
2476 * characteristics.
2477 */
2478 sec = obj_find_section(f, "__ksymtab");
2479 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2480 *((char *)(sec->name)) = 'x'; /* override const */
2481 sec = NULL;
2482 }
2483 if (!sec)
2484 sec = obj_create_alloced_section(f, "__ksymtab",
Eric Andersen3b1a7442003-12-24 20:30:45 +00002485 tgt_sizeof_void_p, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00002486 if (!sec)
2487 return;
2488 sec->header.sh_flags |= SHF_ALLOC;
2489 sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might
Eric Andersen3b1a7442003-12-24 20:30:45 +00002490 be byte-aligned */
Eric Andersen889dd202003-01-23 04:48:34 +00002491 ofs = sec->header.sh_size;
2492 obj_symbol_patch(f, sec->idx, ofs, sym);
2493 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2494 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2495}
2496#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
Eric Andersen9f16d612000-06-12 23:11:16 +00002497
2498static int new_create_module_ksymtab(struct obj_file *f)
2499{
2500 struct obj_section *sec;
2501 int i;
2502
2503 /* We must always add the module references. */
2504
2505 if (n_ext_modules_used) {
2506 struct new_module_ref *dep;
2507 struct obj_symbol *tm;
2508
2509 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002510 (sizeof(struct new_module_ref)
2511 * n_ext_modules_used));
Eric Andersen9f16d612000-06-12 23:11:16 +00002512 if (!sec)
2513 return 0;
2514
Miles Baderae28b042002-04-01 09:34:25 +00002515 tm = obj_find_symbol(f, SPFX "__this_module");
Eric Andersen9f16d612000-06-12 23:11:16 +00002516 dep = (struct new_module_ref *) sec->contents;
2517 for (i = 0; i < n_ext_modules; ++i)
2518 if (ext_modules[i].used) {
2519 dep->dep = ext_modules[i].addr;
2520 obj_symbol_patch(f, sec->idx,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002521 (char *) &dep->ref - sec->contents, tm);
Eric Andersen9f16d612000-06-12 23:11:16 +00002522 dep->next_ref = 0;
2523 ++dep;
2524 }
2525 }
2526
2527 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2528 size_t nsyms;
2529 int *loaded;
2530
2531 sec =
2532 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002533 0);
Eric Andersen9f16d612000-06-12 23:11:16 +00002534
2535 /* We don't want to export symbols residing in sections that
2536 aren't loaded. There are a number of these created so that
2537 we make sure certain module options don't appear twice. */
2538
2539 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2540 while (--i >= 0)
2541 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2542
2543 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2544 struct obj_symbol *sym;
2545 for (sym = f->symtab[i]; sym; sym = sym->next)
2546 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
Eric Andersen3b1a7442003-12-24 20:30:45 +00002547 && sym->secidx <= SHN_HIRESERVE
2548 && (sym->secidx >= SHN_LORESERVE
2549 || loaded[sym->secidx])) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002550 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2551
2552 obj_symbol_patch(f, sec->idx, ofs, sym);
2553 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
Eric Andersen3b1a7442003-12-24 20:30:45 +00002554 sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002555
2556 nsyms++;
2557 }
2558 }
2559
2560 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2561 }
2562
2563 return 1;
2564}
2565
2566
2567static int
Eric Andersencb3b9b12004-06-22 11:50:52 +00002568new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
Eric Andersen9f16d612000-06-12 23:11:16 +00002569{
2570 struct new_module *module;
2571 struct obj_section *sec;
2572 void *image;
2573 int ret;
2574 tgt_long m_addr;
2575
2576 sec = obj_find_section(f, ".this");
Eric Andersenc7bda1c2004-03-15 08:29:22 +00002577 if (!sec || !sec->contents) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002578 bb_perror_msg_and_die("corrupt module %s?",m_name);
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002579 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002580 module = (struct new_module *) sec->contents;
2581 m_addr = sec->header.sh_addr;
2582
2583 module->size_of_struct = sizeof(*module);
2584 module->size = m_size;
2585 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2586
2587 sec = obj_find_section(f, "__ksymtab");
2588 if (sec && sec->header.sh_size) {
2589 module->syms = sec->header.sh_addr;
2590 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2591 }
2592
2593 if (n_ext_modules_used) {
2594 sec = obj_find_section(f, ".kmodtab");
2595 module->deps = sec->header.sh_addr;
2596 module->ndeps = n_ext_modules_used;
2597 }
2598
2599 module->init =
Miles Baderae28b042002-04-01 09:34:25 +00002600 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002601 module->cleanup =
Miles Baderae28b042002-04-01 09:34:25 +00002602 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
Eric Andersen9f16d612000-06-12 23:11:16 +00002603
2604 sec = obj_find_section(f, "__ex_table");
2605 if (sec) {
2606 module->ex_table_start = sec->header.sh_addr;
2607 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2608 }
2609
2610 sec = obj_find_section(f, ".text.init");
2611 if (sec) {
2612 module->runsize = sec->header.sh_addr - m_addr;
2613 }
2614 sec = obj_find_section(f, ".data.init");
2615 if (sec) {
2616 if (!module->runsize ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002617 module->runsize > sec->header.sh_addr - m_addr)
2618 module->runsize = sec->header.sh_addr - m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00002619 }
Eric Andersen8ae319a2001-05-21 16:09:18 +00002620 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2621 if (sec && sec->header.sh_size) {
2622 module->archdata_start = (void*)sec->header.sh_addr;
2623 module->archdata_end = module->archdata_start + sec->header.sh_size;
2624 }
2625 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2626 if (sec && sec->header.sh_size) {
2627 module->kallsyms_start = (void*)sec->header.sh_addr;
2628 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2629 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002630
Eric Andersen9f16d612000-06-12 23:11:16 +00002631 /* Whew! All of the initialization is complete. Collect the final
2632 module image and give it to the kernel. */
2633
2634 image = xmalloc(m_size);
2635 obj_create_image(f, image);
2636
Eric Andersencb3b9b12004-06-22 11:50:52 +00002637 ret = init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002638 if (ret)
Manuel Novoa III cad53642003-03-19 09:13:01 +00002639 bb_perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002640
2641 free(image);
2642
2643 return ret == 0;
2644}
2645
Eric Andersen9f16d612000-06-12 23:11:16 +00002646
2647/*======================================================================*/
2648
Eric Andersen044228d2001-07-17 01:12:36 +00002649static int
Eric Andersen9f16d612000-06-12 23:11:16 +00002650obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2651 const char *string)
2652{
2653 struct obj_string_patch *p;
2654 struct obj_section *strsec;
2655 size_t len = strlen(string) + 1;
2656 char *loc;
2657
2658 p = xmalloc(sizeof(*p));
2659 p->next = f->string_patches;
2660 p->reloc_secidx = secidx;
2661 p->reloc_offset = offset;
2662 f->string_patches = p;
2663
2664 strsec = obj_find_section(f, ".kstrtab");
2665 if (strsec == NULL) {
2666 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2667 p->string_offset = 0;
2668 loc = strsec->contents;
2669 } else {
2670 p->string_offset = strsec->header.sh_size;
2671 loc = obj_extend_section(strsec, len);
2672 }
2673 memcpy(loc, string, len);
2674
2675 return 1;
2676}
2677
Eric Andersen044228d2001-07-17 01:12:36 +00002678static int
Eric Andersen9f16d612000-06-12 23:11:16 +00002679obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2680 struct obj_symbol *sym)
2681{
2682 struct obj_symbol_patch *p;
2683
2684 p = xmalloc(sizeof(*p));
2685 p->next = f->symbol_patches;
2686 p->reloc_secidx = secidx;
2687 p->reloc_offset = offset;
2688 p->sym = sym;
2689 f->symbol_patches = p;
2690
2691 return 1;
2692}
2693
Eric Andersen044228d2001-07-17 01:12:36 +00002694static int obj_check_undefineds(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002695{
2696 unsigned long i;
2697 int ret = 1;
2698
2699 for (i = 0; i < HASH_BUCKETS; ++i) {
2700 struct obj_symbol *sym;
2701 for (sym = f->symtab[i]; sym; sym = sym->next)
2702 if (sym->secidx == SHN_UNDEF) {
2703 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2704 sym->secidx = SHN_ABS;
2705 sym->value = 0;
2706 } else {
Eric Andersenb493dec2002-07-02 19:14:23 +00002707 if (!flag_quiet) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00002708 bb_error_msg("unresolved symbol %s", sym->name);
Eric Andersenb493dec2002-07-02 19:14:23 +00002709 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002710 ret = 0;
2711 }
2712 }
2713 }
2714
2715 return ret;
2716}
2717
Eric Andersen044228d2001-07-17 01:12:36 +00002718static void obj_allocate_commons(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002719{
2720 struct common_entry {
2721 struct common_entry *next;
2722 struct obj_symbol *sym;
2723 } *common_head = NULL;
2724
2725 unsigned long i;
2726
2727 for (i = 0; i < HASH_BUCKETS; ++i) {
2728 struct obj_symbol *sym;
2729 for (sym = f->symtab[i]; sym; sym = sym->next)
2730 if (sym->secidx == SHN_COMMON) {
2731 /* Collect all COMMON symbols and sort them by size so as to
2732 minimize space wasted by alignment requirements. */
2733 {
2734 struct common_entry **p, *n;
2735 for (p = &common_head; *p; p = &(*p)->next)
2736 if (sym->size <= (*p)->sym->size)
2737 break;
2738
2739 n = alloca(sizeof(*n));
2740 n->next = *p;
2741 n->sym = sym;
2742 *p = n;
2743 }
2744 }
2745 }
2746
2747 for (i = 1; i < f->local_symtab_size; ++i) {
2748 struct obj_symbol *sym = f->local_symtab[i];
2749 if (sym && sym->secidx == SHN_COMMON) {
2750 struct common_entry **p, *n;
2751 for (p = &common_head; *p; p = &(*p)->next)
2752 if (sym == (*p)->sym)
2753 break;
2754 else if (sym->size < (*p)->sym->size) {
2755 n = alloca(sizeof(*n));
2756 n->next = *p;
2757 n->sym = sym;
2758 *p = n;
2759 break;
2760 }
2761 }
2762 }
2763
2764 if (common_head) {
2765 /* Find the bss section. */
2766 for (i = 0; i < f->header.e_shnum; ++i)
2767 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2768 break;
2769
2770 /* If for some reason there hadn't been one, create one. */
2771 if (i == f->header.e_shnum) {
2772 struct obj_section *sec;
2773
2774 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2775 f->sections[i] = sec = arch_new_section();
2776 f->header.e_shnum = i + 1;
2777
2778 memset(sec, 0, sizeof(*sec));
2779 sec->header.sh_type = SHT_PROGBITS;
2780 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2781 sec->name = ".bss";
2782 sec->idx = i;
2783 }
2784
2785 /* Allocate the COMMONS. */
2786 {
2787 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2788 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2789 struct common_entry *c;
2790
2791 for (c = common_head; c; c = c->next) {
2792 ElfW(Addr) align = c->sym->value;
2793
2794 if (align > max_align)
2795 max_align = align;
2796 if (bss_size & (align - 1))
2797 bss_size = (bss_size | (align - 1)) + 1;
2798
2799 c->sym->secidx = i;
2800 c->sym->value = bss_size;
2801
2802 bss_size += c->sym->size;
2803 }
2804
2805 f->sections[i]->header.sh_size = bss_size;
2806 f->sections[i]->header.sh_addralign = max_align;
2807 }
2808 }
2809
2810 /* For the sake of patch relocation and parameter initialization,
2811 allocate zeroed data for NOBITS sections now. Note that after
2812 this we cannot assume NOBITS are really empty. */
2813 for (i = 0; i < f->header.e_shnum; ++i) {
2814 struct obj_section *s = f->sections[i];
2815 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00002816 if (s->header.sh_size != 0)
Eric Andersen3b1a7442003-12-24 20:30:45 +00002817 s->contents = memset(xmalloc(s->header.sh_size),
2818 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00002819 else
2820 s->contents = NULL;
2821
Eric Andersen9f16d612000-06-12 23:11:16 +00002822 s->header.sh_type = SHT_PROGBITS;
2823 }
2824 }
2825}
2826
Eric Andersen044228d2001-07-17 01:12:36 +00002827static unsigned long obj_load_size(struct obj_file *f)
Eric Andersen9f16d612000-06-12 23:11:16 +00002828{
2829 unsigned long dot = 0;
2830 struct obj_section *sec;
2831
2832 /* Finalize the positions of the sections relative to one another. */
2833
2834 for (sec = f->load_order; sec; sec = sec->load_next) {
2835 ElfW(Addr) align;
2836
2837 align = sec->header.sh_addralign;
2838 if (align && (dot & (align - 1)))
2839 dot = (dot | (align - 1)) + 1;
2840
2841 sec->header.sh_addr = dot;
2842 dot += sec->header.sh_size;
2843 }
2844
2845 return dot;
2846}
2847
Eric Andersen044228d2001-07-17 01:12:36 +00002848static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
Eric Andersen9f16d612000-06-12 23:11:16 +00002849{
2850 int i, n = f->header.e_shnum;
2851 int ret = 1;
2852
2853 /* Finalize the addresses of the sections. */
2854
2855 f->baseaddr = base;
2856 for (i = 0; i < n; ++i)
2857 f->sections[i]->header.sh_addr += base;
2858
2859 /* And iterate over all of the relocations. */
2860
2861 for (i = 0; i < n; ++i) {
2862 struct obj_section *relsec, *symsec, *targsec, *strsec;
2863 ElfW(RelM) * rel, *relend;
2864 ElfW(Sym) * symtab;
2865 const char *strtab;
2866
2867 relsec = f->sections[i];
2868 if (relsec->header.sh_type != SHT_RELM)
2869 continue;
2870
2871 symsec = f->sections[relsec->header.sh_link];
2872 targsec = f->sections[relsec->header.sh_info];
2873 strsec = f->sections[symsec->header.sh_link];
2874
2875 rel = (ElfW(RelM) *) relsec->contents;
2876 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2877 symtab = (ElfW(Sym) *) symsec->contents;
2878 strtab = (const char *) strsec->contents;
2879
2880 for (; rel < relend; ++rel) {
2881 ElfW(Addr) value = 0;
2882 struct obj_symbol *intsym = NULL;
2883 unsigned long symndx;
2884 ElfW(Sym) * extsym = 0;
2885 const char *errmsg;
2886
2887 /* Attempt to find a value to use for this relocation. */
2888
2889 symndx = ELFW(R_SYM) (rel->r_info);
2890 if (symndx) {
2891 /* Note we've already checked for undefined symbols. */
2892
2893 extsym = &symtab[symndx];
2894 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2895 /* Local symbols we look up in the local table to be sure
2896 we get the one that is really intended. */
2897 intsym = f->local_symtab[symndx];
2898 } else {
2899 /* Others we look up in the hash table. */
2900 const char *name;
2901 if (extsym->st_name)
2902 name = strtab + extsym->st_name;
2903 else
2904 name = f->sections[extsym->st_shndx]->name;
2905 intsym = obj_find_symbol(f, name);
2906 }
2907
2908 value = obj_symbol_final_value(f, intsym);
2909 intsym->referenced = 1;
2910 }
2911#if SHT_RELM == SHT_RELA
2912#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2913 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2914 if (!extsym || !extsym->st_name ||
Eric Andersen3b1a7442003-12-24 20:30:45 +00002915 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
Eric Andersen9f16d612000-06-12 23:11:16 +00002916#endif
2917 value += rel->r_addend;
2918#endif
2919
2920 /* Do it! */
2921 switch (arch_apply_relocation
2922 (f, targsec, symsec, intsym, rel, value)) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00002923 case obj_reloc_ok:
2924 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002925
Eric Andersen3b1a7442003-12-24 20:30:45 +00002926 case obj_reloc_overflow:
2927 errmsg = "Relocation overflow";
2928 goto bad_reloc;
2929 case obj_reloc_dangerous:
2930 errmsg = "Dangerous relocation";
2931 goto bad_reloc;
2932 case obj_reloc_unhandled:
2933 errmsg = "Unhandled relocation";
2934bad_reloc:
2935 if (extsym) {
2936 bb_error_msg("%s of type %ld for %s", errmsg,
2937 (long) ELFW(R_TYPE) (rel->r_info),
2938 strtab + extsym->st_name);
2939 } else {
2940 bb_error_msg("%s of type %ld", errmsg,
2941 (long) ELFW(R_TYPE) (rel->r_info));
2942 }
2943 ret = 0;
2944 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00002945 }
2946 }
2947 }
2948
2949 /* Finally, take care of the patches. */
2950
2951 if (f->string_patches) {
2952 struct obj_string_patch *p;
2953 struct obj_section *strsec;
2954 ElfW(Addr) strsec_base;
2955 strsec = obj_find_section(f, ".kstrtab");
2956 strsec_base = strsec->header.sh_addr;
2957
2958 for (p = f->string_patches; p; p = p->next) {
2959 struct obj_section *targsec = f->sections[p->reloc_secidx];
2960 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2961 = strsec_base + p->string_offset;
2962 }
2963 }
2964
2965 if (f->symbol_patches) {
2966 struct obj_symbol_patch *p;
2967
2968 for (p = f->symbol_patches; p; p = p->next) {
2969 struct obj_section *targsec = f->sections[p->reloc_secidx];
2970 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2971 = obj_symbol_final_value(f, p->sym);
2972 }
2973 }
2974
2975 return ret;
2976}
2977
Eric Andersen044228d2001-07-17 01:12:36 +00002978static int obj_create_image(struct obj_file *f, char *image)
Eric Andersen9f16d612000-06-12 23:11:16 +00002979{
2980 struct obj_section *sec;
2981 ElfW(Addr) base = f->baseaddr;
2982
2983 for (sec = f->load_order; sec; sec = sec->load_next) {
2984 char *secimg;
2985
Eric Andersen2bf658d2001-02-24 20:01:53 +00002986 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002987 continue;
2988
2989 secimg = image + (sec->header.sh_addr - base);
2990
2991 /* Note that we allocated data for NOBITS sections earlier. */
2992 memcpy(secimg, sec->contents, sec->header.sh_size);
2993 }
2994
2995 return 1;
2996}
2997
2998/*======================================================================*/
2999
Eric Andersen044228d2001-07-17 01:12:36 +00003000static struct obj_file *obj_load(FILE * fp, int loadprogbits)
Eric Andersen9f16d612000-06-12 23:11:16 +00003001{
3002 struct obj_file *f;
3003 ElfW(Shdr) * section_headers;
3004 int shnum, i;
3005 char *shstrtab;
3006
3007 /* Read the file header. */
3008
3009 f = arch_new_file();
3010 memset(f, 0, sizeof(*f));
3011 f->symbol_cmp = strcmp;
3012 f->symbol_hash = obj_elf_hash;
3013 f->load_order_search_start = &f->load_order;
3014
3015 fseek(fp, 0, SEEK_SET);
3016 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003017 bb_perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00003018 return NULL;
3019 }
3020
3021 if (f->header.e_ident[EI_MAG0] != ELFMAG0
Eric Andersen3b1a7442003-12-24 20:30:45 +00003022 || f->header.e_ident[EI_MAG1] != ELFMAG1
3023 || f->header.e_ident[EI_MAG2] != ELFMAG2
3024 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003025 bb_error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00003026 return NULL;
3027 }
3028 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
Eric Andersen3b1a7442003-12-24 20:30:45 +00003029 || f->header.e_ident[EI_DATA] != ELFDATAM
3030 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3031 || !MATCH_MACHINE(f->header.e_machine)) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003032 bb_error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00003033 return NULL;
3034 }
3035 if (f->header.e_type != ET_REL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003036 bb_error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00003037 return NULL;
3038 }
3039
3040 /* Read the section headers. */
3041
3042 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003043 bb_error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003044 (unsigned long) f->header.e_shentsize,
3045 (unsigned long) sizeof(ElfW(Shdr)));
3046 return NULL;
3047 }
3048
3049 shnum = f->header.e_shnum;
3050 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
3051 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
3052
3053 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3054 fseek(fp, f->header.e_shoff, SEEK_SET);
3055 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003056 bb_perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00003057 return NULL;
3058 }
3059
3060 /* Read the section data. */
3061
3062 for (i = 0; i < shnum; ++i) {
3063 struct obj_section *sec;
3064
3065 f->sections[i] = sec = arch_new_section();
3066 memset(sec, 0, sizeof(*sec));
3067
3068 sec->header = section_headers[i];
3069 sec->idx = i;
3070
Eric Andersen2bf658d2001-02-24 20:01:53 +00003071 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003072 case SHT_NULL:
3073 case SHT_NOTE:
3074 case SHT_NOBITS:
3075 /* ignore */
Eric Andersen8ae319a2001-05-21 16:09:18 +00003076 break;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003077
3078 case SHT_PROGBITS:
3079#if LOADBITS
3080 if (!loadprogbits) {
3081 sec->contents = NULL;
3082 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003083 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003084#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003085 case SHT_SYMTAB:
3086 case SHT_STRTAB:
3087 case SHT_RELM:
3088 if (sec->header.sh_size > 0) {
3089 sec->contents = xmalloc(sec->header.sh_size);
3090 fseek(fp, sec->header.sh_offset, SEEK_SET);
3091 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3092 bb_perror_msg("error reading ELF section data");
3093 return NULL;
3094 }
3095 } else {
3096 sec->contents = NULL;
3097 }
3098 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003099
3100#if SHT_RELM == SHT_REL
Eric Andersen3b1a7442003-12-24 20:30:45 +00003101 case SHT_RELA:
3102 bb_error_msg("RELA relocations not supported on this architecture");
3103 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003104#else
Eric Andersen3b1a7442003-12-24 20:30:45 +00003105 case SHT_REL:
3106 bb_error_msg("REL relocations not supported on this architecture");
3107 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003108#endif
3109
Eric Andersen3b1a7442003-12-24 20:30:45 +00003110 default:
3111 if (sec->header.sh_type >= SHT_LOPROC) {
3112 /* Assume processor specific section types are debug
3113 info and can safely be ignored. If this is ever not
3114 the case (Hello MIPS?), don't put ifdefs here but
3115 create an arch_load_proc_section(). */
3116 break;
3117 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003118
Eric Andersen3b1a7442003-12-24 20:30:45 +00003119 bb_error_msg("can't handle sections of type %ld",
3120 (long) sec->header.sh_type);
3121 return NULL;
Eric Andersen9f16d612000-06-12 23:11:16 +00003122 }
3123 }
3124
3125 /* Do what sort of interpretation as needed by each section. */
3126
3127 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3128
3129 for (i = 0; i < shnum; ++i) {
3130 struct obj_section *sec = f->sections[i];
3131 sec->name = shstrtab + sec->header.sh_name;
3132 }
3133
3134 for (i = 0; i < shnum; ++i) {
3135 struct obj_section *sec = f->sections[i];
3136
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003137 /* .modinfo should be contents only but gcc has no attribute for that.
3138 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3139 */
3140 if (strcmp(sec->name, ".modinfo") == 0)
3141 sec->header.sh_flags &= ~SHF_ALLOC;
3142
Eric Andersen9f16d612000-06-12 23:11:16 +00003143 if (sec->header.sh_flags & SHF_ALLOC)
3144 obj_insert_section_load_order(f, sec);
3145
3146 switch (sec->header.sh_type) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003147 case SHT_SYMTAB:
3148 {
3149 unsigned long nsym, j;
3150 char *strtab;
3151 ElfW(Sym) * sym;
Eric Andersen9f16d612000-06-12 23:11:16 +00003152
Eric Andersen3b1a7442003-12-24 20:30:45 +00003153 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3154 bb_error_msg("symbol size mismatch: %lu != %lu",
3155 (unsigned long) sec->header.sh_entsize,
3156 (unsigned long) sizeof(ElfW(Sym)));
3157 return NULL;
3158 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003159
Eric Andersen3b1a7442003-12-24 20:30:45 +00003160 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3161 strtab = f->sections[sec->header.sh_link]->contents;
3162 sym = (ElfW(Sym) *) sec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00003163
Eric Andersen3b1a7442003-12-24 20:30:45 +00003164 /* Allocate space for a table of local symbols. */
3165 j = f->local_symtab_size = sec->header.sh_info;
3166 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003167
Eric Andersen3b1a7442003-12-24 20:30:45 +00003168 /* Insert all symbols into the hash table. */
3169 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3170 ElfW(Addr) val = sym->st_value;
3171 const char *name;
3172 if (sym->st_name)
3173 name = strtab + sym->st_name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003174 else if (sym->st_shndx < shnum)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003175 name = f->sections[sym->st_shndx]->name;
Manuel Novoa III 21fbe0e2004-02-18 10:14:17 +00003176 else
3177 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00003178
Eric Andersenbf833552003-08-13 19:56:33 +00003179#if defined(__SH5__)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003180 /*
3181 * For sh64 it is possible that the target of a branch
3182 * requires a mode switch (32 to 16 and back again).
3183 *
3184 * This is implied by the lsb being set in the target
3185 * address for SHmedia mode and clear for SHcompact.
3186 */
3187 val |= sym->st_other & 4;
Eric Andersenbf833552003-08-13 19:56:33 +00003188#endif
3189
Eric Andersen3b1a7442003-12-24 20:30:45 +00003190 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3191 val, sym->st_size);
3192 }
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003193 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00003194 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003195
Eric Andersen3b1a7442003-12-24 20:30:45 +00003196 case SHT_RELM:
3197 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3198 bb_error_msg("relocation entry size mismatch: %lu != %lu",
3199 (unsigned long) sec->header.sh_entsize,
3200 (unsigned long) sizeof(ElfW(RelM)));
3201 return NULL;
3202 }
3203 break;
3204 /* XXX Relocation code from modutils-2.3.19 is not here.
3205 * Why? That's about 20 lines of code from obj/obj_load.c,
3206 * which gets done in a second pass through the sections.
3207 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003208 }
3209 }
3210
3211 return f;
3212}
3213
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003214#ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM
Eric Andersen8ae319a2001-05-21 16:09:18 +00003215/*
3216 * load the unloaded sections directly into the memory allocated by
3217 * kernel for the module
3218 */
3219
Eric Andersenac5dbd12001-08-22 05:26:08 +00003220static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase)
Eric Andersen8ae319a2001-05-21 16:09:18 +00003221{
Eric Andersen8ae319a2001-05-21 16:09:18 +00003222 ElfW(Addr) base = f->baseaddr;
3223 struct obj_section* sec;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003224
Eric Andersen8ae319a2001-05-21 16:09:18 +00003225 for (sec = f->load_order; sec; sec = sec->load_next) {
3226
3227 /* section already loaded? */
3228 if (sec->contents != NULL)
3229 continue;
Eric Andersen3b1a7442003-12-24 20:30:45 +00003230
Eric Andersen8ae319a2001-05-21 16:09:18 +00003231 if (sec->header.sh_size == 0)
3232 continue;
3233
3234 sec->contents = imagebase + (sec->header.sh_addr - base);
3235 fseek(fp, sec->header.sh_offset, SEEK_SET);
3236 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003237 bb_error_msg("error reading ELF section data: %s\n", strerror(errno));
Eric Andersen8ae319a2001-05-21 16:09:18 +00003238 return 0;
3239 }
3240
3241 }
3242 return 1;
3243}
3244#endif
3245
Eric Andersen9f16d612000-06-12 23:11:16 +00003246static void hide_special_symbols(struct obj_file *f)
3247{
3248 static const char *const specials[] = {
Miles Baderae28b042002-04-01 09:34:25 +00003249 SPFX "cleanup_module",
3250 SPFX "init_module",
3251 SPFX "kernel_version",
Eric Andersen9f16d612000-06-12 23:11:16 +00003252 NULL
3253 };
3254
3255 struct obj_symbol *sym;
3256 const char *const *p;
3257
3258 for (p = specials; *p; ++p)
3259 if ((sym = obj_find_symbol(f, *p)) != NULL)
3260 sym->info =
3261 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3262}
3263
Glenn L McGrath759515c2003-08-30 06:00:33 +00003264
Eric Andersen71ae64b2002-10-10 04:20:21 +00003265#ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE
Eric Andersen166fa462002-09-16 05:30:24 +00003266static int obj_gpl_license(struct obj_file *f, const char **license)
3267{
3268 struct obj_section *sec;
3269 /* This list must match *exactly* the list of allowable licenses in
3270 * linux/include/linux/module.h. Checking for leading "GPL" will not
3271 * work, somebody will use "GPL sucks, this is proprietary".
3272 */
3273 static const char *gpl_licenses[] = {
3274 "GPL",
3275 "GPL v2",
3276 "GPL and additional rights",
3277 "Dual BSD/GPL",
3278 "Dual MPL/GPL",
3279 };
Eric Andersen9f16d612000-06-12 23:11:16 +00003280
Eric Andersen166fa462002-09-16 05:30:24 +00003281 if ((sec = obj_find_section(f, ".modinfo"))) {
3282 const char *value, *ptr, *endptr;
3283 ptr = sec->contents;
3284 endptr = ptr + sec->header.sh_size;
3285 while (ptr < endptr) {
3286 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) {
3287 int i;
3288 if (license)
3289 *license = value+1;
3290 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3291 if (strcmp(value+1, gpl_licenses[i]) == 0)
3292 return(0);
3293 }
3294 return(2);
3295 }
3296 if (strchr(ptr, '\0'))
3297 ptr = strchr(ptr, '\0') + 1;
3298 else
3299 ptr = endptr;
3300 }
3301 }
3302 return(1);
3303}
3304
3305#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3306#define TAINT_PROPRIETORY_MODULE (1<<0)
3307#define TAINT_FORCED_MODULE (1<<1)
3308#define TAINT_UNSAFE_SMP (1<<2)
3309#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3310
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003311static void set_tainted(struct obj_file *f, int fd, char *m_name,
Eric Andersen166fa462002-09-16 05:30:24 +00003312 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3313{
3314 char buf[80];
3315 int oldval;
3316 static int first = 1;
3317 if (fd < 0 && !kernel_has_tainted)
3318 return; /* New modutils on old kernel */
3319 printf("Warning: loading %s will taint the kernel: %s%s\n",
3320 m_name, text1, text2);
3321 if (first) {
3322 printf(" See %s for information about tainted modules\n", TAINT_URL);
3323 first = 0;
3324 }
3325 if (fd >= 0) {
3326 read(fd, buf, sizeof(buf)-1);
3327 buf[sizeof(buf)-1] = '\0';
3328 oldval = strtoul(buf, NULL, 10);
3329 sprintf(buf, "%d\n", oldval | taint);
3330 write(fd, buf, strlen(buf));
3331 }
3332}
3333
3334/* Check if loading this module will taint the kernel. */
3335static void check_tainted_module(struct obj_file *f, char *m_name)
3336{
3337 static const char tainted_file[] = TAINT_FILENAME;
3338 int fd, kernel_has_tainted;
3339 const char *ptr;
3340
3341 kernel_has_tainted = 1;
3342 if ((fd = open(tainted_file, O_RDWR)) < 0) {
3343 if (errno == ENOENT)
3344 kernel_has_tainted = 0;
3345 else if (errno == EACCES)
3346 kernel_has_tainted = 1;
3347 else {
3348 perror(tainted_file);
3349 kernel_has_tainted = 0;
3350 }
3351 }
3352
3353 switch (obj_gpl_license(f, &ptr)) {
3354 case 0:
3355 break;
3356 case 1:
3357 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3358 break;
3359 case 2:
3360 /* The module has a non-GPL license so we pretend that the
3361 * kernel always has a taint flag to get a warning even on
3362 * kernels without the proc flag.
3363 */
3364 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3365 break;
3366 default:
3367 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3368 break;
3369 }
3370
3371 if (flag_force_load)
3372 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3373
3374 if (fd >= 0)
3375 close(fd);
3376}
Eric Andersen71ae64b2002-10-10 04:20:21 +00003377#else /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
3378#define check_tainted_module(x, y) do { } while(0);
3379#endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */
Eric Andersen9f16d612000-06-12 23:11:16 +00003380
Eric Andersen889dd202003-01-23 04:48:34 +00003381#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3382/* add module source, timestamp, kernel version and a symbol for the
3383 * start of some sections. this info is used by ksymoops to do better
3384 * debugging.
3385 */
3386static int
3387get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3388{
3389#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00003390 return new_get_module_version(f, str);
Eric Andersen889dd202003-01-23 04:48:34 +00003391#else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003392 strncpy(str, "???", sizeof(str));
3393 return -1;
Eric Andersen889dd202003-01-23 04:48:34 +00003394#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
3395}
3396
3397/* add module source, timestamp, kernel version and a symbol for the
3398 * start of some sections. this info is used by ksymoops to do better
3399 * debugging.
3400 */
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003401static void
Eric Andersen889dd202003-01-23 04:48:34 +00003402add_ksymoops_symbols(struct obj_file *f, const char *filename,
3403 const char *m_name)
3404{
3405 static const char symprefix[] = "__insmod_";
3406 struct obj_section *sec;
3407 struct obj_symbol *sym;
3408 char *name, *absolute_filename;
3409 char str[STRVERSIONLEN], real[PATH_MAX];
3410 int i, l, lm_name, lfilename, use_ksymtab, version;
3411 struct stat statbuf;
3412
3413 static const char *section_names[] = {
3414 ".text",
3415 ".rodata",
3416 ".data",
3417 ".bss"
Eric Andersen3b1a7442003-12-24 20:30:45 +00003418 ".sbss"
Eric Andersen889dd202003-01-23 04:48:34 +00003419 };
3420
3421 if (realpath(filename, real)) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003422 absolute_filename = bb_xstrdup(real);
Eric Andersen889dd202003-01-23 04:48:34 +00003423 }
3424 else {
3425 int save_errno = errno;
Manuel Novoa III cad53642003-03-19 09:13:01 +00003426 bb_error_msg("cannot get realpath for %s", filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003427 errno = save_errno;
3428 perror("");
Manuel Novoa III cad53642003-03-19 09:13:01 +00003429 absolute_filename = bb_xstrdup(filename);
Eric Andersen889dd202003-01-23 04:48:34 +00003430 }
3431
3432 lm_name = strlen(m_name);
3433 lfilename = strlen(absolute_filename);
3434
3435 /* add to ksymtab if it already exists or there is no ksymtab and other symbols
3436 * are not to be exported. otherwise leave ksymtab alone for now, the
3437 * "export all symbols" compatibility code will export these symbols later.
3438 */
3439 use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export;
3440
3441 if ((sec = obj_find_section(f, ".this"))) {
3442 /* tag the module header with the object name, last modified
3443 * timestamp and module version. worst case for module version
3444 * is 0xffffff, decimal 16777215. putting all three fields in
3445 * one symbol is less readable but saves kernel space.
3446 */
3447 l = sizeof(symprefix)+ /* "__insmod_" */
Eric Andersen3b1a7442003-12-24 20:30:45 +00003448 lm_name+ /* module name */
3449 2+ /* "_O" */
3450 lfilename+ /* object filename */
3451 2+ /* "_M" */
3452 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */
3453 2+ /* "_V" */
3454 8+ /* version in dec */
3455 1; /* nul */
Eric Andersen889dd202003-01-23 04:48:34 +00003456 name = xmalloc(l);
3457 if (stat(absolute_filename, &statbuf) != 0)
3458 statbuf.st_mtime = 0;
3459 version = get_module_version(f, str); /* -1 if not found */
3460 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003461 symprefix, m_name, absolute_filename,
3462 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime,
3463 version);
Eric Andersen889dd202003-01-23 04:48:34 +00003464 sym = obj_add_symbol(f, name, -1,
Eric Andersen3b1a7442003-12-24 20:30:45 +00003465 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
3466 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003467 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003468 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003469 }
3470 free(absolute_filename);
3471#ifdef _NOT_SUPPORTED_
3472 /* record where the persistent data is going, same address as previous symbol */
3473
3474 if (f->persist) {
3475 l = sizeof(symprefix)+ /* "__insmod_" */
3476 lm_name+ /* module name */
3477 2+ /* "_P" */
3478 strlen(f->persist)+ /* data store */
3479 1; /* nul */
3480 name = xmalloc(l);
3481 snprintf(name, l, "%s%s_P%s",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003482 symprefix, m_name, f->persist);
Eric Andersen889dd202003-01-23 04:48:34 +00003483 sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003484 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003485 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003486 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003487 }
3488#endif /* _NOT_SUPPORTED_ */
3489 /* tag the desired sections if size is non-zero */
3490
3491 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
3492 if ((sec = obj_find_section(f, section_names[i])) &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00003493 sec->header.sh_size) {
Eric Andersen889dd202003-01-23 04:48:34 +00003494 l = sizeof(symprefix)+ /* "__insmod_" */
3495 lm_name+ /* module name */
3496 2+ /* "_S" */
3497 strlen(sec->name)+ /* section name */
3498 2+ /* "_L" */
3499 8+ /* length in dec */
3500 1; /* nul */
3501 name = xmalloc(l);
3502 snprintf(name, l, "%s%s_S%s_L%ld",
Eric Andersen3b1a7442003-12-24 20:30:45 +00003503 symprefix, m_name, sec->name,
3504 (long)sec->header.sh_size);
Eric Andersen889dd202003-01-23 04:48:34 +00003505 sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
Eric Andersen3b1a7442003-12-24 20:30:45 +00003506 sec->idx, sec->header.sh_addr, 0);
Eric Andersen889dd202003-01-23 04:48:34 +00003507 if (use_ksymtab)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003508 new_add_ksymtab(f, sym);
Eric Andersen889dd202003-01-23 04:48:34 +00003509 }
3510 }
3511}
3512#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3513
Eric Andersenbe65c352003-01-23 04:57:35 +00003514#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3515static void print_load_map(struct obj_file *f)
3516{
3517 struct obj_symbol *sym;
3518 struct obj_symbol **all, **p;
3519 struct obj_section *sec;
3520 int i, nsyms, *loaded;
3521
3522 /* Report on the section layout. */
3523
3524 printf("Sections: Size %-*s Align\n",
3525 (int) (2 * sizeof(void *)), "Address");
3526
3527 for (sec = f->load_order; sec; sec = sec->load_next) {
3528 int a;
3529 unsigned long tmp;
3530
3531 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3532 tmp >>= 1;
3533 if (a == -1)
3534 a = 0;
3535
3536 printf("%-15s %08lx %0*lx 2**%d\n",
3537 sec->name,
3538 (long)sec->header.sh_size,
3539 (int) (2 * sizeof(void *)),
3540 (long)sec->header.sh_addr,
3541 a);
3542 }
3543#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
3544 /* Quick reference which section indicies are loaded. */
3545
3546 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
3547 while (--i >= 0)
3548 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
3549
3550 /* Collect the symbols we'll be listing. */
3551
3552 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3553 for (sym = f->symtab[i]; sym; sym = sym->next)
3554 if (sym->secidx <= SHN_HIRESERVE
3555 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3556 ++nsyms;
3557
3558 all = alloca(nsyms * sizeof(struct obj_symbol *));
3559
3560 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3561 for (sym = f->symtab[i]; sym; sym = sym->next)
3562 if (sym->secidx <= SHN_HIRESERVE
3563 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]))
3564 *p++ = sym;
3565
3566 /* And list them. */
3567 printf("\nSymbols:\n");
3568 for (p = all; p < all + nsyms; ++p) {
3569 char type = '?';
3570 unsigned long value;
3571
3572 sym = *p;
3573 if (sym->secidx == SHN_ABS) {
3574 type = 'A';
3575 value = sym->value;
3576 } else if (sym->secidx == SHN_UNDEF) {
3577 type = 'U';
3578 value = 0;
3579 } else {
3580 sec = f->sections[sym->secidx];
3581
3582 if (sec->header.sh_type == SHT_NOBITS)
3583 type = 'B';
3584 else if (sec->header.sh_flags & SHF_ALLOC) {
3585 if (sec->header.sh_flags & SHF_EXECINSTR)
3586 type = 'T';
3587 else if (sec->header.sh_flags & SHF_WRITE)
3588 type = 'D';
3589 else
3590 type = 'R';
3591 }
3592 value = sym->value + sec->header.sh_addr;
3593 }
3594
3595 if (ELFW(ST_BIND) (sym->info) == STB_LOCAL)
3596 type = tolower(type);
3597
3598 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3599 type, sym->name);
3600 }
3601#endif
3602}
3603
3604#endif
3605
Eric Andersen9f16d612000-06-12 23:11:16 +00003606extern int insmod_main( int argc, char **argv)
3607{
Eric Andersena18aaf12001-01-24 19:07:09 +00003608 int opt;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003609 int len;
Eric Andersen5275b1e2004-06-22 20:10:53 +00003610 int k_crcs;
Eric Andersen6fb4e482002-06-06 14:24:57 +00003611 char *tmp, *tmp1;
Eric Andersen9f16d612000-06-12 23:11:16 +00003612 unsigned long m_size;
3613 ElfW(Addr) m_addr;
Eric Andersen9f16d612000-06-12 23:11:16 +00003614 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003615 struct stat st;
Eric Andersen61f83052002-06-22 17:15:42 +00003616 char *m_name = 0;
Matt Kraai3e856ce2000-12-01 02:55:13 +00003617 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003618 int m_has_modinfo;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003619#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Matt Kraai063c1f52001-08-06 14:18:08 +00003620 struct utsname uts_info;
Eric Andersen9f16d612000-06-12 23:11:16 +00003621 char m_strversion[STRVERSIONLEN];
Eric Andersen5275b1e2004-06-22 20:10:53 +00003622 int m_version, m_crcs;
Eric Andersen9f16d612000-06-12 23:11:16 +00003623#endif
Eric Andersen61f83052002-06-22 17:15:42 +00003624#ifdef CONFIG_FEATURE_CLEAN_UP
3625 FILE *fp = 0;
3626#else
3627 FILE *fp;
3628#endif
Eric Andersenbe65c352003-01-23 04:57:35 +00003629#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3630 int flag_print_load_map = 0;
3631#endif
Eric Andersen03d80912003-12-19 21:04:19 +00003632 int k_version = 0;
3633 struct utsname myuname;
Eric Andersen9f16d612000-06-12 23:11:16 +00003634
Erik Andersene49d5ec2000-02-08 19:58:47 +00003635 /* Parse any options */
Eric Andersenbe65c352003-01-23 04:57:35 +00003636#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
Eric Andersen3b1a7442003-12-24 20:30:45 +00003637 while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0)
Eric Andersenbe65c352003-01-23 04:57:35 +00003638#else
Eric Andersenc7bda1c2004-03-15 08:29:22 +00003639 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0)
Eric Andersenbe65c352003-01-23 04:57:35 +00003640#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003641 {
3642 switch (opt) {
3643 case 'f': /* force loading */
3644 flag_force_load = 1;
3645 break;
3646 case 'k': /* module loaded by kerneld, auto-cleanable */
3647 flag_autoclean = 1;
3648 break;
3649 case 's': /* log to syslog */
3650 /* log to syslog -- not supported */
3651 /* but kernel needs this for request_module(), */
3652 /* as this calls: modprobe -k -s -- <module> */
3653 /* so silently ignore this flag */
3654 break;
3655 case 'v': /* verbose output */
3656 flag_verbose = 1;
3657 break;
3658 case 'q': /* silent */
3659 flag_quiet = 1;
3660 break;
3661 case 'x': /* do not export externs */
3662 flag_export = 0;
3663 break;
3664 case 'o': /* name the output module */
3665 free(m_name);
3666 m_name = bb_xstrdup(optarg);
3667 break;
3668 case 'L': /* Stub warning */
3669 /* This is needed for compatibility with modprobe.
3670 * In theory, this does locking, but we don't do
3671 * that. So be careful and plan your life around not
3672 * loading the same module 50 times concurrently. */
3673 break;
Eric Andersenbe65c352003-01-23 04:57:35 +00003674#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
Eric Andersen3b1a7442003-12-24 20:30:45 +00003675 case 'm': /* print module load map */
3676 flag_print_load_map = 1;
3677 break;
Eric Andersenbe65c352003-01-23 04:57:35 +00003678#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003679 default:
3680 bb_show_usage();
3681 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003682 }
Eric Andersen03d80912003-12-19 21:04:19 +00003683
Eric Andersena18aaf12001-01-24 19:07:09 +00003684 if (argv[optind] == NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003685 bb_show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003686 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003687
Erik Andersene49d5ec2000-02-08 19:58:47 +00003688 /* Grab the module name */
Manuel Novoa III cad53642003-03-19 09:13:01 +00003689 tmp1 = bb_xstrdup(argv[optind]);
Eric Andersen6fb4e482002-06-06 14:24:57 +00003690 tmp = basename(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003691 len = strlen(tmp);
3692
Eric Andersen03d80912003-12-19 21:04:19 +00003693 if (uname(&myuname) == 0) {
3694 if (myuname.release[0] == '2') {
3695 k_version = myuname.release[2] - '0';
3696 }
3697 }
3698
3699#if defined(CONFIG_FEATURE_2_6_MODULES)
3700 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' &&
Eric Andersen3b1a7442003-12-24 20:30:45 +00003701 tmp[len - 2] == 'k' && tmp[len - 1] == 'o') {
Eric Andersen03d80912003-12-19 21:04:19 +00003702 len-=3;
3703 tmp[len] = '\0';
3704 }
3705 else
3706#endif
Eric Andersen3b1a7442003-12-24 20:30:45 +00003707 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
3708 len-=2;
3709 tmp[len] = '\0';
3710 }
Eric Andersen2d342152002-06-18 05:16:25 +00003711
Eric Andersen03d80912003-12-19 21:04:19 +00003712
3713#if defined(CONFIG_FEATURE_2_6_MODULES)
3714 if (k_version > 4)
3715 bb_xasprintf(&m_fullName, "%s.ko", tmp);
3716 else
Eric Andersen03d80912003-12-19 21:04:19 +00003717#endif
Eric Andersen66e21fd2004-01-05 23:49:37 +00003718 bb_xasprintf(&m_fullName, "%s.o", tmp);
Eric Andersen61f83052002-06-22 17:15:42 +00003719
Eric Andersen61f83052002-06-22 17:15:42 +00003720 if (!m_name) {
3721 m_name = tmp;
3722 } else {
3723 free(tmp1);
3724 tmp1 = 0; /* flag for free(m_name) before exit() */
3725 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003726
Eric Andersen14d35432001-05-14 17:07:32 +00003727 /* Get a filedesc for the module. Check we we have a complete path */
Eric Andersen02b9f422001-02-15 19:07:43 +00003728 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3729 (fp = fopen(argv[optind], "r")) == NULL) {
Eric Andersen14d35432001-05-14 17:07:32 +00003730 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
3731 * but do not error out yet if we fail to find it... */
Eric Andersen03d80912003-12-19 21:04:19 +00003732 if (k_version) { /* uname succeedd */
3733 char *module_dir;
3734 char *tmdn;
Eric Andersen2416dfc2001-05-14 20:03:04 +00003735 char real_module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00003736
Eric Andersen03d80912003-12-19 21:04:19 +00003737 tmdn = concat_path_file(_PATH_MODULES, myuname.release);
Eric Andersen2416dfc2001-05-14 20:03:04 +00003738 /* Jump through hoops in case /lib/modules/`uname -r`
3739 * is a symlink. We do not want recursive_action to
3740 * follow symlinks, but we do want to follow the
3741 * /lib/modules/`uname -r` dir, So resolve it ourselves
3742 * if it is a link... */
Eric Andersen03d80912003-12-19 21:04:19 +00003743 if (realpath (tmdn, real_module_dir) == NULL)
3744 module_dir = tmdn;
3745 else
3746 module_dir = real_module_dir;
3747 recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen3b1a7442003-12-24 20:30:45 +00003748 check_module_name_match, 0, m_fullName);
Eric Andersen03d80912003-12-19 21:04:19 +00003749 free(tmdn);
Eric Andersen14d35432001-05-14 17:07:32 +00003750 }
3751
3752 /* Check if we have found anything yet */
Eric Andersen61f83052002-06-22 17:15:42 +00003753 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen9f16d612000-06-12 23:11:16 +00003754 {
Eric Andersen2416dfc2001-05-14 20:03:04 +00003755 char module_dir[FILENAME_MAX];
Robert Griebld378c312002-07-19 00:05:54 +00003756
Eric Andersen03d80912003-12-19 21:04:19 +00003757 free(m_filename);
3758 m_filename = 0;
Eric Andersen2416dfc2001-05-14 20:03:04 +00003759 if (realpath (_PATH_MODULES, module_dir) == NULL)
3760 strcpy(module_dir, _PATH_MODULES);
Eric Andersen14d35432001-05-14 17:07:32 +00003761 /* No module found under /lib/modules/`uname -r`, this
3762 * time cast the net a bit wider. Search /lib/modules/ */
Matt Kraai1f0c4362001-12-20 23:13:26 +00003763 if (! recursive_action(module_dir, TRUE, FALSE, FALSE,
Eric Andersen03d80912003-12-19 21:04:19 +00003764 check_module_name_match, 0, m_fullName))
Eric Andersen9f16d612000-06-12 23:11:16 +00003765 {
Eric Andersen61f83052002-06-22 17:15:42 +00003766 if (m_filename == 0
Eric Andersen03d80912003-12-19 21:04:19 +00003767 || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen14d35432001-05-14 17:07:32 +00003768 {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003769 bb_error_msg("%s: no module by that name found", m_fullName);
Eric Andersen61f83052002-06-22 17:15:42 +00003770 goto out;
Eric Andersen14d35432001-05-14 17:07:32 +00003771 }
3772 } else
Manuel Novoa III cad53642003-03-19 09:13:01 +00003773 bb_error_msg_and_die("%s: no module by that name found", m_fullName);
Eric Andersen14d35432001-05-14 17:07:32 +00003774 }
Eric Andersen03d80912003-12-19 21:04:19 +00003775 } else
Manuel Novoa III cad53642003-03-19 09:13:01 +00003776 m_filename = bb_xstrdup(argv[optind]);
Erik Andersend387d011999-12-21 02:55:11 +00003777
Glenn L McGrath5c9f0d02003-12-31 23:20:10 +00003778 if (!flag_quiet)
3779 printf("Using %s\n", m_filename);
Erik Andersend387d011999-12-21 02:55:11 +00003780
Eric Andersene7047882003-12-11 01:42:13 +00003781#ifdef CONFIG_FEATURE_2_6_MODULES
Eric Andersen03d80912003-12-19 21:04:19 +00003782 if (k_version > 4)
3783 {
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003784 optind--;
Eric Andersen03d80912003-12-19 21:04:19 +00003785 argv[optind + 1] = m_filename;
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003786 return insmod_ng_main(argc - optind, argv + optind);
Eric Andersen03d80912003-12-19 21:04:19 +00003787 }
Glenn L McGrathc2942f02003-08-31 01:58:18 +00003788#endif
3789
Eric Andersen8ae319a2001-05-21 16:09:18 +00003790 if ((f = obj_load(fp, LOADBITS)) == NULL)
Manuel Novoa III cad53642003-03-19 09:13:01 +00003791 bb_perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00003792
Eric Andersen9f16d612000-06-12 23:11:16 +00003793 if (get_modinfo_value(f, "kernel_version") == NULL)
3794 m_has_modinfo = 0;
3795 else
3796 m_has_modinfo = 1;
3797
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003798#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersen9f16d612000-06-12 23:11:16 +00003799 /* Version correspondence? */
Eric Andersenb493dec2002-07-02 19:14:23 +00003800 if (!flag_quiet) {
3801 if (uname(&uts_info) < 0)
3802 uts_info.release[0] = '\0';
3803 if (m_has_modinfo) {
3804 m_version = new_get_module_version(f, m_strversion);
Eric Andersenb493dec2002-07-02 19:14:23 +00003805 if (m_version == -1) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003806 bb_error_msg("couldn't find the kernel version the module was "
Eric Andersenb493dec2002-07-02 19:14:23 +00003807 "compiled for");
3808 goto out;
3809 }
3810 }
3811
3812 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) {
3813 if (flag_force_load) {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003814 bb_error_msg("Warning: kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00003815 "\t%s was compiled for kernel version %s\n"
3816 "\twhile this kernel is version %s",
3817 m_filename, m_strversion, uts_info.release);
3818 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003819 bb_error_msg("kernel-module version mismatch\n"
Eric Andersenb493dec2002-07-02 19:14:23 +00003820 "\t%s was compiled for kernel version %s\n"
3821 "\twhile this kernel is version %s.",
3822 m_filename, m_strversion, uts_info.release);
3823 goto out;
3824 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003825 }
3826 }
3827 k_crcs = 0;
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003828#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00003829
Eric Andersencb3b9b12004-06-22 11:50:52 +00003830 if (!query_module(NULL, 0, NULL, 0, NULL)) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003831 if (!new_get_kernel_symbols())
3832 goto out;
3833 k_crcs = new_is_kernel_checksummed();
Eric Andersen9f16d612000-06-12 23:11:16 +00003834 } else {
Manuel Novoa III cad53642003-03-19 09:13:01 +00003835 bb_error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003836 goto out;
Eric Andersen9f16d612000-06-12 23:11:16 +00003837 }
3838
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003839#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING
Eric Andersencb3b9b12004-06-22 11:50:52 +00003840 m_crcs = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00003841 if (m_has_modinfo)
3842 m_crcs = new_is_module_checksummed(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00003843
3844 if (m_crcs != k_crcs)
3845 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
Eric Andersenbdfd0d72001-10-24 05:00:29 +00003846#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
Eric Andersen9f16d612000-06-12 23:11:16 +00003847
Erik Andersene49d5ec2000-02-08 19:58:47 +00003848 /* Let the module know about the kernel symbols. */
3849 add_kernel_symbols(f);
3850
Eric Andersen9f16d612000-06-12 23:11:16 +00003851 /* Allocate common symbols, symbol tables, and string tables. */
3852
Eric Andersencb3b9b12004-06-22 11:50:52 +00003853 if (!new_create_this_module(f, m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00003854 {
3855 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003856 }
3857
Eric Andersen9f16d612000-06-12 23:11:16 +00003858 if (!obj_check_undefineds(f)) {
3859 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003860 }
3861 obj_allocate_commons(f);
Eric Andersen166fa462002-09-16 05:30:24 +00003862 check_tainted_module(f, m_name);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003863
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003864 /* done with the module name, on to the optional var=value arguments */
3865 ++optind;
3866
Eric Andersen9f16d612000-06-12 23:11:16 +00003867 if (optind < argc) {
Robert Griebl809387f2004-07-20 15:43:57 +00003868 if (!new_process_module_arguments(f, argc - optind, argv + optind))
Eric Andersen9f16d612000-06-12 23:11:16 +00003869 {
3870 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003871 }
3872 }
3873
Eric Andersen9f16d612000-06-12 23:11:16 +00003874 arch_create_got(f);
3875 hide_special_symbols(f);
3876
Eric Andersen889dd202003-01-23 04:48:34 +00003877#ifdef CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3878 add_ksymoops_symbols(f, m_filename, m_name);
3879#endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */
3880
Eric Andersencb3b9b12004-06-22 11:50:52 +00003881 new_create_module_ksymtab(f);
Eric Andersen9f16d612000-06-12 23:11:16 +00003882
Erik Andersene49d5ec2000-02-08 19:58:47 +00003883 /* Find current size of the module */
3884 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00003885
3886
Erik Andersene49d5ec2000-02-08 19:58:47 +00003887 m_addr = create_module(m_name, m_size);
Eric Andersen61f83052002-06-22 17:15:42 +00003888 if (m_addr == -1) switch (errno) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003889 case EEXIST:
3890 bb_error_msg("A module named %s already exists", m_name);
3891 goto out;
3892 case ENOMEM:
3893 bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3894 m_size);
3895 goto out;
3896 default:
3897 bb_perror_msg("create_module: %s", m_name);
3898 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003899 }
Erik Andersend387d011999-12-21 02:55:11 +00003900
Eric Andersen8ae319a2001-05-21 16:09:18 +00003901#if !LOADBITS
3902 /*
3903 * the PROGBITS section was not loaded by the obj_load
3904 * now we can load them directly into the kernel memory
3905 */
Eric Andersenac5dbd12001-08-22 05:26:08 +00003906 if (!obj_load_progbits(fp, f, (char*)m_addr)) {
Eric Andersen8ae319a2001-05-21 16:09:18 +00003907 delete_module(m_name);
3908 goto out;
3909 }
Eric Andersen03d80912003-12-19 21:04:19 +00003910#endif
Eric Andersen8ae319a2001-05-21 16:09:18 +00003911
Eric Andersen9f16d612000-06-12 23:11:16 +00003912 if (!obj_relocate(f, m_addr)) {
3913 delete_module(m_name);
3914 goto out;
3915 }
Erik Andersend387d011999-12-21 02:55:11 +00003916
Eric Andersencb3b9b12004-06-22 11:50:52 +00003917 if (!new_init_module(m_name, f, m_size))
Eric Andersen9f16d612000-06-12 23:11:16 +00003918 {
3919 delete_module(m_name);
3920 goto out;
3921 }
3922
Eric Andersenbe65c352003-01-23 04:57:35 +00003923#ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
3924 if(flag_print_load_map)
3925 print_load_map(f);
3926#endif
3927
Matt Kraai3e856ce2000-12-01 02:55:13 +00003928 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00003929
3930out:
Eric Andersen61f83052002-06-22 17:15:42 +00003931#ifdef CONFIG_FEATURE_CLEAN_UP
3932 if(fp)
Eric Andersen3b1a7442003-12-24 20:30:45 +00003933 fclose(fp);
Eric Andersen61f83052002-06-22 17:15:42 +00003934 if(tmp1) {
3935 free(tmp1);
3936 } else {
3937 free(m_name);
3938 }
3939 free(m_filename);
3940#endif
Eric Andersenbb245ba2000-06-19 19:53:30 +00003941 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00003942}
Eric Andersene7047882003-12-11 01:42:13 +00003943
3944
3945#endif
3946
3947
3948#ifdef CONFIG_FEATURE_2_6_MODULES
3949
3950#include <sys/mman.h>
3951#include <asm/unistd.h>
3952#include <sys/syscall.h>
3953
3954/* We use error numbers in a loose translation... */
3955static const char *moderror(int err)
3956{
3957 switch (err) {
Eric Andersen3b1a7442003-12-24 20:30:45 +00003958 case ENOEXEC:
3959 return "Invalid module format";
3960 case ENOENT:
3961 return "Unknown symbol in module";
3962 case ESRCH:
3963 return "Module has wrong symbol version";
3964 case EINVAL:
3965 return "Invalid parameters";
3966 default:
3967 return strerror(err);
Eric Andersene7047882003-12-11 01:42:13 +00003968 }
3969}
3970
3971extern int insmod_ng_main( int argc, char **argv)
3972{
3973 int i;
3974 int fd;
3975 long int ret;
3976 struct stat st;
3977 unsigned long len;
3978 void *map;
3979 char *filename, *options = bb_xstrdup("");
Eric Andersen3b1a7442003-12-24 20:30:45 +00003980
Eric Andersene7047882003-12-11 01:42:13 +00003981 filename = argv[1];
3982 if (!filename) {
3983 bb_show_usage();
3984 return -1;
3985 }
3986
3987 /* Rest is options */
3988 for (i = 2; i < argc; i++) {
3989 options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2);
3990 /* Spaces handled by "" pairs, but no way of escaping quotes */
3991 if (strchr(argv[i], ' ')) {
3992 strcat(options, "\"");
3993 strcat(options, argv[i]);
3994 strcat(options, "\"");
3995 } else {
3996 strcat(options, argv[i]);
3997 }
3998 strcat(options, " ");
3999 }
4000
4001 if ((fd = open(filename, O_RDONLY, 0)) < 0) {
4002 bb_perror_msg_and_die("cannot open module `%s'", filename);
4003 }
4004
4005 fstat(fd, &st);
4006 len = st.st_size;
4007 map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
4008 if (map == MAP_FAILED) {
4009 bb_perror_msg_and_die("cannot mmap `%s'", filename);
4010 }
4011
4012 ret = syscall(__NR_init_module, map, len, options);
4013 if (ret != 0) {
4014 bb_perror_msg_and_die("cannot insert `%s': %s (%li)",
Eric Andersen3b1a7442003-12-24 20:30:45 +00004015 filename, moderror(errno), ret);
Eric Andersene7047882003-12-11 01:42:13 +00004016 }
Eric Andersen3b1a7442003-12-24 20:30:45 +00004017
Eric Andersene7047882003-12-11 01:42:13 +00004018 return 0;
4019}
4020
4021#endif