blob: 4dd14c6bcf093c800ef25406e7471cdba7d29673 [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 Andersen4f4bcfc2001-04-25 17:22:32 +00004 * This version of insmod now supports x86, ARM, SH3/4, powerpc, and MIPS.
Erik Andersen02104321999-12-17 18:57:34 +00005 *
Eric Andersen8ec10a92001-01-27 09:33:39 +00006 * Copyright (C) 1999,2000,2001 by Lineo, inc.
Eric Andersen9f16d612000-06-12 23:11:16 +00007 * Written by Erik Andersen <andersen@lineo.com>
8 * and Ron Alder <alder@lineo.com>
9 *
Eric Andersenfe4208f2000-09-24 03:44:29 +000010 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
Eric Andersen21adca72000-12-06 18:18:26 +000011 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
12 *
13 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
14 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
15 * very minor changes required to also work with StrongArm and presumably
16 * all ARM based systems.
Eric Andersenfe4208f2000-09-24 03:44:29 +000017 *
Eric Andersen90fe7fe2001-02-20 20:47:08 +000018 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001.
19 * PowerPC specific code stolen from modutils-2.3.16,
20 * written by Paul Mackerras, Copyright 1996, 1997 Linux International.
21 * I've only tested the code on mpc8xx platforms in big-endian mode.
22 * Did some cleanup and added BB_USE_xxx_ENTRIES...
23 *
Eric Andersen2bf658d2001-02-24 20:01:53 +000024 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
25 * based on modutils-2.4.2
26 * MIPS specific support for Elf loading and relocation.
27 * Copyright 1996, 1997 Linux International.
28 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
29 *
Eric Andersen9f16d612000-06-12 23:11:16 +000030 * Based almost entirely on the Linux modutils-2.3.11 implementation.
31 * Copyright 1996, 1997 Linux International.
32 * New implementation contributed by Richard Henderson <rth@tamu.edu>
33 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
34 * Restructured (and partly rewritten) by:
35 * Björn Ekwall <bj0rn@blox.se> February 1999
Erik Andersen02104321999-12-17 18:57:34 +000036 *
37 * This program is free software; you can redistribute it and/or modify
38 * it under the terms of the GNU General Public License as published by
39 * the Free Software Foundation; either version 2 of the License, or
40 * (at your option) any later version.
41 *
42 * This program is distributed in the hope that it will be useful,
43 * but WITHOUT ANY WARRANTY; without even the implied warranty of
44 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
45 * General Public License for more details.
46 *
47 * You should have received a copy of the GNU General Public License
48 * along with this program; if not, write to the Free Software
49 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50 *
51 */
52
Erik Andersen02104321999-12-17 18:57:34 +000053#include <stdlib.h>
54#include <stdio.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000055#include <stddef.h>
Erik Andersen02104321999-12-17 18:57:34 +000056#include <errno.h>
57#include <unistd.h>
58#include <dirent.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000059#include <ctype.h>
60#include <assert.h>
Eric Andersened3ef502001-01-27 08:24:39 +000061#include <string.h>
Eric Andersen999bf722000-07-09 06:59:58 +000062#include <getopt.h>
Eric Andersen9f16d612000-06-12 23:11:16 +000063#include <sys/utsname.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000064#include "busybox.h"
Eric Andersen9f16d612000-06-12 23:11:16 +000065
Eric Andersen64c8b172001-04-05 07:33:10 +000066#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
67# define new_sys_init_module init_module
68#else
69# define old_sys_init_module init_module
70#endif
71
Eric Andersen90fe7fe2001-02-20 20:47:08 +000072#if defined(__powerpc__)
73#define BB_USE_PLT_ENTRIES
74#define BB_PLT_ENTRY_SIZE 16
75#endif
76
77#if defined(__arm__)
78#define BB_USE_PLT_ENTRIES
79#define BB_PLT_ENTRY_SIZE 8
80#define BB_USE_GOT_ENTRIES
81#define BB_GOT_ENTRY_SIZE 8
82#endif
83
84#if defined(__sh__)
85#define BB_USE_GOT_ENTRIES
86#define BB_GOT_ENTRY_SIZE 4
87#endif
88
89#if defined(__i386__)
90#define BB_USE_GOT_ENTRIES
91#define BB_GOT_ENTRY_SIZE 4
92#endif
93
Eric Andersen2bf658d2001-02-24 20:01:53 +000094#if defined(__mips__)
95// neither used
96#endif
97
Eric Andersen9f16d612000-06-12 23:11:16 +000098//----------------------------------------------------------------------------
99//--------modutils module.h, lines 45-242
100//----------------------------------------------------------------------------
101
102/* Definitions for the Linux module syscall interface.
103 Copyright 1996, 1997 Linux International.
104
105 Contributed by Richard Henderson <rth@tamu.edu>
106
107 This file is part of the Linux modutils.
108
109 This program is free software; you can redistribute it and/or modify it
110 under the terms of the GNU General Public License as published by the
111 Free Software Foundation; either version 2 of the License, or (at your
112 option) any later version.
113
114 This program is distributed in the hope that it will be useful, but
115 WITHOUT ANY WARRANTY; without even the implied warranty of
116 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
117 General Public License for more details.
118
119 You should have received a copy of the GNU General Public License
120 along with this program; if not, write to the Free Software Foundation,
121 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
122
123
124#ifndef MODUTILS_MODULE_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000125static const int MODUTILS_MODULE_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000126
Eric Andersen4f4bcfc2001-04-25 17:22:32 +0000127#ident "$Id: insmod.c,v 1.59 2001/04/25 17:22:32 andersen Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000128
129/* This file contains the structures used by the 2.0 and 2.1 kernels.
130 We do not use the kernel headers directly because we do not wish
131 to be dependant on a particular kernel version to compile insmod. */
132
133
134/*======================================================================*/
135/* The structures used by Linux 2.0. */
136
137/* The symbol format used by get_kernel_syms(2). */
138struct old_kernel_sym
139{
140 unsigned long value;
141 char name[60];
142};
143
144struct old_module_ref
145{
146 unsigned long module; /* kernel addresses */
147 unsigned long next;
148};
149
150struct old_module_symbol
151{
152 unsigned long addr;
153 unsigned long name;
154};
155
156struct old_symbol_table
157{
158 int size; /* total, including string table!!! */
159 int n_symbols;
160 int n_refs;
161 struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */
162 struct old_module_ref ref[0]; /* actual size defined by n_refs */
163};
164
165struct old_mod_routines
166{
167 unsigned long init;
168 unsigned long cleanup;
169};
170
171struct old_module
172{
173 unsigned long next;
174 unsigned long ref; /* the list of modules that refer to me */
175 unsigned long symtab;
176 unsigned long name;
177 int size; /* size of module in pages */
178 unsigned long addr; /* address of module */
179 int state;
180 unsigned long cleanup; /* cleanup routine */
181};
182
183/* Sent to init_module(2) or'ed into the code size parameter. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000184static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */
Eric Andersen9f16d612000-06-12 23:11:16 +0000185
186int get_kernel_syms(struct old_kernel_sym *);
187int old_sys_init_module(const char *name, char *code, unsigned codesize,
188 struct old_mod_routines *, struct old_symbol_table *);
189
190/*======================================================================*/
191/* For sizeof() which are related to the module platform and not to the
192 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
193
194#define tgt_sizeof_char sizeof(char)
195#define tgt_sizeof_short sizeof(short)
196#define tgt_sizeof_int sizeof(int)
197#define tgt_sizeof_long sizeof(long)
198#define tgt_sizeof_char_p sizeof(char *)
199#define tgt_sizeof_void_p sizeof(void *)
200#define tgt_long long
201
202#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
203#undef tgt_sizeof_long
204#undef tgt_sizeof_char_p
205#undef tgt_sizeof_void_p
206#undef tgt_long
Mark Whitley59ab0252001-01-23 22:30:04 +0000207static const int tgt_sizeof_long = 8;
208static const int tgt_sizeof_char_p = 8;
209static const int tgt_sizeof_void_p = 8;
Eric Andersen9f16d612000-06-12 23:11:16 +0000210#define tgt_long long long
211#endif
212
213/*======================================================================*/
214/* The structures used in Linux 2.1. */
215
216/* Note: new_module_symbol does not use tgt_long intentionally */
217struct new_module_symbol
218{
219 unsigned long value;
220 unsigned long name;
221};
222
223struct new_module_persist;
224
225struct new_module_ref
226{
227 unsigned tgt_long dep; /* kernel addresses */
228 unsigned tgt_long ref;
229 unsigned tgt_long next_ref;
230};
231
232struct new_module
233{
234 unsigned tgt_long size_of_struct; /* == sizeof(module) */
235 unsigned tgt_long next;
236 unsigned tgt_long name;
237 unsigned tgt_long size;
238
239 tgt_long usecount;
240 unsigned tgt_long flags; /* AUTOCLEAN et al */
241
242 unsigned nsyms;
243 unsigned ndeps;
244
245 unsigned tgt_long syms;
246 unsigned tgt_long deps;
247 unsigned tgt_long refs;
248 unsigned tgt_long init;
249 unsigned tgt_long cleanup;
250 unsigned tgt_long ex_table_start;
251 unsigned tgt_long ex_table_end;
252#ifdef __alpha__
253 unsigned tgt_long gp;
254#endif
255 /* Everything after here is extension. */
256 unsigned tgt_long persist_start;
257 unsigned tgt_long persist_end;
258 unsigned tgt_long can_unload;
259 unsigned tgt_long runsize;
260};
261
262struct new_module_info
263{
264 unsigned long addr;
265 unsigned long size;
266 unsigned long flags;
267 long usecount;
268};
269
270/* Bits of module.flags. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000271static const int NEW_MOD_RUNNING = 1;
272static const int NEW_MOD_DELETED = 2;
273static const int NEW_MOD_AUTOCLEAN = 4;
274static const int NEW_MOD_VISITED = 8;
275static const int NEW_MOD_USED_ONCE = 16;
Eric Andersen9f16d612000-06-12 23:11:16 +0000276
Eric Andersen64c8b172001-04-05 07:33:10 +0000277int new_sys_init_module(const char *name, const struct new_module *);
Eric Andersen9f16d612000-06-12 23:11:16 +0000278int query_module(const char *name, int which, void *buf, size_t bufsize,
279 size_t *ret);
280
281/* Values for query_module's which. */
282
Mark Whitley59ab0252001-01-23 22:30:04 +0000283static const int QM_MODULES = 1;
284static const int QM_DEPS = 2;
285static const int QM_REFS = 3;
286static const int QM_SYMBOLS = 4;
287static const int QM_INFO = 5;
Eric Andersen9f16d612000-06-12 23:11:16 +0000288
289/*======================================================================*/
290/* The system calls unchanged between 2.0 and 2.1. */
291
292unsigned long create_module(const char *, size_t);
293int delete_module(const char *);
294
295
296#endif /* module.h */
297
298//----------------------------------------------------------------------------
299//--------end of modutils module.h
300//----------------------------------------------------------------------------
301
302
303
304//----------------------------------------------------------------------------
305//--------modutils obj.h, lines 253-462
306//----------------------------------------------------------------------------
307
308/* Elf object file loading and relocation routines.
309 Copyright 1996, 1997 Linux International.
310
311 Contributed by Richard Henderson <rth@tamu.edu>
312
313 This file is part of the Linux modutils.
314
315 This program is free software; you can redistribute it and/or modify it
316 under the terms of the GNU General Public License as published by the
317 Free Software Foundation; either version 2 of the License, or (at your
318 option) any later version.
319
320 This program is distributed in the hope that it will be useful, but
321 WITHOUT ANY WARRANTY; without even the implied warranty of
322 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
323 General Public License for more details.
324
325 You should have received a copy of the GNU General Public License
326 along with this program; if not, write to the Free Software Foundation,
327 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
328
329
330#ifndef MODUTILS_OBJ_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000331static const int MODUTILS_OBJ_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000332
Eric Andersen4f4bcfc2001-04-25 17:22:32 +0000333#ident "$Id: insmod.c,v 1.59 2001/04/25 17:22:32 andersen Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000334
335/* The relocatable object is manipulated using elfin types. */
336
337#include <stdio.h>
338#include <elf.h>
339
340
341/* Machine-specific elf macros for i386 et al. */
342
Eric Andersenfe4208f2000-09-24 03:44:29 +0000343/* the SH changes have only been tested on the SH4 in =little endian= mode */
344/* I'm not sure about big endian, so let's warn: */
345
346#if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
347#error insmod.c may require changes for use on big endian SH4/SH3
348#endif
349
350/* it may or may not work on the SH1/SH2... So let's error on those
351 also */
352#if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
353#error insmod.c may require changes for non-SH3/SH4 use
354#endif
355
Eric Andersen9f16d612000-06-12 23:11:16 +0000356#define ELFCLASSM ELFCLASS32
Eric Andersenfe4208f2000-09-24 03:44:29 +0000357
358#if defined(__sh__)
359
360#define MATCH_MACHINE(x) (x == EM_SH)
361#define SHT_RELM SHT_RELA
362#define Elf32_RelM Elf32_Rela
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000363#define ELFDATAM ELFDATA2LSB
Eric Andersenfe4208f2000-09-24 03:44:29 +0000364
Eric Andersen21adca72000-12-06 18:18:26 +0000365#elif defined(__arm__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000366
Eric Andersen21adca72000-12-06 18:18:26 +0000367#define MATCH_MACHINE(x) (x == EM_ARM)
368#define SHT_RELM SHT_REL
369#define Elf32_RelM Elf32_Rel
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000370#define ELFDATAM ELFDATA2LSB
371
372#elif defined(__powerpc__)
373
374#define MATCH_MACHINE(x) (x == EM_PPC)
375#define SHT_RELM SHT_RELA
376#define Elf32_RelM Elf32_Rela
377#define ELFDATAM ELFDATA2MSB
Eric Andersen21adca72000-12-06 18:18:26 +0000378
Eric Andersen2bf658d2001-02-24 20:01:53 +0000379#elif defined(__mips__)
380
Eric Andersen82bb8a22001-03-22 19:01:16 +0000381/* Account for ELF spec changes. */
382#ifndef EM_MIPS_RS3_LE
383#ifdef EM_MIPS_RS4_BE
384#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
385#else
386#define EM_MIPS_RS3_LE 10
387#endif
388#endif /* !EM_MIPS_RS3_LE */
389
Eric Andersen2bf658d2001-02-24 20:01:53 +0000390#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
391#define SHT_RELM SHT_REL
392#define Elf32_RelM Elf32_Rel
393#ifdef __MIPSEB__
394#define ELFDATAM ELFDATA2MSB
395#endif
396#ifdef __MIPSEL__
397#define ELFDATAM ELFDATA2LSB
398#endif
399
Eric Andersen21adca72000-12-06 18:18:26 +0000400#elif defined(__i386__)
401
402/* presumably we can use these for anything but the SH and ARM*/
Eric Andersenfe4208f2000-09-24 03:44:29 +0000403/* this is the previous behavior, but it does result in
404 insmod.c being broken on anything except i386 */
Pavel Roskin43f3e612000-09-28 20:52:55 +0000405#ifndef EM_486
406#define MATCH_MACHINE(x) (x == EM_386)
407#else
Eric Andersenfe4208f2000-09-24 03:44:29 +0000408#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
Pavel Roskin43f3e612000-09-28 20:52:55 +0000409#endif
410
Eric Andersen9f16d612000-06-12 23:11:16 +0000411#define SHT_RELM SHT_REL
412#define Elf32_RelM Elf32_Rel
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000413#define ELFDATAM ELFDATA2LSB
Eric Andersen9f16d612000-06-12 23:11:16 +0000414
Eric Andersen21adca72000-12-06 18:18:26 +0000415#else
Eric Andersend5cad142001-01-26 02:23:57 +0000416#error Sorry, but insmod.c does not yet support this architecture...
Eric Andersenfe4208f2000-09-24 03:44:29 +0000417#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000418
419#ifndef ElfW
420# if ELFCLASSM == ELFCLASS32
421# define ElfW(x) Elf32_ ## x
422# define ELFW(x) ELF32_ ## x
423# else
424# define ElfW(x) Elf64_ ## x
425# define ELFW(x) ELF64_ ## x
426# endif
427#endif
428
429/* For some reason this is missing from libc5. */
430#ifndef ELF32_ST_INFO
431# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
432#endif
433
434#ifndef ELF64_ST_INFO
435# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
436#endif
437
438struct obj_string_patch;
439struct obj_symbol_patch;
440
441struct obj_section
442{
443 ElfW(Shdr) header;
444 const char *name;
445 char *contents;
446 struct obj_section *load_next;
447 int idx;
448};
449
450struct obj_symbol
451{
452 struct obj_symbol *next; /* hash table link */
453 const char *name;
454 unsigned long value;
455 unsigned long size;
456 int secidx; /* the defining section index/module */
457 int info;
458 int ksymidx; /* for export to the kernel symtab */
459 int referenced; /* actually used in the link */
460};
461
462/* Hardcode the hash table size. We shouldn't be needing so many
463 symbols that we begin to degrade performance, and we get a big win
464 by giving the compiler a constant divisor. */
465
466#define HASH_BUCKETS 521
467
468struct obj_file
469{
470 ElfW(Ehdr) header;
471 ElfW(Addr) baseaddr;
472 struct obj_section **sections;
473 struct obj_section *load_order;
474 struct obj_section **load_order_search_start;
475 struct obj_string_patch *string_patches;
476 struct obj_symbol_patch *symbol_patches;
477 int (*symbol_cmp)(const char *, const char *);
478 unsigned long (*symbol_hash)(const char *);
479 unsigned long local_symtab_size;
480 struct obj_symbol **local_symtab;
481 struct obj_symbol *symtab[HASH_BUCKETS];
482};
483
484enum obj_reloc
485{
486 obj_reloc_ok,
487 obj_reloc_overflow,
488 obj_reloc_dangerous,
489 obj_reloc_unhandled
490};
491
492struct obj_string_patch
493{
494 struct obj_string_patch *next;
495 int reloc_secidx;
496 ElfW(Addr) reloc_offset;
497 ElfW(Addr) string_offset;
498};
499
500struct obj_symbol_patch
501{
502 struct obj_symbol_patch *next;
503 int reloc_secidx;
504 ElfW(Addr) reloc_offset;
505 struct obj_symbol *sym;
506};
507
508
509/* Generic object manipulation routines. */
510
511unsigned long obj_elf_hash(const char *);
512
513unsigned long obj_elf_hash_n(const char *, unsigned long len);
514
515struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name,
516 unsigned long symidx, int info, int secidx,
517 ElfW(Addr) value, unsigned long size);
518
519struct obj_symbol *obj_find_symbol (struct obj_file *f,
520 const char *name);
521
522ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
523 struct obj_symbol *sym);
524
525void obj_set_symbol_compare(struct obj_file *f,
526 int (*cmp)(const char *, const char *),
527 unsigned long (*hash)(const char *));
528
529struct obj_section *obj_find_section (struct obj_file *f,
530 const char *name);
531
532void obj_insert_section_load_order (struct obj_file *f,
533 struct obj_section *sec);
534
535struct obj_section *obj_create_alloced_section (struct obj_file *f,
536 const char *name,
537 unsigned long align,
538 unsigned long size);
539
540struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
541 const char *name,
542 unsigned long align,
543 unsigned long size);
544
545void *obj_extend_section (struct obj_section *sec, unsigned long more);
546
547int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
548 const char *string);
549
550int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
551 struct obj_symbol *sym);
552
553int obj_check_undefineds(struct obj_file *f);
554
555void obj_allocate_commons(struct obj_file *f);
556
557unsigned long obj_load_size (struct obj_file *f);
558
559int obj_relocate (struct obj_file *f, ElfW(Addr) base);
560
561struct obj_file *obj_load(FILE *f);
562
563int obj_create_image (struct obj_file *f, char *image);
564
565/* Architecture specific manipulation routines. */
566
567struct obj_file *arch_new_file (void);
568
569struct obj_section *arch_new_section (void);
570
571struct obj_symbol *arch_new_symbol (void);
572
573enum obj_reloc arch_apply_relocation (struct obj_file *f,
574 struct obj_section *targsec,
575 struct obj_section *symsec,
576 struct obj_symbol *sym,
577 ElfW(RelM) *rel, ElfW(Addr) value);
578
579int arch_create_got (struct obj_file *f);
580
581struct new_module;
582int arch_init_module (struct obj_file *f, struct new_module *);
583
584#endif /* obj.h */
585//----------------------------------------------------------------------------
586//--------end of modutils obj.h
587//----------------------------------------------------------------------------
588
589
590
591
Erik Andersen02104321999-12-17 18:57:34 +0000592
Erik Andersend387d011999-12-21 02:55:11 +0000593#define _PATH_MODULES "/lib/modules"
Mark Whitley59ab0252001-01-23 22:30:04 +0000594static const int STRVERSIONLEN = 32;
Erik Andersend387d011999-12-21 02:55:11 +0000595
Eric Andersen9f16d612000-06-12 23:11:16 +0000596/*======================================================================*/
597
598int flag_force_load = 0;
599int flag_autoclean = 0;
600int flag_verbose = 0;
601int flag_export = 1;
602
603
604/*======================================================================*/
605
Eric Andersenfe4208f2000-09-24 03:44:29 +0000606/* previously, these were named i386_* but since we could be
607 compiling for the sh, I've renamed them to the more general
608 arch_* These structures are the same between the x86 and SH,
609 and we can't support anything else right now anyway. In the
610 future maybe they should be #if defined'd */
611
Eric Andersen21adca72000-12-06 18:18:26 +0000612/* Done ;-) */
613
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000614
615
616#if defined(BB_USE_PLT_ENTRIES)
617struct arch_plt_entry
Eric Andersen21adca72000-12-06 18:18:26 +0000618{
619 int offset;
620 int allocated:1;
621 int inited:1; /* has been set up */
622};
623#endif
624
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000625#if defined(BB_USE_GOT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000626struct arch_got_entry {
Eric Andersen9f16d612000-06-12 23:11:16 +0000627 int offset;
628 unsigned offset_done:1;
629 unsigned reloc_done:1;
630};
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000631#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000632
Eric Andersen2bf658d2001-02-24 20:01:53 +0000633#if defined(__mips__)
634struct mips_hi16
635{
636 struct mips_hi16 *next;
637 Elf32_Addr *addr;
638 Elf32_Addr value;
639};
640#endif
641
Eric Andersenfe4208f2000-09-24 03:44:29 +0000642struct arch_file {
Eric Andersen9f16d612000-06-12 23:11:16 +0000643 struct obj_file root;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000644#if defined(BB_USE_PLT_ENTRIES)
645 struct obj_section *plt;
Eric Andersen21adca72000-12-06 18:18:26 +0000646#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000647#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000648 struct obj_section *got;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000649#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000650#if defined(__mips__)
651 struct mips_hi16 *mips_hi16_list;
652#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000653};
654
Eric Andersenfe4208f2000-09-24 03:44:29 +0000655struct arch_symbol {
Eric Andersen9f16d612000-06-12 23:11:16 +0000656 struct obj_symbol root;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000657#if defined(BB_USE_PLT_ENTRIES)
658 struct arch_plt_entry pltent;
Eric Andersen21adca72000-12-06 18:18:26 +0000659#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000660#if defined(BB_USE_GOT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000661 struct arch_got_entry gotent;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000662#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000663};
664
665
Eric Andersen9f16d612000-06-12 23:11:16 +0000666struct external_module {
667 const char *name;
668 ElfW(Addr) addr;
669 int used;
670 size_t nsyms;
671 struct new_module_symbol *syms;
672};
673
674struct new_module_symbol *ksyms;
675size_t nksyms;
676
677struct external_module *ext_modules;
678int n_ext_modules;
679int n_ext_modules_used;
680
Erik Andersend387d011999-12-21 02:55:11 +0000681
Erik Andersen02104321999-12-17 18:57:34 +0000682extern int delete_module(const char *);
Eric Andersena2a978a2001-04-05 06:08:14 +0000683
Erik Andersen02104321999-12-17 18:57:34 +0000684
Eric Andersenfe4208f2000-09-24 03:44:29 +0000685/* This is kind of troublesome. See, we don't actually support
686 the m68k or the arm the same way we support i386 and (now)
687 sh. In doing my SH patch, I just assumed that whatever works
688 for i386 also works for m68k and arm since currently insmod.c
689 does nothing special for them. If this isn't true, the below
690 line is rather misleading IMHO, and someone should either
691 change it or add more proper architecture-dependent support
692 for these boys.
693
694 -- Bryan Rittmeyer <bryan@ixiacom.com> */
695
Eric Andersen23c1a182001-03-19 19:28:24 +0000696static char m_filename[BUFSIZ + 1];
697static char m_fullName[BUFSIZ + 1];
Erik Andersen02104321999-12-17 18:57:34 +0000698
Eric Andersen9f16d612000-06-12 23:11:16 +0000699/*======================================================================*/
Erik Andersen02104321999-12-17 18:57:34 +0000700
Eric Andersen9f16d612000-06-12 23:11:16 +0000701
702static int findNamedModule(const char *fileName, struct stat *statbuf,
703 void *userDate)
704{
705 char *fullName = (char *) userDate;
706
707
708 if (fullName[0] == '\0')
Erik Andersene49d5ec2000-02-08 19:58:47 +0000709 return (FALSE);
710 else {
Eric Andersen21adca72000-12-06 18:18:26 +0000711 char *tmp = strrchr((char *) fileName, '/');
Erik Andersene49d5ec2000-02-08 19:58:47 +0000712
713 if (tmp == NULL)
714 tmp = (char *) fileName;
715 else
716 tmp++;
Eric Andersen9f16d612000-06-12 23:11:16 +0000717 if (check_wildcard_match(tmp, fullName) == TRUE) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000718 /* Stop searching if we find a match */
Eric Andersenf2278152001-04-24 21:41:41 +0000719 safe_strncpy(m_filename, fileName, sizeof(m_filename));
Erik Andersene49d5ec2000-02-08 19:58:47 +0000720 return (FALSE);
721 }
Erik Andersend387d011999-12-21 02:55:11 +0000722 }
Erik Andersene49d5ec2000-02-08 19:58:47 +0000723 return (TRUE);
Erik Andersend387d011999-12-21 02:55:11 +0000724}
725
Erik Andersen02104321999-12-17 18:57:34 +0000726
Eric Andersen9f16d612000-06-12 23:11:16 +0000727/*======================================================================*/
728
729struct obj_file *arch_new_file(void)
Erik Andersen02104321999-12-17 18:57:34 +0000730{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000731 struct arch_file *f;
Eric Andersen9f16d612000-06-12 23:11:16 +0000732 f = xmalloc(sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000733
734#if defined(BB_USE_PLT_ENTRIES)
735 f->plt = NULL;
736#endif
737#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000738 f->got = NULL;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000739#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000740#if defined(__mips__)
741 f->mips_hi16_list = NULL;
742#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000743
Eric Andersen9f16d612000-06-12 23:11:16 +0000744 return &f->root;
745}
746
747struct obj_section *arch_new_section(void)
748{
749 return xmalloc(sizeof(struct obj_section));
750}
751
752struct obj_symbol *arch_new_symbol(void)
753{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000754 struct arch_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000755 sym = xmalloc(sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000756
757#if defined(BB_USE_PLT_ENTRIES)
758 memset(&sym->pltent, 0, sizeof(sym->pltent));
759#endif
760#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000761 memset(&sym->gotent, 0, sizeof(sym->gotent));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000762#endif
763
Eric Andersen9f16d612000-06-12 23:11:16 +0000764 return &sym->root;
765}
Eric Andersenfe4208f2000-09-24 03:44:29 +0000766
Eric Andersen9f16d612000-06-12 23:11:16 +0000767enum obj_reloc
768arch_apply_relocation(struct obj_file *f,
769 struct obj_section *targsec,
770 struct obj_section *symsec,
771 struct obj_symbol *sym,
Eric Andersen21adca72000-12-06 18:18:26 +0000772 ElfW(RelM) *rel, ElfW(Addr) v)
Eric Andersen9f16d612000-06-12 23:11:16 +0000773{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000774 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen82bb8a22001-03-22 19:01:16 +0000775#if !(defined(__mips__))
Eric Andersenfe4208f2000-09-24 03:44:29 +0000776 struct arch_symbol *isym = (struct arch_symbol *) sym;
Eric Andersen82bb8a22001-03-22 19:01:16 +0000777#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000778
Eric Andersen21adca72000-12-06 18:18:26 +0000779 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
780 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000781#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000782 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000783#endif
784#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000785 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000786 struct arch_plt_entry *pe;
Eric Andersen21adca72000-12-06 18:18:26 +0000787 unsigned long *ip;
788#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000789 enum obj_reloc ret = obj_reloc_ok;
790
791 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersenfe4208f2000-09-24 03:44:29 +0000792
793/* even though these constants seem to be the same for
794 the i386 and the sh, we "#if define" them for clarity
795 and in case that ever changes */
796#if defined(__sh__)
797 case R_SH_NONE:
Eric Andersen21adca72000-12-06 18:18:26 +0000798#elif defined(__arm__)
799 case R_ARM_NONE:
800#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +0000801 case R_386_NONE:
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000802#elif defined(__powerpc__)
803 case R_PPC_NONE:
Eric Andersen2bf658d2001-02-24 20:01:53 +0000804#elif defined(__mips__)
805 case R_MIPS_NONE:
Eric Andersenfe4208f2000-09-24 03:44:29 +0000806#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000807 break;
808
Eric Andersenfe4208f2000-09-24 03:44:29 +0000809#if defined(__sh__)
810 case R_SH_DIR32:
Eric Andersen21adca72000-12-06 18:18:26 +0000811#elif defined(__arm__)
812 case R_ARM_ABS32:
813#elif defined(__i386__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000814 case R_386_32:
815#elif defined(__powerpc__)
816 case R_PPC_ADDR32:
Eric Andersen2bf658d2001-02-24 20:01:53 +0000817#elif defined(__mips__)
818 case R_MIPS_32:
Eric Andersenfe4208f2000-09-24 03:44:29 +0000819#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000820 *loc += v;
821 break;
822
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000823#if defined(__powerpc__)
824 case R_PPC_ADDR16_HA:
825 *(unsigned short *)loc = (v + 0x8000) >> 16;
826 break;
827
828 case R_PPC_ADDR16_HI:
829 *(unsigned short *)loc = v >> 16;
830 break;
831
832 case R_PPC_ADDR16_LO:
833 *(unsigned short *)loc = v;
834 break;
835#endif
836
Eric Andersen2bf658d2001-02-24 20:01:53 +0000837#if defined(__mips__)
838 case R_MIPS_26:
839 if (v % 4)
840 ret = obj_reloc_dangerous;
841 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
842 ret = obj_reloc_overflow;
843 *loc =
844 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
845 0x03ffffff);
846 break;
847
848 case R_MIPS_HI16:
849 {
850 struct mips_hi16 *n;
851
852 /* We cannot relocate this one now because we don't know the value
853 of the carry we need to add. Save the information, and let LO16
854 do the actual relocation. */
855 n = (struct mips_hi16 *) xmalloc(sizeof *n);
856 n->addr = loc;
857 n->value = v;
858 n->next = ifile->mips_hi16_list;
859 ifile->mips_hi16_list = n;
860 break;
861 }
862
863 case R_MIPS_LO16:
864 {
865 unsigned long insnlo = *loc;
866 Elf32_Addr val, vallo;
867
868 /* Sign extend the addend we extract from the lo insn. */
869 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
870
871 if (ifile->mips_hi16_list != NULL) {
872 struct mips_hi16 *l;
873
874 l = ifile->mips_hi16_list;
875 while (l != NULL) {
876 struct mips_hi16 *next;
877 unsigned long insn;
878
879 /* The value for the HI16 had best be the same. */
880 assert(v == l->value);
881
882 /* Do the HI16 relocation. Note that we actually don't
883 need to know anything about the LO16 itself, except where
884 to find the low 16 bits of the addend needed by the LO16. */
885 insn = *l->addr;
886 val =
887 ((insn & 0xffff) << 16) +
888 vallo;
889 val += v;
890
891 /* Account for the sign extension that will happen in the
892 low bits. */
893 val =
894 ((val >> 16) +
895 ((val & 0x8000) !=
896 0)) & 0xffff;
897
898 insn = (insn & ~0xffff) | val;
899 *l->addr = insn;
900
901 next = l->next;
902 free(l);
903 l = next;
904 }
905
906 ifile->mips_hi16_list = NULL;
907 }
908
909 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
910 val = v + vallo;
911 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
912 *loc = insnlo;
913 break;
914 }
915#endif
916
Eric Andersen21adca72000-12-06 18:18:26 +0000917#if defined(__arm__)
918#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000919 case R_SH_REL32:
Eric Andersen9f16d612000-06-12 23:11:16 +0000920 *loc += v - dot;
921 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000922#elif defined(__i386__)
923 case R_386_PLT32:
924 case R_386_PC32:
925 *loc += v - dot;
926 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000927#elif defined(__powerpc__)
928 case R_PPC_REL32:
929 *loc = v - dot;
930 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000931#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000932
Eric Andersenfe4208f2000-09-24 03:44:29 +0000933#if defined(__sh__)
934 case R_SH_PLT32:
935 *loc = v - dot;
936 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000937#elif defined(__i386__)
938#endif
939
940#if defined(BB_USE_PLT_ENTRIES)
941
942#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000943 case R_ARM_PC24:
944 case R_ARM_PLT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000945#endif
946#if defined(__powerpc__)
947 case R_PPC_REL24:
948#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000949 /* find the plt entry and initialize it if necessary */
950 assert(isym != NULL);
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000951
952 pe = (struct arch_plt_entry*) &isym->pltent;
953
Eric Andersen21adca72000-12-06 18:18:26 +0000954 if (! pe->inited) {
955 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000956
957 /* generate some machine code */
958
959#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000960 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
961 ip[1] = v; /* sym@ */
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000962#endif
963#if defined(__powerpc__)
964 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
965 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
966 ip[2] = 0x7d6903a6; /* mtctr r11 */
967 ip[3] = 0x4e800420; /* bctr */
968#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000969 pe->inited = 1;
970 }
971
972 /* relative distance to target */
973 v -= dot;
974 /* if the target is too far away.... */
975 if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
976 /* go via the plt */
977 v = plt + pe->offset - dot;
978 }
979 if (v & 3)
980 ret = obj_reloc_dangerous;
981
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000982 /* merge the offset into the instruction. */
983#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000984 /* Convert to words. */
985 v >>= 2;
986
Eric Andersen21adca72000-12-06 18:18:26 +0000987 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
Eric Andersenfe4208f2000-09-24 03:44:29 +0000988#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000989#if defined(__powerpc__)
990 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
991#endif
992 break;
993#endif /* BB_USE_PLT_ENTRIES */
Eric Andersenfe4208f2000-09-24 03:44:29 +0000994
Eric Andersen21adca72000-12-06 18:18:26 +0000995#if defined(__arm__)
996#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000997 case R_SH_GLOB_DAT:
998 case R_SH_JMP_SLOT:
999 *loc = v;
1000 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001001#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001002 case R_386_GLOB_DAT:
1003 case R_386_JMP_SLOT:
1004 *loc = v;
1005 break;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001006#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001007
Eric Andersen21adca72000-12-06 18:18:26 +00001008#if defined(__arm__)
1009#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001010 case R_SH_RELATIVE:
1011 *loc += f->baseaddr + rel->r_addend;
1012 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001013#elif defined(__i386__)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001014 case R_386_RELATIVE:
Eric Andersen9f16d612000-06-12 23:11:16 +00001015 *loc += f->baseaddr;
1016 break;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001017#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001018
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001019#if defined(BB_USE_GOT_ENTRIES)
1020
Eric Andersenfe4208f2000-09-24 03:44:29 +00001021#if defined(__sh__)
1022 case R_SH_GOTPC:
Eric Andersen21adca72000-12-06 18:18:26 +00001023#elif defined(__arm__)
1024 case R_ARM_GOTPC:
1025#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001026 case R_386_GOTPC:
Eric Andersenfe4208f2000-09-24 03:44:29 +00001027#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001028 assert(got != 0);
1029#if defined(__sh__)
1030 *loc += got - dot + rel->r_addend;;
1031#elif defined(__i386__) || defined(__arm__)
1032 *loc += got - dot;
1033#endif
1034 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001035
Eric Andersenfe4208f2000-09-24 03:44:29 +00001036#if defined(__sh__)
1037 case R_SH_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001038#elif defined(__arm__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001039 case R_ARM_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001040#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001041 case R_386_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001042#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001043 assert(isym != NULL);
Eric Andersen21adca72000-12-06 18:18:26 +00001044 /* needs an entry in the .got: set it, once */
Eric Andersen9f16d612000-06-12 23:11:16 +00001045 if (!isym->gotent.reloc_done) {
1046 isym->gotent.reloc_done = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001047 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
Eric Andersen9f16d612000-06-12 23:11:16 +00001048 }
Eric Andersen21adca72000-12-06 18:18:26 +00001049 /* make the reloc with_respect_to_.got */
1050#if defined(__sh__)
1051 *loc += isym->gotent.offset + rel->r_addend;
1052#elif defined(__i386__) || defined(__arm__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001053 *loc += isym->gotent.offset;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001054#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001055 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001056
Eric Andersen21adca72000-12-06 18:18:26 +00001057 /* address relative to the got */
Eric Andersenfe4208f2000-09-24 03:44:29 +00001058#if defined(__sh__)
1059 case R_SH_GOTOFF:
Eric Andersen21adca72000-12-06 18:18:26 +00001060#elif defined(__arm__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001061 case R_ARM_GOTOFF:
Eric Andersen21adca72000-12-06 18:18:26 +00001062#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001063 case R_386_GOTOFF:
Eric Andersenfe4208f2000-09-24 03:44:29 +00001064#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001065 assert(got != 0);
1066 *loc += v - got;
1067 break;
1068
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001069#endif /* BB_USE_GOT_ENTRIES */
1070
Eric Andersen9f16d612000-06-12 23:11:16 +00001071 default:
Eric Andersen21125542000-12-13 16:41:29 +00001072 printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
Eric Andersen9f16d612000-06-12 23:11:16 +00001073 ret = obj_reloc_unhandled;
1074 break;
1075 }
1076
1077 return ret;
1078}
1079
1080int arch_create_got(struct obj_file *f)
1081{
Eric Andersen2bf658d2001-02-24 20:01:53 +00001082#if defined(BB_USE_GOT_ENTRIES) || defined(BB_USE_PLT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001083 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001084 int i;
1085#if defined(BB_USE_GOT_ENTRIES)
1086 int got_offset = 0, gotneeded = 0;
1087#endif
1088#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001089 int plt_offset = 0, pltneeded = 0;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001090#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001091 struct obj_section *relsec, *symsec, *strsec;
1092 ElfW(RelM) *rel, *relend;
1093 ElfW(Sym) *symtab, *extsym;
1094 const char *strtab, *name;
1095 struct arch_symbol *intsym;
Eric Andersen9f16d612000-06-12 23:11:16 +00001096
Eric Andersen21adca72000-12-06 18:18:26 +00001097 for (i = 0; i < f->header.e_shnum; ++i) {
1098 relsec = f->sections[i];
1099 if (relsec->header.sh_type != SHT_RELM)
Eric Andersen9f16d612000-06-12 23:11:16 +00001100 continue;
1101
Eric Andersen21adca72000-12-06 18:18:26 +00001102 symsec = f->sections[relsec->header.sh_link];
1103 strsec = f->sections[symsec->header.sh_link];
Eric Andersen9f16d612000-06-12 23:11:16 +00001104
Eric Andersen21adca72000-12-06 18:18:26 +00001105 rel = (ElfW(RelM) *) relsec->contents;
1106 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1107 symtab = (ElfW(Sym) *) symsec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00001108 strtab = (const char *) strsec->contents;
1109
1110 for (; rel < relend; ++rel) {
Eric Andersen21adca72000-12-06 18:18:26 +00001111 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
Eric Andersen9f16d612000-06-12 23:11:16 +00001112
1113 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersen21adca72000-12-06 18:18:26 +00001114#if defined(__arm__)
1115 case R_ARM_GOT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001116 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001117#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001118 case R_SH_GOT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001119 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001120#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001121 case R_386_GOT32:
1122 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001123#endif
1124
1125#if defined(__powerpc__)
1126 case R_PPC_REL24:
1127 pltneeded = 1;
1128 break;
1129#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001130
1131#if defined(__arm__)
1132 case R_ARM_PC24:
1133 case R_ARM_PLT32:
1134 pltneeded = 1;
1135 break;
1136
1137 case R_ARM_GOTPC:
1138 case R_ARM_GOTOFF:
1139 gotneeded = 1;
1140 if (got_offset == 0)
1141 got_offset = 4;
1142#elif defined(__sh__)
1143 case R_SH_GOTPC:
1144 case R_SH_GOTOFF:
1145 gotneeded = 1;
1146#elif defined(__i386__)
1147 case R_386_GOTPC:
1148 case R_386_GOTOFF:
1149 gotneeded = 1;
1150#endif
1151
1152 default:
1153 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00001154 }
1155
Eric Andersen21adca72000-12-06 18:18:26 +00001156 if (extsym->st_name != 0) {
Eric Andersen9f16d612000-06-12 23:11:16 +00001157 name = strtab + extsym->st_name;
Eric Andersen21adca72000-12-06 18:18:26 +00001158 } else {
Eric Andersen9f16d612000-06-12 23:11:16 +00001159 name = f->sections[extsym->st_shndx]->name;
Eric Andersen21adca72000-12-06 18:18:26 +00001160 }
1161 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001162#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +00001163 if (!intsym->gotent.offset_done) {
1164 intsym->gotent.offset_done = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001165 intsym->gotent.offset = got_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001166 got_offset += BB_GOT_ENTRY_SIZE;
Eric Andersen21adca72000-12-06 18:18:26 +00001167 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001168#endif
1169#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001170 if (pltneeded && intsym->pltent.allocated == 0) {
1171 intsym->pltent.allocated = 1;
1172 intsym->pltent.offset = plt_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001173 plt_offset += BB_PLT_ENTRY_SIZE;
Eric Andersen21adca72000-12-06 18:18:26 +00001174 intsym->pltent.inited = 0;
1175 pltneeded = 0;
1176 }
1177#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001178 }
1179 }
Eric Andersen21adca72000-12-06 18:18:26 +00001180
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001181#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001182 if (got_offset) {
Eric Andersene76c3b02001-04-05 03:14:39 +00001183 struct obj_section* myrelsec = obj_find_section(f, ".got");
Eric Andersen21adca72000-12-06 18:18:26 +00001184
Eric Andersene76c3b02001-04-05 03:14:39 +00001185 if (myrelsec) {
1186 obj_extend_section(myrelsec, got_offset);
Eric Andersen21adca72000-12-06 18:18:26 +00001187 } else {
Eric Andersene76c3b02001-04-05 03:14:39 +00001188 myrelsec = obj_create_alloced_section(f, ".got",
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001189 BB_GOT_ENTRY_SIZE,
1190 got_offset);
Eric Andersene76c3b02001-04-05 03:14:39 +00001191 assert(myrelsec);
Eric Andersen21adca72000-12-06 18:18:26 +00001192 }
1193
Eric Andersene76c3b02001-04-05 03:14:39 +00001194 ifile->got = myrelsec;
Eric Andersen9f16d612000-06-12 23:11:16 +00001195 }
Eric Andersen21adca72000-12-06 18:18:26 +00001196#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001197
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001198#if defined(BB_USE_PLT_ENTRIES)
1199 if (plt_offset)
1200 ifile->plt = obj_create_alloced_section(f, ".plt",
1201 BB_PLT_ENTRY_SIZE,
1202 plt_offset);
1203#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +00001204#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001205 return 1;
1206}
1207
1208int arch_init_module(struct obj_file *f, struct new_module *mod)
1209{
1210 return 1;
1211}
1212
1213
1214/*======================================================================*/
1215
1216/* Standard ELF hash function. */
1217inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1218{
1219 unsigned long h = 0;
1220 unsigned long g;
1221 unsigned char ch;
1222
1223 while (n > 0) {
1224 ch = *name++;
1225 h = (h << 4) + ch;
1226 if ((g = (h & 0xf0000000)) != 0) {
1227 h ^= g >> 24;
1228 h &= ~g;
1229 }
1230 n--;
1231 }
1232 return h;
1233}
1234
1235unsigned long obj_elf_hash(const char *name)
1236{
1237 return obj_elf_hash_n(name, strlen(name));
1238}
1239
1240#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1241/* Get the kernel version in the canonical integer form. */
1242
1243static int get_kernel_version(char str[STRVERSIONLEN])
1244{
1245 struct utsname uts_info;
1246 char *p, *q;
1247 int a, b, c;
1248
1249 if (uname(&uts_info) < 0)
1250 return -1;
1251 strncpy(str, uts_info.release, STRVERSIONLEN);
1252 p = uts_info.release;
1253
1254 a = strtoul(p, &p, 10);
1255 if (*p != '.')
1256 return -1;
1257 b = strtoul(p + 1, &p, 10);
1258 if (*p != '.')
1259 return -1;
1260 c = strtoul(p + 1, &q, 10);
1261 if (p + 1 == q)
1262 return -1;
1263
1264 return a << 16 | b << 8 | c;
1265}
1266
1267/* String comparison for non-co-versioned kernel and module. */
1268
1269static int ncv_strcmp(const char *a, const char *b)
1270{
1271 size_t alen = strlen(a), blen = strlen(b);
1272
1273 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1274 return strncmp(a, b, alen);
1275 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1276 return strncmp(a, b, blen);
1277 else
1278 return strcmp(a, b);
1279}
1280
1281/* String hashing for non-co-versioned kernel and module. Here
1282 we are simply forced to drop the crc from the hash. */
1283
1284static unsigned long ncv_symbol_hash(const char *str)
1285{
1286 size_t len = strlen(str);
1287 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1288 len -= 10;
1289 return obj_elf_hash_n(str, len);
1290}
1291
1292void
1293obj_set_symbol_compare(struct obj_file *f,
1294 int (*cmp) (const char *, const char *),
1295 unsigned long (*hash) (const char *))
1296{
1297 if (cmp)
1298 f->symbol_cmp = cmp;
1299 if (hash) {
1300 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1301 int i;
1302
1303 f->symbol_hash = hash;
1304
1305 memcpy(tmptab, f->symtab, sizeof(tmptab));
1306 memset(f->symtab, 0, sizeof(f->symtab));
1307
1308 for (i = 0; i < HASH_BUCKETS; ++i)
1309 for (sym = tmptab[i]; sym; sym = next) {
1310 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1311 next = sym->next;
1312 sym->next = f->symtab[h];
1313 f->symtab[h] = sym;
1314 }
1315 }
1316}
1317
1318#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1319
1320
1321struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
1322 unsigned long symidx, int info,
1323 int secidx, ElfW(Addr) value,
1324 unsigned long size)
1325{
1326 struct obj_symbol *sym;
1327 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1328 int n_type = ELFW(ST_TYPE) (info);
1329 int n_binding = ELFW(ST_BIND) (info);
1330
1331 for (sym = f->symtab[hash]; sym; sym = sym->next)
1332 if (f->symbol_cmp(sym->name, name) == 0) {
1333 int o_secidx = sym->secidx;
1334 int o_info = sym->info;
1335 int o_type = ELFW(ST_TYPE) (o_info);
1336 int o_binding = ELFW(ST_BIND) (o_info);
1337
1338 /* A redefinition! Is it legal? */
1339
1340 if (secidx == SHN_UNDEF)
1341 return sym;
1342 else if (o_secidx == SHN_UNDEF)
1343 goto found;
1344 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1345 /* Cope with local and global symbols of the same name
1346 in the same object file, as might have been created
1347 by ld -r. The only reason locals are now seen at this
1348 level at all is so that we can do semi-sensible things
1349 with parameters. */
1350
1351 struct obj_symbol *nsym, **p;
1352
1353 nsym = arch_new_symbol();
1354 nsym->next = sym->next;
1355 nsym->ksymidx = -1;
1356
1357 /* Excise the old (local) symbol from the hash chain. */
1358 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1359 continue;
1360 *p = sym = nsym;
1361 goto found;
1362 } else if (n_binding == STB_LOCAL) {
1363 /* Another symbol of the same name has already been defined.
1364 Just add this to the local table. */
1365 sym = arch_new_symbol();
1366 sym->next = NULL;
1367 sym->ksymidx = -1;
1368 f->local_symtab[symidx] = sym;
1369 goto found;
1370 } else if (n_binding == STB_WEAK)
1371 return sym;
1372 else if (o_binding == STB_WEAK)
1373 goto found;
1374 /* Don't unify COMMON symbols with object types the programmer
1375 doesn't expect. */
1376 else if (secidx == SHN_COMMON
1377 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1378 return sym;
1379 else if (o_secidx == SHN_COMMON
1380 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1381 goto found;
1382 else {
1383 /* Don't report an error if the symbol is coming from
1384 the kernel or some external module. */
1385 if (secidx <= SHN_HIRESERVE)
Matt Kraaidd19c692001-01-31 19:00:21 +00001386 error_msg("%s multiply defined", name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001387 return sym;
1388 }
1389 }
1390
1391 /* Completely new symbol. */
1392 sym = arch_new_symbol();
1393 sym->next = f->symtab[hash];
1394 f->symtab[hash] = sym;
1395 sym->ksymidx = -1;
1396
1397 if (ELFW(ST_BIND) (info) == STB_LOCAL)
1398 f->local_symtab[symidx] = sym;
1399
1400 found:
1401 sym->name = name;
1402 sym->value = value;
1403 sym->size = size;
1404 sym->secidx = secidx;
1405 sym->info = info;
1406
1407 return sym;
1408}
1409
1410struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
1411{
1412 struct obj_symbol *sym;
1413 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1414
1415 for (sym = f->symtab[hash]; sym; sym = sym->next)
1416 if (f->symbol_cmp(sym->name, name) == 0)
1417 return sym;
1418
1419 return NULL;
1420}
1421
1422ElfW(Addr)
1423 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1424{
1425 if (sym) {
1426 if (sym->secidx >= SHN_LORESERVE)
1427 return sym->value;
1428
1429 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1430 } else {
1431 /* As a special case, a NULL sym has value zero. */
1432 return 0;
1433 }
1434}
1435
1436struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1437{
1438 int i, n = f->header.e_shnum;
1439
1440 for (i = 0; i < n; ++i)
1441 if (strcmp(f->sections[i]->name, name) == 0)
1442 return f->sections[i];
1443
1444 return NULL;
1445}
1446
1447static int obj_load_order_prio(struct obj_section *a)
1448{
1449 unsigned long af, ac;
1450
1451 af = a->header.sh_flags;
1452
1453 ac = 0;
1454 if (a->name[0] != '.' || strlen(a->name) != 10 ||
1455 strcmp(a->name + 5, ".init"))
1456 ac |= 32;
1457 if (af & SHF_ALLOC)
1458 ac |= 16;
1459 if (!(af & SHF_WRITE))
1460 ac |= 8;
1461 if (af & SHF_EXECINSTR)
1462 ac |= 4;
1463 if (a->header.sh_type != SHT_NOBITS)
1464 ac |= 2;
1465
1466 return ac;
1467}
1468
1469void
1470obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1471{
1472 struct obj_section **p;
1473 int prio = obj_load_order_prio(sec);
1474 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1475 if (obj_load_order_prio(*p) < prio)
1476 break;
1477 sec->load_next = *p;
1478 *p = sec;
1479}
1480
1481struct obj_section *obj_create_alloced_section(struct obj_file *f,
1482 const char *name,
1483 unsigned long align,
1484 unsigned long size)
1485{
1486 int newidx = f->header.e_shnum++;
1487 struct obj_section *sec;
1488
1489 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1490 f->sections[newidx] = sec = arch_new_section();
1491
1492 memset(sec, 0, sizeof(*sec));
1493 sec->header.sh_type = SHT_PROGBITS;
1494 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1495 sec->header.sh_size = size;
1496 sec->header.sh_addralign = align;
1497 sec->name = name;
1498 sec->idx = newidx;
1499 if (size)
1500 sec->contents = xmalloc(size);
1501
1502 obj_insert_section_load_order(f, sec);
1503
1504 return sec;
1505}
1506
1507struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1508 const char *name,
1509 unsigned long align,
1510 unsigned long size)
1511{
1512 int newidx = f->header.e_shnum++;
1513 struct obj_section *sec;
1514
1515 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1516 f->sections[newidx] = sec = arch_new_section();
1517
1518 memset(sec, 0, sizeof(*sec));
1519 sec->header.sh_type = SHT_PROGBITS;
1520 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1521 sec->header.sh_size = size;
1522 sec->header.sh_addralign = align;
1523 sec->name = name;
1524 sec->idx = newidx;
1525 if (size)
1526 sec->contents = xmalloc(size);
1527
1528 sec->load_next = f->load_order;
1529 f->load_order = sec;
1530 if (f->load_order_search_start == &f->load_order)
1531 f->load_order_search_start = &sec->load_next;
1532
1533 return sec;
1534}
1535
1536void *obj_extend_section(struct obj_section *sec, unsigned long more)
1537{
1538 unsigned long oldsize = sec->header.sh_size;
1539 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1540 return sec->contents + oldsize;
1541}
1542
1543
1544
1545/* Conditionally add the symbols from the given symbol set to the
1546 new module. */
1547
1548static int
1549add_symbols_from(
1550 struct obj_file *f,
1551 int idx, struct new_module_symbol *syms, size_t nsyms)
1552{
1553 struct new_module_symbol *s;
1554 size_t i;
1555 int used = 0;
1556
1557 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1558
1559 /* Only add symbols that are already marked external. If we
1560 override locals we may cause problems for argument initialization.
1561 We will also create a false dependency on the module. */
1562 struct obj_symbol *sym;
1563
1564 sym = obj_find_symbol(f, (char *) s->name);
1565 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1566 sym = obj_add_symbol(f, (char *) s->name, -1,
1567 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1568 idx, s->value, 0);
1569 /* Did our symbol just get installed? If so, mark the
1570 module as "used". */
1571 if (sym->secidx == idx)
1572 used = 1;
1573 }
1574 }
1575
1576 return used;
1577}
1578
1579static void add_kernel_symbols(struct obj_file *f)
1580{
1581 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00001582 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00001583
1584 /* Add module symbols first. */
1585
1586 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1587 if (m->nsyms
1588 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1589 m->nsyms)) m->used = 1, ++nused;
1590
1591 n_ext_modules_used = nused;
1592
1593 /* And finally the symbols from the kernel proper. */
1594
1595 if (nksyms)
1596 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1597}
1598
1599static char *get_modinfo_value(struct obj_file *f, const char *key)
1600{
1601 struct obj_section *sec;
1602 char *p, *v, *n, *ep;
1603 size_t klen = strlen(key);
1604
1605 sec = obj_find_section(f, ".modinfo");
1606 if (sec == NULL)
1607 return NULL;
1608 p = sec->contents;
1609 ep = p + sec->header.sh_size;
1610 while (p < ep) {
1611 v = strchr(p, '=');
1612 n = strchr(p, '\0');
1613 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001614 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001615 return v + 1;
1616 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001617 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001618 return n;
1619 }
1620 p = n + 1;
1621 }
1622
1623 return NULL;
1624}
1625
1626
1627/*======================================================================*/
1628/* Functions relating to module loading in pre 2.1 kernels. */
1629
1630static int
1631old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1632{
1633 while (argc > 0) {
1634 char *p, *q;
1635 struct obj_symbol *sym;
1636 int *loc;
1637
1638 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00001639 if ((q = strchr(p, '=')) == NULL) {
1640 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00001641 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00001642 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001643 *q++ = '\0';
1644
1645 sym = obj_find_symbol(f, p);
1646
1647 /* Also check that the parameter was not resolved from the kernel. */
1648 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00001649 error_msg("symbol for parameter %s not found", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001650 return 0;
1651 }
1652
1653 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1654
1655 /* Do C quoting if we begin with a ". */
1656 if (*q == '"') {
1657 char *r, *str;
1658
1659 str = alloca(strlen(q));
1660 for (r = str, q++; *q != '"'; ++q, ++r) {
1661 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00001662 error_msg("improperly terminated string argument for %s", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001663 return 0;
1664 } else if (*q == '\\')
1665 switch (*++q) {
1666 case 'a':
1667 *r = '\a';
1668 break;
1669 case 'b':
1670 *r = '\b';
1671 break;
1672 case 'e':
1673 *r = '\033';
1674 break;
1675 case 'f':
1676 *r = '\f';
1677 break;
1678 case 'n':
1679 *r = '\n';
1680 break;
1681 case 'r':
1682 *r = '\r';
1683 break;
1684 case 't':
1685 *r = '\t';
1686 break;
1687
1688 case '0':
1689 case '1':
1690 case '2':
1691 case '3':
1692 case '4':
1693 case '5':
1694 case '6':
1695 case '7':
1696 {
1697 int c = *q - '0';
1698 if (q[1] >= '0' && q[1] <= '7') {
1699 c = (c * 8) + *++q - '0';
1700 if (q[1] >= '0' && q[1] <= '7')
1701 c = (c * 8) + *++q - '0';
1702 }
1703 *r = c;
1704 }
1705 break;
1706
1707 default:
1708 *r = *q;
1709 break;
1710 } else
1711 *r = *q;
1712 }
1713 *r = '\0';
1714 obj_string_patch(f, sym->secidx, sym->value, str);
1715 } else if (*q >= '0' && *q <= '9') {
1716 do
1717 *loc++ = strtoul(q, &q, 0);
1718 while (*q++ == ',');
1719 } else {
1720 char *contents = f->sections[sym->secidx]->contents;
Eric Andersene76c3b02001-04-05 03:14:39 +00001721 char *myloc = contents + sym->value;
Eric Andersen9f16d612000-06-12 23:11:16 +00001722 char *r; /* To search for commas */
1723
1724 /* Break the string with comas */
1725 while ((r = strchr(q, ',')) != (char *) NULL) {
1726 *r++ = '\0';
Eric Andersene76c3b02001-04-05 03:14:39 +00001727 obj_string_patch(f, sym->secidx, myloc - contents, q);
1728 myloc += sizeof(char *);
Eric Andersen9f16d612000-06-12 23:11:16 +00001729 q = r;
1730 }
1731
1732 /* last part */
Eric Andersene76c3b02001-04-05 03:14:39 +00001733 obj_string_patch(f, sym->secidx, myloc - contents, q);
Eric Andersen9f16d612000-06-12 23:11:16 +00001734 }
1735
1736 argc--, argv++;
1737 }
1738
1739 return 1;
1740}
1741
1742#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1743static int old_is_module_checksummed(struct obj_file *f)
1744{
1745 return obj_find_symbol(f, "Using_Versions") != NULL;
1746}
1747/* Get the module's kernel version in the canonical integer form. */
1748
1749static int
1750old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1751{
1752 struct obj_symbol *sym;
1753 char *p, *q;
1754 int a, b, c;
1755
1756 sym = obj_find_symbol(f, "kernel_version");
1757 if (sym == NULL)
1758 return -1;
1759
1760 p = f->sections[sym->secidx]->contents + sym->value;
1761 strncpy(str, p, STRVERSIONLEN);
1762
1763 a = strtoul(p, &p, 10);
1764 if (*p != '.')
1765 return -1;
1766 b = strtoul(p + 1, &p, 10);
1767 if (*p != '.')
1768 return -1;
1769 c = strtoul(p + 1, &q, 10);
1770 if (p + 1 == q)
1771 return -1;
1772
1773 return a << 16 | b << 8 | c;
1774}
1775
1776#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1777
Eric Andersenf5d5e772001-01-24 23:34:48 +00001778#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00001779
1780/* Fetch all the symbols and divvy them up as appropriate for the modules. */
1781
Eric Andersen8c185f92000-09-22 00:38:07 +00001782static int old_get_kernel_symbols(const char *m_name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001783{
1784 struct old_kernel_sym *ks, *k;
1785 struct new_module_symbol *s;
1786 struct external_module *mod;
1787 int nks, nms, nmod, i;
1788
1789 nks = get_kernel_syms(NULL);
Eric Andersenf2278152001-04-24 21:41:41 +00001790 if (nks <= 0) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00001791 if (nks)
1792 perror_msg("get_kernel_syms: %s", m_name);
1793 else
1794 error_msg("No kernel symbols");
Eric Andersen9f16d612000-06-12 23:11:16 +00001795 return 0;
1796 }
1797
1798 ks = k = xmalloc(nks * sizeof(*ks));
1799
1800 if (get_kernel_syms(ks) != nks) {
1801 perror("inconsistency with get_kernel_syms -- is someone else "
1802 "playing with modules?");
1803 free(ks);
1804 return 0;
1805 }
1806
1807 /* Collect the module information. */
1808
1809 mod = NULL;
1810 nmod = -1;
1811
1812 while (k->name[0] == '#' && k->name[1]) {
1813 struct old_kernel_sym *k2;
Eric Andersen9f16d612000-06-12 23:11:16 +00001814
1815 /* Find out how many symbols this module has. */
1816 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1817 continue;
1818 nms = k2 - k - 1;
1819
1820 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1821 mod[nmod].name = k->name + 1;
1822 mod[nmod].addr = k->value;
1823 mod[nmod].used = 0;
1824 mod[nmod].nsyms = nms;
1825 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1826
1827 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1828 s->name = (unsigned long) k->name;
1829 s->value = k->value;
1830 }
1831
1832 k = k2;
1833 }
1834
1835 ext_modules = mod;
1836 n_ext_modules = nmod + 1;
1837
1838 /* Now collect the symbols for the kernel proper. */
1839
1840 if (k->name[0] == '#')
1841 ++k;
1842
1843 nksyms = nms = nks - (k - ks);
1844 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1845
1846 for (i = 0; i < nms; ++i, ++s, ++k) {
1847 s->name = (unsigned long) k->name;
1848 s->value = k->value;
1849 }
1850
1851 return 1;
1852}
1853
1854/* Return the kernel symbol checksum version, or zero if not used. */
1855
1856static int old_is_kernel_checksummed(void)
1857{
1858 /* Using_Versions is the first symbol. */
1859 if (nksyms > 0
1860 && strcmp((char *) ksyms[0].name,
1861 "Using_Versions") == 0) return ksyms[0].value;
1862 else
1863 return 0;
1864}
1865
1866
1867static int old_create_mod_use_count(struct obj_file *f)
1868{
1869 struct obj_section *sec;
1870
1871 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1872 sizeof(long));
1873
1874 obj_add_symbol(f, "mod_use_count_", -1,
1875 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1876 sizeof(long));
1877
1878 return 1;
1879}
1880
1881static int
1882old_init_module(const char *m_name, struct obj_file *f,
1883 unsigned long m_size)
1884{
1885 char *image;
1886 struct old_mod_routines routines;
1887 struct old_symbol_table *symtab;
1888 int ret;
1889
1890 /* Create the symbol table */
1891 {
1892 int nsyms = 0, strsize = 0, total;
1893
1894 /* Size things first... */
1895 if (flag_export) {
1896 int i;
1897 for (i = 0; i < HASH_BUCKETS; ++i) {
1898 struct obj_symbol *sym;
1899 for (sym = f->symtab[i]; sym; sym = sym->next)
1900 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1901 && sym->secidx <= SHN_HIRESERVE)
1902 {
1903 sym->ksymidx = nsyms++;
1904 strsize += strlen(sym->name) + 1;
1905 }
1906 }
1907 }
1908
1909 total = (sizeof(struct old_symbol_table)
1910 + nsyms * sizeof(struct old_module_symbol)
1911 + n_ext_modules_used * sizeof(struct old_module_ref)
1912 + strsize);
1913 symtab = xmalloc(total);
1914 symtab->size = total;
1915 symtab->n_symbols = nsyms;
1916 symtab->n_refs = n_ext_modules_used;
1917
1918 if (flag_export && nsyms) {
1919 struct old_module_symbol *ksym;
1920 char *str;
1921 int i;
1922
1923 ksym = symtab->symbol;
1924 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1925 + n_ext_modules_used * sizeof(struct old_module_ref));
1926
1927 for (i = 0; i < HASH_BUCKETS; ++i) {
1928 struct obj_symbol *sym;
1929 for (sym = f->symtab[i]; sym; sym = sym->next)
1930 if (sym->ksymidx >= 0) {
1931 ksym->addr = obj_symbol_final_value(f, sym);
1932 ksym->name =
1933 (unsigned long) str - (unsigned long) symtab;
1934
Matt Kraai70a78552001-01-04 02:00:17 +00001935 strcpy(str, sym->name);
1936 str += strlen(sym->name) + 1;
Eric Andersen9f16d612000-06-12 23:11:16 +00001937 ksym++;
1938 }
1939 }
1940 }
1941
1942 if (n_ext_modules_used) {
1943 struct old_module_ref *ref;
1944 int i;
1945
1946 ref = (struct old_module_ref *)
1947 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1948
1949 for (i = 0; i < n_ext_modules; ++i)
1950 if (ext_modules[i].used)
1951 ref++->module = ext_modules[i].addr;
1952 }
1953 }
1954
1955 /* Fill in routines. */
1956
1957 routines.init =
1958 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1959 routines.cleanup =
1960 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1961
1962 /* Whew! All of the initialization is complete. Collect the final
1963 module image and give it to the kernel. */
1964
1965 image = xmalloc(m_size);
1966 obj_create_image(f, image);
1967
1968 /* image holds the complete relocated module, accounting correctly for
1969 mod_use_count. However the old module kernel support assume that
1970 it is receiving something which does not contain mod_use_count. */
1971 ret = old_sys_init_module(m_name, image + sizeof(long),
1972 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1973 : 0), &routines, symtab);
1974 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00001975 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001976
1977 free(image);
1978 free(symtab);
1979
1980 return ret == 0;
1981}
1982
1983#else
1984
1985#define old_create_mod_use_count(x) TRUE
1986#define old_init_module(x, y, z) TRUE
1987
Eric Andersenf5d5e772001-01-24 23:34:48 +00001988#endif /* BB_FEATURE_OLD_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00001989
1990
1991
1992/*======================================================================*/
1993/* Functions relating to module loading after 2.1.18. */
1994
1995static int
1996new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1997{
1998 while (argc > 0) {
1999 char *p, *q, *key;
2000 struct obj_symbol *sym;
2001 char *contents, *loc;
2002 int min, max, n;
2003
2004 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00002005 if ((q = strchr(p, '=')) == NULL) {
2006 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00002007 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00002008 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002009
2010 key = alloca(q - p + 6);
2011 memcpy(key, "parm_", 5);
2012 memcpy(key + 5, p, q - p);
2013 key[q - p + 5] = 0;
2014
2015 p = get_modinfo_value(f, key);
2016 key += 5;
2017 if (p == NULL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002018 error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002019 return 0;
2020 }
2021
2022 sym = obj_find_symbol(f, key);
2023
2024 /* Also check that the parameter was not resolved from the kernel. */
2025 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002026 error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002027 return 0;
2028 }
2029
2030 if (isdigit(*p)) {
2031 min = strtoul(p, &p, 10);
2032 if (*p == '-')
2033 max = strtoul(p + 1, &p, 10);
2034 else
2035 max = min;
2036 } else
2037 min = max = 1;
2038
2039 contents = f->sections[sym->secidx]->contents;
2040 loc = contents + sym->value;
2041 n = (*++q != '\0');
2042
2043 while (1) {
2044 if ((*p == 's') || (*p == 'c')) {
2045 char *str;
2046
2047 /* Do C quoting if we begin with a ", else slurp the lot. */
2048 if (*q == '"') {
2049 char *r;
2050
2051 str = alloca(strlen(q));
2052 for (r = str, q++; *q != '"'; ++q, ++r) {
2053 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00002054 error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002055 key);
2056 return 0;
2057 } else if (*q == '\\')
2058 switch (*++q) {
2059 case 'a':
2060 *r = '\a';
2061 break;
2062 case 'b':
2063 *r = '\b';
2064 break;
2065 case 'e':
2066 *r = '\033';
2067 break;
2068 case 'f':
2069 *r = '\f';
2070 break;
2071 case 'n':
2072 *r = '\n';
2073 break;
2074 case 'r':
2075 *r = '\r';
2076 break;
2077 case 't':
2078 *r = '\t';
2079 break;
2080
2081 case '0':
2082 case '1':
2083 case '2':
2084 case '3':
2085 case '4':
2086 case '5':
2087 case '6':
2088 case '7':
2089 {
2090 int c = *q - '0';
2091 if (q[1] >= '0' && q[1] <= '7') {
2092 c = (c * 8) + *++q - '0';
2093 if (q[1] >= '0' && q[1] <= '7')
2094 c = (c * 8) + *++q - '0';
2095 }
2096 *r = c;
2097 }
2098 break;
2099
2100 default:
2101 *r = *q;
2102 break;
2103 } else
2104 *r = *q;
2105 }
2106 *r = '\0';
2107 ++q;
2108 } else {
2109 char *r;
2110
2111 /* In this case, the string is not quoted. We will break
2112 it using the coma (like for ints). If the user wants to
2113 include comas in a string, he just has to quote it */
2114
2115 /* Search the next coma */
2116 r = strchr(q, ',');
2117
2118 /* Found ? */
2119 if (r != (char *) NULL) {
2120 /* Recopy the current field */
2121 str = alloca(r - q + 1);
2122 memcpy(str, q, r - q);
2123
2124 /* I don't know if it is usefull, as the previous case
2125 doesn't null terminate the string ??? */
2126 str[r - q] = '\0';
2127
2128 /* Keep next fields */
2129 q = r;
2130 } else {
2131 /* last string */
2132 str = q;
2133 q = "";
2134 }
2135 }
2136
2137 if (*p == 's') {
2138 /* Normal string */
2139 obj_string_patch(f, sym->secidx, loc - contents, str);
2140 loc += tgt_sizeof_char_p;
2141 } else {
2142 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002143 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002144
2145 /* Get the size of each member */
2146 /* Probably we should do that outside the loop ? */
2147 if (!isdigit(*(p + 1))) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00002148 error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002149 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002150 return 0;
2151 }
2152 charssize = strtoul(p + 1, (char **) NULL, 10);
2153
2154 /* Check length */
2155 if (strlen(str) >= charssize) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002156 error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002157 charssize - 1);
2158 return 0;
2159 }
2160
2161 /* Copy to location */
2162 strcpy((char *) loc, str);
2163 loc += charssize;
2164 }
2165 } else {
2166 long v = strtoul(q, &q, 0);
2167 switch (*p) {
2168 case 'b':
2169 *loc++ = v;
2170 break;
2171 case 'h':
2172 *(short *) loc = v;
2173 loc += tgt_sizeof_short;
2174 break;
2175 case 'i':
2176 *(int *) loc = v;
2177 loc += tgt_sizeof_int;
2178 break;
2179 case 'l':
2180 *(long *) loc = v;
2181 loc += tgt_sizeof_long;
2182 break;
2183
2184 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002185 error_msg("unknown parameter type '%c' for %s", *p, key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002186 return 0;
2187 }
2188 }
2189
2190 retry_end_of_value:
2191 switch (*q) {
2192 case '\0':
2193 goto end_of_arg;
2194
2195 case ' ':
2196 case '\t':
2197 case '\n':
2198 case '\r':
2199 ++q;
2200 goto retry_end_of_value;
2201
2202 case ',':
2203 if (++n > max) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002204 error_msg("too many values for %s (max %d)", key, max);
Eric Andersen9f16d612000-06-12 23:11:16 +00002205 return 0;
2206 }
2207 ++q;
2208 break;
2209
2210 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002211 error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002212 return 0;
2213 }
2214 }
2215
2216 end_of_arg:
2217 if (n < min) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002218 error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002219 return 0;
2220 }
2221
2222 argc--, argv++;
2223 }
2224
2225 return 1;
2226}
2227
2228#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2229static int new_is_module_checksummed(struct obj_file *f)
2230{
2231 const char *p = get_modinfo_value(f, "using_checksums");
2232 if (p)
2233 return atoi(p);
2234 else
2235 return 0;
2236}
2237
2238/* Get the module's kernel version in the canonical integer form. */
2239
2240static int
2241new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2242{
2243 char *p, *q;
2244 int a, b, c;
2245
2246 p = get_modinfo_value(f, "kernel_version");
2247 if (p == NULL)
2248 return -1;
2249 strncpy(str, p, STRVERSIONLEN);
2250
2251 a = strtoul(p, &p, 10);
2252 if (*p != '.')
2253 return -1;
2254 b = strtoul(p + 1, &p, 10);
2255 if (*p != '.')
2256 return -1;
2257 c = strtoul(p + 1, &q, 10);
2258 if (p + 1 == q)
2259 return -1;
2260
2261 return a << 16 | b << 8 | c;
2262}
2263
2264#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2265
2266
Eric Andersenf5d5e772001-01-24 23:34:48 +00002267#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00002268
2269/* Fetch the loaded modules, and all currently exported symbols. */
2270
2271static int new_get_kernel_symbols(void)
2272{
2273 char *module_names, *mn;
2274 struct external_module *modules, *m;
2275 struct new_module_symbol *syms, *s;
2276 size_t ret, bufsize, nmod, nsyms, i, j;
2277
2278 /* Collect the loaded modules. */
2279
2280 module_names = xmalloc(bufsize = 256);
2281 retry_modules_load:
2282 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002283 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002284 module_names = xrealloc(module_names, bufsize = ret);
2285 goto retry_modules_load;
2286 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002287 perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002288 return 0;
2289 }
2290
2291 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002292
2293 /* Collect the modules' symbols. */
2294
Mark Whitley94fd4802001-03-12 23:08:34 +00002295 if (nmod){
2296 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2297 memset(modules, 0, nmod * sizeof(*modules));
2298 for (i = 0, mn = module_names, m = modules;
2299 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2300 struct new_module_info info;
2301
2302 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2303 if (errno == ENOENT) {
2304 /* The module was removed out from underneath us. */
2305 continue;
2306 }
2307 perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002308 return 0;
2309 }
Mark Whitley94fd4802001-03-12 23:08:34 +00002310
2311 syms = xmalloc(bufsize = 1024);
2312 retry_mod_sym_load:
2313 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2314 switch (errno) {
2315 case ENOSPC:
2316 syms = xrealloc(syms, bufsize = ret);
2317 goto retry_mod_sym_load;
2318 case ENOENT:
2319 /* The module was removed out from underneath us. */
2320 continue;
2321 default:
2322 perror_msg("query_module: QM_SYMBOLS: %s", mn);
2323 return 0;
2324 }
2325 }
2326 nsyms = ret;
2327
2328 m->name = mn;
2329 m->addr = info.addr;
2330 m->nsyms = nsyms;
2331 m->syms = syms;
2332
2333 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2334 s->name += (unsigned long) syms;
2335 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002336 }
2337 }
2338
2339 /* Collect the kernel's symbols. */
2340
2341 syms = xmalloc(bufsize = 16 * 1024);
2342 retry_kern_sym_load:
2343 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002344 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002345 syms = xrealloc(syms, bufsize = ret);
2346 goto retry_kern_sym_load;
2347 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002348 perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002349 return 0;
2350 }
2351 nksyms = nsyms = ret;
2352 ksyms = syms;
2353
2354 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2355 s->name += (unsigned long) syms;
2356 }
2357 return 1;
2358}
2359
2360
2361/* Return the kernel symbol checksum version, or zero if not used. */
2362
2363static int new_is_kernel_checksummed(void)
2364{
2365 struct new_module_symbol *s;
2366 size_t i;
2367
2368 /* Using_Versions is not the first symbol, but it should be in there. */
2369
2370 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2371 if (strcmp((char *) s->name, "Using_Versions") == 0)
2372 return s->value;
2373
2374 return 0;
2375}
2376
2377
2378static int new_create_this_module(struct obj_file *f, const char *m_name)
2379{
2380 struct obj_section *sec;
2381
2382 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2383 sizeof(struct new_module));
2384 memset(sec->contents, 0, sizeof(struct new_module));
2385
2386 obj_add_symbol(f, "__this_module", -1,
2387 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2388 sizeof(struct new_module));
2389
2390 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2391 m_name);
2392
2393 return 1;
2394}
2395
2396
2397static int new_create_module_ksymtab(struct obj_file *f)
2398{
2399 struct obj_section *sec;
2400 int i;
2401
2402 /* We must always add the module references. */
2403
2404 if (n_ext_modules_used) {
2405 struct new_module_ref *dep;
2406 struct obj_symbol *tm;
2407
2408 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2409 (sizeof(struct new_module_ref)
2410 * n_ext_modules_used));
2411 if (!sec)
2412 return 0;
2413
2414 tm = obj_find_symbol(f, "__this_module");
2415 dep = (struct new_module_ref *) sec->contents;
2416 for (i = 0; i < n_ext_modules; ++i)
2417 if (ext_modules[i].used) {
2418 dep->dep = ext_modules[i].addr;
2419 obj_symbol_patch(f, sec->idx,
2420 (char *) &dep->ref - sec->contents, tm);
2421 dep->next_ref = 0;
2422 ++dep;
2423 }
2424 }
2425
2426 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2427 size_t nsyms;
2428 int *loaded;
2429
2430 sec =
2431 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2432 0);
2433
2434 /* We don't want to export symbols residing in sections that
2435 aren't loaded. There are a number of these created so that
2436 we make sure certain module options don't appear twice. */
2437
2438 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2439 while (--i >= 0)
2440 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2441
2442 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2443 struct obj_symbol *sym;
2444 for (sym = f->symtab[i]; sym; sym = sym->next)
2445 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2446 && sym->secidx <= SHN_HIRESERVE
2447 && (sym->secidx >= SHN_LORESERVE
2448 || loaded[sym->secidx])) {
2449 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2450
2451 obj_symbol_patch(f, sec->idx, ofs, sym);
2452 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2453 sym->name);
2454
2455 nsyms++;
2456 }
2457 }
2458
2459 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2460 }
2461
2462 return 1;
2463}
2464
2465
2466static int
2467new_init_module(const char *m_name, struct obj_file *f,
2468 unsigned long m_size)
2469{
2470 struct new_module *module;
2471 struct obj_section *sec;
2472 void *image;
2473 int ret;
2474 tgt_long m_addr;
2475
2476 sec = obj_find_section(f, ".this");
2477 module = (struct new_module *) sec->contents;
2478 m_addr = sec->header.sh_addr;
2479
2480 module->size_of_struct = sizeof(*module);
2481 module->size = m_size;
2482 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2483
2484 sec = obj_find_section(f, "__ksymtab");
2485 if (sec && sec->header.sh_size) {
2486 module->syms = sec->header.sh_addr;
2487 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2488 }
2489
2490 if (n_ext_modules_used) {
2491 sec = obj_find_section(f, ".kmodtab");
2492 module->deps = sec->header.sh_addr;
2493 module->ndeps = n_ext_modules_used;
2494 }
2495
2496 module->init =
2497 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2498 module->cleanup =
2499 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2500
2501 sec = obj_find_section(f, "__ex_table");
2502 if (sec) {
2503 module->ex_table_start = sec->header.sh_addr;
2504 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2505 }
2506
2507 sec = obj_find_section(f, ".text.init");
2508 if (sec) {
2509 module->runsize = sec->header.sh_addr - m_addr;
2510 }
2511 sec = obj_find_section(f, ".data.init");
2512 if (sec) {
2513 if (!module->runsize ||
2514 module->runsize > sec->header.sh_addr - m_addr)
2515 module->runsize = sec->header.sh_addr - m_addr;
2516 }
2517
2518 if (!arch_init_module(f, module))
2519 return 0;
2520
2521 /* Whew! All of the initialization is complete. Collect the final
2522 module image and give it to the kernel. */
2523
2524 image = xmalloc(m_size);
2525 obj_create_image(f, image);
2526
Eric Andersen64c8b172001-04-05 07:33:10 +00002527 ret = new_sys_init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002528 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002529 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002530
2531 free(image);
2532
2533 return ret == 0;
2534}
2535
2536#else
2537
2538#define new_init_module(x, y, z) TRUE
2539#define new_create_this_module(x, y) 0
2540#define new_create_module_ksymtab(x)
Eric Andersen21adca72000-12-06 18:18:26 +00002541#define query_module(v, w, x, y, z) -1
Eric Andersen9f16d612000-06-12 23:11:16 +00002542
Eric Andersenf5d5e772001-01-24 23:34:48 +00002543#endif /* BB_FEATURE_NEW_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00002544
2545
2546/*======================================================================*/
2547
2548int
2549obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2550 const char *string)
2551{
2552 struct obj_string_patch *p;
2553 struct obj_section *strsec;
2554 size_t len = strlen(string) + 1;
2555 char *loc;
2556
2557 p = xmalloc(sizeof(*p));
2558 p->next = f->string_patches;
2559 p->reloc_secidx = secidx;
2560 p->reloc_offset = offset;
2561 f->string_patches = p;
2562
2563 strsec = obj_find_section(f, ".kstrtab");
2564 if (strsec == NULL) {
2565 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2566 p->string_offset = 0;
2567 loc = strsec->contents;
2568 } else {
2569 p->string_offset = strsec->header.sh_size;
2570 loc = obj_extend_section(strsec, len);
2571 }
2572 memcpy(loc, string, len);
2573
2574 return 1;
2575}
2576
2577int
2578obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2579 struct obj_symbol *sym)
2580{
2581 struct obj_symbol_patch *p;
2582
2583 p = xmalloc(sizeof(*p));
2584 p->next = f->symbol_patches;
2585 p->reloc_secidx = secidx;
2586 p->reloc_offset = offset;
2587 p->sym = sym;
2588 f->symbol_patches = p;
2589
2590 return 1;
2591}
2592
2593int obj_check_undefineds(struct obj_file *f)
2594{
2595 unsigned long i;
2596 int ret = 1;
2597
2598 for (i = 0; i < HASH_BUCKETS; ++i) {
2599 struct obj_symbol *sym;
2600 for (sym = f->symtab[i]; sym; sym = sym->next)
2601 if (sym->secidx == SHN_UNDEF) {
2602 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2603 sym->secidx = SHN_ABS;
2604 sym->value = 0;
2605 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002606 error_msg("unresolved symbol %s", sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002607 ret = 0;
2608 }
2609 }
2610 }
2611
2612 return ret;
2613}
2614
2615void obj_allocate_commons(struct obj_file *f)
2616{
2617 struct common_entry {
2618 struct common_entry *next;
2619 struct obj_symbol *sym;
2620 } *common_head = NULL;
2621
2622 unsigned long i;
2623
2624 for (i = 0; i < HASH_BUCKETS; ++i) {
2625 struct obj_symbol *sym;
2626 for (sym = f->symtab[i]; sym; sym = sym->next)
2627 if (sym->secidx == SHN_COMMON) {
2628 /* Collect all COMMON symbols and sort them by size so as to
2629 minimize space wasted by alignment requirements. */
2630 {
2631 struct common_entry **p, *n;
2632 for (p = &common_head; *p; p = &(*p)->next)
2633 if (sym->size <= (*p)->sym->size)
2634 break;
2635
2636 n = alloca(sizeof(*n));
2637 n->next = *p;
2638 n->sym = sym;
2639 *p = n;
2640 }
2641 }
2642 }
2643
2644 for (i = 1; i < f->local_symtab_size; ++i) {
2645 struct obj_symbol *sym = f->local_symtab[i];
2646 if (sym && sym->secidx == SHN_COMMON) {
2647 struct common_entry **p, *n;
2648 for (p = &common_head; *p; p = &(*p)->next)
2649 if (sym == (*p)->sym)
2650 break;
2651 else if (sym->size < (*p)->sym->size) {
2652 n = alloca(sizeof(*n));
2653 n->next = *p;
2654 n->sym = sym;
2655 *p = n;
2656 break;
2657 }
2658 }
2659 }
2660
2661 if (common_head) {
2662 /* Find the bss section. */
2663 for (i = 0; i < f->header.e_shnum; ++i)
2664 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2665 break;
2666
2667 /* If for some reason there hadn't been one, create one. */
2668 if (i == f->header.e_shnum) {
2669 struct obj_section *sec;
2670
2671 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2672 f->sections[i] = sec = arch_new_section();
2673 f->header.e_shnum = i + 1;
2674
2675 memset(sec, 0, sizeof(*sec));
2676 sec->header.sh_type = SHT_PROGBITS;
2677 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2678 sec->name = ".bss";
2679 sec->idx = i;
2680 }
2681
2682 /* Allocate the COMMONS. */
2683 {
2684 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2685 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2686 struct common_entry *c;
2687
2688 for (c = common_head; c; c = c->next) {
2689 ElfW(Addr) align = c->sym->value;
2690
2691 if (align > max_align)
2692 max_align = align;
2693 if (bss_size & (align - 1))
2694 bss_size = (bss_size | (align - 1)) + 1;
2695
2696 c->sym->secidx = i;
2697 c->sym->value = bss_size;
2698
2699 bss_size += c->sym->size;
2700 }
2701
2702 f->sections[i]->header.sh_size = bss_size;
2703 f->sections[i]->header.sh_addralign = max_align;
2704 }
2705 }
2706
2707 /* For the sake of patch relocation and parameter initialization,
2708 allocate zeroed data for NOBITS sections now. Note that after
2709 this we cannot assume NOBITS are really empty. */
2710 for (i = 0; i < f->header.e_shnum; ++i) {
2711 struct obj_section *s = f->sections[i];
2712 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00002713 if (s->header.sh_size != 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002714 s->contents = memset(xmalloc(s->header.sh_size),
2715 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00002716 else
2717 s->contents = NULL;
2718
Eric Andersen9f16d612000-06-12 23:11:16 +00002719 s->header.sh_type = SHT_PROGBITS;
2720 }
2721 }
2722}
2723
2724unsigned long obj_load_size(struct obj_file *f)
2725{
2726 unsigned long dot = 0;
2727 struct obj_section *sec;
2728
2729 /* Finalize the positions of the sections relative to one another. */
2730
2731 for (sec = f->load_order; sec; sec = sec->load_next) {
2732 ElfW(Addr) align;
2733
2734 align = sec->header.sh_addralign;
2735 if (align && (dot & (align - 1)))
2736 dot = (dot | (align - 1)) + 1;
2737
2738 sec->header.sh_addr = dot;
2739 dot += sec->header.sh_size;
2740 }
2741
2742 return dot;
2743}
2744
2745int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2746{
2747 int i, n = f->header.e_shnum;
2748 int ret = 1;
2749
2750 /* Finalize the addresses of the sections. */
2751
2752 f->baseaddr = base;
2753 for (i = 0; i < n; ++i)
2754 f->sections[i]->header.sh_addr += base;
2755
2756 /* And iterate over all of the relocations. */
2757
2758 for (i = 0; i < n; ++i) {
2759 struct obj_section *relsec, *symsec, *targsec, *strsec;
2760 ElfW(RelM) * rel, *relend;
2761 ElfW(Sym) * symtab;
2762 const char *strtab;
2763
2764 relsec = f->sections[i];
2765 if (relsec->header.sh_type != SHT_RELM)
2766 continue;
2767
2768 symsec = f->sections[relsec->header.sh_link];
2769 targsec = f->sections[relsec->header.sh_info];
2770 strsec = f->sections[symsec->header.sh_link];
2771
2772 rel = (ElfW(RelM) *) relsec->contents;
2773 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2774 symtab = (ElfW(Sym) *) symsec->contents;
2775 strtab = (const char *) strsec->contents;
2776
2777 for (; rel < relend; ++rel) {
2778 ElfW(Addr) value = 0;
2779 struct obj_symbol *intsym = NULL;
2780 unsigned long symndx;
2781 ElfW(Sym) * extsym = 0;
2782 const char *errmsg;
2783
2784 /* Attempt to find a value to use for this relocation. */
2785
2786 symndx = ELFW(R_SYM) (rel->r_info);
2787 if (symndx) {
2788 /* Note we've already checked for undefined symbols. */
2789
2790 extsym = &symtab[symndx];
2791 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2792 /* Local symbols we look up in the local table to be sure
2793 we get the one that is really intended. */
2794 intsym = f->local_symtab[symndx];
2795 } else {
2796 /* Others we look up in the hash table. */
2797 const char *name;
2798 if (extsym->st_name)
2799 name = strtab + extsym->st_name;
2800 else
2801 name = f->sections[extsym->st_shndx]->name;
2802 intsym = obj_find_symbol(f, name);
2803 }
2804
2805 value = obj_symbol_final_value(f, intsym);
2806 intsym->referenced = 1;
2807 }
2808#if SHT_RELM == SHT_RELA
2809#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2810 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2811 if (!extsym || !extsym->st_name ||
2812 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2813#endif
2814 value += rel->r_addend;
2815#endif
2816
2817 /* Do it! */
2818 switch (arch_apply_relocation
2819 (f, targsec, symsec, intsym, rel, value)) {
2820 case obj_reloc_ok:
2821 break;
2822
2823 case obj_reloc_overflow:
2824 errmsg = "Relocation overflow";
2825 goto bad_reloc;
2826 case obj_reloc_dangerous:
2827 errmsg = "Dangerous relocation";
2828 goto bad_reloc;
2829 case obj_reloc_unhandled:
2830 errmsg = "Unhandled relocation";
2831 bad_reloc:
2832 if (extsym) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002833 error_msg("%s of type %ld for %s", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002834 (long) ELFW(R_TYPE) (rel->r_info),
2835 strtab + extsym->st_name);
2836 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002837 error_msg("%s of type %ld", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002838 (long) ELFW(R_TYPE) (rel->r_info));
2839 }
2840 ret = 0;
2841 break;
2842 }
2843 }
2844 }
2845
2846 /* Finally, take care of the patches. */
2847
2848 if (f->string_patches) {
2849 struct obj_string_patch *p;
2850 struct obj_section *strsec;
2851 ElfW(Addr) strsec_base;
2852 strsec = obj_find_section(f, ".kstrtab");
2853 strsec_base = strsec->header.sh_addr;
2854
2855 for (p = f->string_patches; p; p = p->next) {
2856 struct obj_section *targsec = f->sections[p->reloc_secidx];
2857 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2858 = strsec_base + p->string_offset;
2859 }
2860 }
2861
2862 if (f->symbol_patches) {
2863 struct obj_symbol_patch *p;
2864
2865 for (p = f->symbol_patches; p; p = p->next) {
2866 struct obj_section *targsec = f->sections[p->reloc_secidx];
2867 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2868 = obj_symbol_final_value(f, p->sym);
2869 }
2870 }
2871
2872 return ret;
2873}
2874
2875int obj_create_image(struct obj_file *f, char *image)
2876{
2877 struct obj_section *sec;
2878 ElfW(Addr) base = f->baseaddr;
2879
2880 for (sec = f->load_order; sec; sec = sec->load_next) {
2881 char *secimg;
2882
Eric Andersen2bf658d2001-02-24 20:01:53 +00002883 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002884 continue;
2885
2886 secimg = image + (sec->header.sh_addr - base);
2887
2888 /* Note that we allocated data for NOBITS sections earlier. */
2889 memcpy(secimg, sec->contents, sec->header.sh_size);
2890 }
2891
2892 return 1;
2893}
2894
2895/*======================================================================*/
2896
2897struct obj_file *obj_load(FILE * fp)
2898{
2899 struct obj_file *f;
2900 ElfW(Shdr) * section_headers;
2901 int shnum, i;
2902 char *shstrtab;
2903
2904 /* Read the file header. */
2905
2906 f = arch_new_file();
2907 memset(f, 0, sizeof(*f));
2908 f->symbol_cmp = strcmp;
2909 f->symbol_hash = obj_elf_hash;
2910 f->load_order_search_start = &f->load_order;
2911
2912 fseek(fp, 0, SEEK_SET);
2913 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002914 perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00002915 return NULL;
2916 }
2917
2918 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2919 || f->header.e_ident[EI_MAG1] != ELFMAG1
2920 || f->header.e_ident[EI_MAG2] != ELFMAG2
2921 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002922 error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00002923 return NULL;
2924 }
2925 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2926 || f->header.e_ident[EI_DATA] != ELFDATAM
2927 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2928 || !MATCH_MACHINE(f->header.e_machine)) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002929 error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002930 return NULL;
2931 }
2932 if (f->header.e_type != ET_REL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002933 error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00002934 return NULL;
2935 }
2936
2937 /* Read the section headers. */
2938
2939 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002940 error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00002941 (unsigned long) f->header.e_shentsize,
2942 (unsigned long) sizeof(ElfW(Shdr)));
2943 return NULL;
2944 }
2945
2946 shnum = f->header.e_shnum;
2947 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2948 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2949
2950 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2951 fseek(fp, f->header.e_shoff, SEEK_SET);
2952 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002953 perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00002954 return NULL;
2955 }
2956
2957 /* Read the section data. */
2958
2959 for (i = 0; i < shnum; ++i) {
2960 struct obj_section *sec;
2961
2962 f->sections[i] = sec = arch_new_section();
2963 memset(sec, 0, sizeof(*sec));
2964
2965 sec->header = section_headers[i];
2966 sec->idx = i;
2967
Eric Andersen2bf658d2001-02-24 20:01:53 +00002968 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002969 case SHT_NULL:
2970 case SHT_NOTE:
2971 case SHT_NOBITS:
2972 /* ignore */
2973 break;
2974
2975 case SHT_PROGBITS:
2976 case SHT_SYMTAB:
2977 case SHT_STRTAB:
2978 case SHT_RELM:
2979 if (sec->header.sh_size > 0) {
2980 sec->contents = xmalloc(sec->header.sh_size);
2981 fseek(fp, sec->header.sh_offset, SEEK_SET);
2982 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002983 perror_msg("error reading ELF section data");
Eric Andersen9f16d612000-06-12 23:11:16 +00002984 return NULL;
2985 }
2986 } else {
2987 sec->contents = NULL;
2988 }
2989 break;
2990
2991#if SHT_RELM == SHT_REL
2992 case SHT_RELA:
Matt Kraaidd19c692001-01-31 19:00:21 +00002993 error_msg("RELA relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002994 return NULL;
2995#else
2996 case SHT_REL:
Matt Kraaidd19c692001-01-31 19:00:21 +00002997 error_msg("REL relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002998 return NULL;
2999#endif
3000
3001 default:
3002 if (sec->header.sh_type >= SHT_LOPROC) {
3003 /* Assume processor specific section types are debug
3004 info and can safely be ignored. If this is ever not
3005 the case (Hello MIPS?), don't put ifdefs here but
3006 create an arch_load_proc_section(). */
3007 break;
3008 }
3009
Matt Kraaidd19c692001-01-31 19:00:21 +00003010 error_msg("can't handle sections of type %ld",
Eric Andersen9f16d612000-06-12 23:11:16 +00003011 (long) sec->header.sh_type);
3012 return NULL;
3013 }
3014 }
3015
3016 /* Do what sort of interpretation as needed by each section. */
3017
3018 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3019
3020 for (i = 0; i < shnum; ++i) {
3021 struct obj_section *sec = f->sections[i];
3022 sec->name = shstrtab + sec->header.sh_name;
3023 }
3024
3025 for (i = 0; i < shnum; ++i) {
3026 struct obj_section *sec = f->sections[i];
3027
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003028 /* .modinfo should be contents only but gcc has no attribute for that.
3029 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3030 */
3031 if (strcmp(sec->name, ".modinfo") == 0)
3032 sec->header.sh_flags &= ~SHF_ALLOC;
3033
Eric Andersen9f16d612000-06-12 23:11:16 +00003034 if (sec->header.sh_flags & SHF_ALLOC)
3035 obj_insert_section_load_order(f, sec);
3036
3037 switch (sec->header.sh_type) {
3038 case SHT_SYMTAB:
3039 {
3040 unsigned long nsym, j;
3041 char *strtab;
3042 ElfW(Sym) * sym;
3043
3044 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003045 error_msg("symbol size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003046 (unsigned long) sec->header.sh_entsize,
3047 (unsigned long) sizeof(ElfW(Sym)));
3048 return NULL;
3049 }
3050
3051 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3052 strtab = f->sections[sec->header.sh_link]->contents;
3053 sym = (ElfW(Sym) *) sec->contents;
3054
3055 /* Allocate space for a table of local symbols. */
3056 j = f->local_symtab_size = sec->header.sh_info;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003057 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003058
3059 /* Insert all symbols into the hash table. */
3060 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3061 const char *name;
3062 if (sym->st_name)
3063 name = strtab + sym->st_name;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003064 else
Eric Andersen9f16d612000-06-12 23:11:16 +00003065 name = f->sections[sym->st_shndx]->name;
3066
3067 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3068 sym->st_value, sym->st_size);
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003069 }
3070 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003071 break;
3072
3073 case SHT_RELM:
3074 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003075 error_msg("relocation entry size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003076 (unsigned long) sec->header.sh_entsize,
3077 (unsigned long) sizeof(ElfW(RelM)));
3078 return NULL;
3079 }
3080 break;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003081 /* XXX Relocation code from modutils-2.3.19 is not here.
3082 * Why? That's about 20 lines of code from obj/obj_load.c,
3083 * which gets done in a second pass through the sections.
3084 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003085 }
3086 }
3087
3088 return f;
3089}
3090
3091static void hide_special_symbols(struct obj_file *f)
3092{
3093 static const char *const specials[] = {
3094 "cleanup_module",
3095 "init_module",
3096 "kernel_version",
3097 NULL
3098 };
3099
3100 struct obj_symbol *sym;
3101 const char *const *p;
3102
3103 for (p = specials; *p; ++p)
3104 if ((sym = obj_find_symbol(f, *p)) != NULL)
3105 sym->info =
3106 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3107}
3108
3109
3110
3111extern int insmod_main( int argc, char **argv)
3112{
Eric Andersena18aaf12001-01-24 19:07:09 +00003113 int opt;
Eric Andersen9f16d612000-06-12 23:11:16 +00003114 int k_crcs;
3115 int k_new_syscalls;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003116 int len;
3117 char *tmp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003118 unsigned long m_size;
3119 ElfW(Addr) m_addr;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003120 FILE *fp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003121 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003122 struct stat st;
Eric Andersen9f16d612000-06-12 23:11:16 +00003123 char m_name[BUFSIZ + 1] = "\0";
Matt Kraai3e856ce2000-12-01 02:55:13 +00003124 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003125 int m_has_modinfo;
3126#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3127 int k_version;
3128 char k_strversion[STRVERSIONLEN];
3129 char m_strversion[STRVERSIONLEN];
3130 int m_version;
3131 int m_crcs;
3132#endif
3133
Erik Andersene49d5ec2000-02-08 19:58:47 +00003134 /* Parse any options */
Eric Andersen155c89b2001-01-25 04:11:06 +00003135 while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
Eric Andersena18aaf12001-01-24 19:07:09 +00003136 switch (opt) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003137 case 'f': /* force loading */
3138 flag_force_load = 1;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003139 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003140 case 'k': /* module loaded by kerneld, auto-cleanable */
3141 flag_autoclean = 1;
3142 break;
3143 case 'v': /* verbose output */
3144 flag_verbose = 1;
3145 break;
3146 case 'x': /* do not export externs */
3147 flag_export = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003148 break;
Eric Andersen155c89b2001-01-25 04:11:06 +00003149 case 'o': /* name the output module */
3150 strncpy(m_name, optarg, BUFSIZ);
3151 break;
Eric Andersena18aaf12001-01-24 19:07:09 +00003152 case 'L': /* Stub warning */
3153 /* This is needed for compatibility with modprobe.
3154 * In theory, this does locking, but we don't do
3155 * that. So be careful and plan your life around not
3156 * loading the same module 50 times concurrently. */
3157 break;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003158 default:
Eric Andersen67991cf2001-02-14 21:23:06 +00003159 show_usage();
Erik Andersene49d5ec2000-02-08 19:58:47 +00003160 }
Erik Andersend387d011999-12-21 02:55:11 +00003161 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003162
3163 if (argv[optind] == NULL) {
Eric Andersen67991cf2001-02-14 21:23:06 +00003164 show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003165 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003166
Erik Andersene49d5ec2000-02-08 19:58:47 +00003167 /* Grab the module name */
Eric Andersena18aaf12001-01-24 19:07:09 +00003168 if ((tmp = strrchr(argv[optind], '/')) != NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003169 tmp++;
Eric Andersen9f16d612000-06-12 23:11:16 +00003170 } else {
Eric Andersena18aaf12001-01-24 19:07:09 +00003171 tmp = argv[optind];
Eric Andersen9f16d612000-06-12 23:11:16 +00003172 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003173 len = strlen(tmp);
3174
3175 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3176 len -= 2;
Eric Andersenf2278152001-04-24 21:41:41 +00003177 memcpy(m_fullName, tmp, len);
3178 m_fullName[len]='\0';
Eric Andersen114ad9c2001-01-26 01:52:14 +00003179 if (*m_name == '\0') {
3180 strcpy(m_name, m_fullName);
Eric Andersen155c89b2001-01-25 04:11:06 +00003181 }
Eric Andersen114ad9c2001-01-26 01:52:14 +00003182 strcat(m_fullName, ".o");
Erik Andersene49d5ec2000-02-08 19:58:47 +00003183
3184 /* Get a filedesc for the module */
Eric Andersen02b9f422001-02-15 19:07:43 +00003185 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3186 (fp = fopen(argv[optind], "r")) == NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003187 /* Hmpf. Could not open it. Search through _PATH_MODULES to find a module named m_name */
Mark Whitleyf57c9442000-12-07 19:56:48 +00003188 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
Matt Kraai0f8f7b82000-08-01 18:16:56 +00003189 findNamedModule, 0, m_fullName) == FALSE)
Eric Andersen9f16d612000-06-12 23:11:16 +00003190 {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003191 if (m_filename[0] == '\0'
Eric Andersen9f16d612000-06-12 23:11:16 +00003192 || ((fp = fopen(m_filename, "r")) == NULL))
3193 {
Matt Kraaidd19c692001-01-31 19:00:21 +00003194 error_msg("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
Matt Kraai3e856ce2000-12-01 02:55:13 +00003195 return EXIT_FAILURE;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003196 }
Matt Kraai0f8f7b82000-08-01 18:16:56 +00003197 } else
Matt Kraaidd19c692001-01-31 19:00:21 +00003198 error_msg_and_die("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003199 } else
Eric Andersenf2278152001-04-24 21:41:41 +00003200 safe_strncpy(m_filename, argv[optind], sizeof(m_filename));
Erik Andersend387d011999-12-21 02:55:11 +00003201
3202
Matt Kraaia9819b22000-12-22 01:48:07 +00003203 if ((f = obj_load(fp)) == NULL)
3204 perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00003205
Eric Andersen9f16d612000-06-12 23:11:16 +00003206 if (get_modinfo_value(f, "kernel_version") == NULL)
3207 m_has_modinfo = 0;
3208 else
3209 m_has_modinfo = 1;
3210
3211#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3212 /* Version correspondence? */
3213
3214 k_version = get_kernel_version(k_strversion);
3215 if (m_has_modinfo) {
3216 m_version = new_get_module_version(f, m_strversion);
3217 } else {
3218 m_version = old_get_module_version(f, m_strversion);
3219 if (m_version == -1) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003220 error_msg("couldn't find the kernel version the module was "
Matt Kraaidd19c692001-01-31 19:00:21 +00003221 "compiled for");
Eric Andersen9f16d612000-06-12 23:11:16 +00003222 goto out;
3223 }
3224 }
3225
3226 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3227 if (flag_force_load) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003228 error_msg("Warning: kernel-module version mismatch\n"
Eric Andersen9f16d612000-06-12 23:11:16 +00003229 "\t%s was compiled for kernel version %s\n"
Matt Kraaidd19c692001-01-31 19:00:21 +00003230 "\twhile this kernel is version %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00003231 m_filename, m_strversion, k_strversion);
3232 } else {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003233 error_msg("kernel-module version mismatch\n"
Eric Andersen9f16d612000-06-12 23:11:16 +00003234 "\t%s was compiled for kernel version %s\n"
Matt Kraaidd19c692001-01-31 19:00:21 +00003235 "\twhile this kernel is version %s.",
Eric Andersen9f16d612000-06-12 23:11:16 +00003236 m_filename, m_strversion, k_strversion);
3237 goto out;
3238 }
3239 }
3240 k_crcs = 0;
3241#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3242
3243 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3244
3245 if (k_new_syscalls) {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003246#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00003247 if (!new_get_kernel_symbols())
3248 goto out;
3249 k_crcs = new_is_kernel_checksummed();
3250#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003251 error_msg("Not configured to support new kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003252 goto out;
3253#endif
3254 } else {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003255#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen8c185f92000-09-22 00:38:07 +00003256 if (!old_get_kernel_symbols(m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00003257 goto out;
3258 k_crcs = old_is_kernel_checksummed();
3259#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003260 error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003261 goto out;
3262#endif
3263 }
3264
3265#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3266 if (m_has_modinfo)
3267 m_crcs = new_is_module_checksummed(f);
3268 else
3269 m_crcs = old_is_module_checksummed(f);
3270
3271 if (m_crcs != k_crcs)
3272 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3273#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3274
Erik Andersene49d5ec2000-02-08 19:58:47 +00003275 /* Let the module know about the kernel symbols. */
3276 add_kernel_symbols(f);
3277
Eric Andersen9f16d612000-06-12 23:11:16 +00003278 /* Allocate common symbols, symbol tables, and string tables. */
3279
3280 if (k_new_syscalls
3281 ? !new_create_this_module(f, m_name)
3282 : !old_create_mod_use_count(f))
3283 {
3284 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003285 }
3286
Eric Andersen9f16d612000-06-12 23:11:16 +00003287 if (!obj_check_undefineds(f)) {
3288 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003289 }
3290 obj_allocate_commons(f);
3291
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003292 /* done with the module name, on to the optional var=value arguments */
3293 ++optind;
3294
Eric Andersen9f16d612000-06-12 23:11:16 +00003295 if (optind < argc) {
3296 if (m_has_modinfo
3297 ? !new_process_module_arguments(f, argc - optind, argv + optind)
3298 : !old_process_module_arguments(f, argc - optind, argv + optind))
3299 {
3300 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003301 }
3302 }
3303
Eric Andersen9f16d612000-06-12 23:11:16 +00003304 arch_create_got(f);
3305 hide_special_symbols(f);
3306
3307 if (k_new_syscalls)
3308 new_create_module_ksymtab(f);
3309
Erik Andersene49d5ec2000-02-08 19:58:47 +00003310 /* Find current size of the module */
3311 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00003312
3313
Erik Andersene49d5ec2000-02-08 19:58:47 +00003314 m_addr = create_module(m_name, m_size);
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003315 if (m_addr==-1) switch (errno) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003316 case EEXIST:
Matt Kraaidd19c692001-01-31 19:00:21 +00003317 error_msg("A module named %s already exists", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003318 goto out;
3319 case ENOMEM:
Matt Kraaidd19c692001-01-31 19:00:21 +00003320 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
Eric Andersen9f16d612000-06-12 23:11:16 +00003321 m_size);
3322 goto out;
Erik Andersend387d011999-12-21 02:55:11 +00003323 default:
Matt Kraai1fa1ade2000-12-18 03:57:16 +00003324 perror_msg("create_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003325 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003326 }
Erik Andersend387d011999-12-21 02:55:11 +00003327
Eric Andersen9f16d612000-06-12 23:11:16 +00003328 if (!obj_relocate(f, m_addr)) {
3329 delete_module(m_name);
3330 goto out;
3331 }
Erik Andersend387d011999-12-21 02:55:11 +00003332
Eric Andersen9f16d612000-06-12 23:11:16 +00003333 if (k_new_syscalls
3334 ? !new_init_module(m_name, f, m_size)
3335 : !old_init_module(m_name, f, m_size))
3336 {
3337 delete_module(m_name);
3338 goto out;
3339 }
3340
Matt Kraai3e856ce2000-12-01 02:55:13 +00003341 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00003342
3343out:
Erik Andersene49d5ec2000-02-08 19:58:47 +00003344 fclose(fp);
Eric Andersenbb245ba2000-06-19 19:53:30 +00003345 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00003346}