blob: 27f4a50e2045123f0aa1ce7da403bea9385a8c42 [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 Andersen7f3b86e2001-04-26 19:29:58 +0000127#ident "$Id: insmod.c,v 1.60 2001/04/26 19:29:58 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 Andersen7f3b86e2001-04-26 19:29:58 +0000333#ident "$Id: insmod.c,v 1.60 2001/04/26 19:29:58 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;
Eric Andersen7f3b86e2001-04-26 19:29:58 +00001539 if (more) {
1540 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1541 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001542 return sec->contents + oldsize;
1543}
1544
1545
1546
1547/* Conditionally add the symbols from the given symbol set to the
1548 new module. */
1549
1550static int
1551add_symbols_from(
1552 struct obj_file *f,
1553 int idx, struct new_module_symbol *syms, size_t nsyms)
1554{
1555 struct new_module_symbol *s;
1556 size_t i;
1557 int used = 0;
1558
1559 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1560
1561 /* Only add symbols that are already marked external. If we
1562 override locals we may cause problems for argument initialization.
1563 We will also create a false dependency on the module. */
1564 struct obj_symbol *sym;
1565
1566 sym = obj_find_symbol(f, (char *) s->name);
1567 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1568 sym = obj_add_symbol(f, (char *) s->name, -1,
1569 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1570 idx, s->value, 0);
1571 /* Did our symbol just get installed? If so, mark the
1572 module as "used". */
1573 if (sym->secidx == idx)
1574 used = 1;
1575 }
1576 }
1577
1578 return used;
1579}
1580
1581static void add_kernel_symbols(struct obj_file *f)
1582{
1583 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00001584 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00001585
1586 /* Add module symbols first. */
1587
1588 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1589 if (m->nsyms
1590 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1591 m->nsyms)) m->used = 1, ++nused;
1592
1593 n_ext_modules_used = nused;
1594
1595 /* And finally the symbols from the kernel proper. */
1596
1597 if (nksyms)
1598 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1599}
1600
1601static char *get_modinfo_value(struct obj_file *f, const char *key)
1602{
1603 struct obj_section *sec;
1604 char *p, *v, *n, *ep;
1605 size_t klen = strlen(key);
1606
1607 sec = obj_find_section(f, ".modinfo");
1608 if (sec == NULL)
1609 return NULL;
1610 p = sec->contents;
1611 ep = p + sec->header.sh_size;
1612 while (p < ep) {
1613 v = strchr(p, '=');
1614 n = strchr(p, '\0');
1615 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001616 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001617 return v + 1;
1618 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001619 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001620 return n;
1621 }
1622 p = n + 1;
1623 }
1624
1625 return NULL;
1626}
1627
1628
1629/*======================================================================*/
1630/* Functions relating to module loading in pre 2.1 kernels. */
1631
1632static int
1633old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1634{
1635 while (argc > 0) {
1636 char *p, *q;
1637 struct obj_symbol *sym;
1638 int *loc;
1639
1640 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00001641 if ((q = strchr(p, '=')) == NULL) {
1642 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00001643 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00001644 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001645 *q++ = '\0';
1646
1647 sym = obj_find_symbol(f, p);
1648
1649 /* Also check that the parameter was not resolved from the kernel. */
1650 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00001651 error_msg("symbol for parameter %s not found", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001652 return 0;
1653 }
1654
1655 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1656
1657 /* Do C quoting if we begin with a ". */
1658 if (*q == '"') {
1659 char *r, *str;
1660
1661 str = alloca(strlen(q));
1662 for (r = str, q++; *q != '"'; ++q, ++r) {
1663 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00001664 error_msg("improperly terminated string argument for %s", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001665 return 0;
1666 } else if (*q == '\\')
1667 switch (*++q) {
1668 case 'a':
1669 *r = '\a';
1670 break;
1671 case 'b':
1672 *r = '\b';
1673 break;
1674 case 'e':
1675 *r = '\033';
1676 break;
1677 case 'f':
1678 *r = '\f';
1679 break;
1680 case 'n':
1681 *r = '\n';
1682 break;
1683 case 'r':
1684 *r = '\r';
1685 break;
1686 case 't':
1687 *r = '\t';
1688 break;
1689
1690 case '0':
1691 case '1':
1692 case '2':
1693 case '3':
1694 case '4':
1695 case '5':
1696 case '6':
1697 case '7':
1698 {
1699 int c = *q - '0';
1700 if (q[1] >= '0' && q[1] <= '7') {
1701 c = (c * 8) + *++q - '0';
1702 if (q[1] >= '0' && q[1] <= '7')
1703 c = (c * 8) + *++q - '0';
1704 }
1705 *r = c;
1706 }
1707 break;
1708
1709 default:
1710 *r = *q;
1711 break;
1712 } else
1713 *r = *q;
1714 }
1715 *r = '\0';
1716 obj_string_patch(f, sym->secidx, sym->value, str);
1717 } else if (*q >= '0' && *q <= '9') {
1718 do
1719 *loc++ = strtoul(q, &q, 0);
1720 while (*q++ == ',');
1721 } else {
1722 char *contents = f->sections[sym->secidx]->contents;
Eric Andersene76c3b02001-04-05 03:14:39 +00001723 char *myloc = contents + sym->value;
Eric Andersen9f16d612000-06-12 23:11:16 +00001724 char *r; /* To search for commas */
1725
1726 /* Break the string with comas */
1727 while ((r = strchr(q, ',')) != (char *) NULL) {
1728 *r++ = '\0';
Eric Andersene76c3b02001-04-05 03:14:39 +00001729 obj_string_patch(f, sym->secidx, myloc - contents, q);
1730 myloc += sizeof(char *);
Eric Andersen9f16d612000-06-12 23:11:16 +00001731 q = r;
1732 }
1733
1734 /* last part */
Eric Andersene76c3b02001-04-05 03:14:39 +00001735 obj_string_patch(f, sym->secidx, myloc - contents, q);
Eric Andersen9f16d612000-06-12 23:11:16 +00001736 }
1737
1738 argc--, argv++;
1739 }
1740
1741 return 1;
1742}
1743
1744#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1745static int old_is_module_checksummed(struct obj_file *f)
1746{
1747 return obj_find_symbol(f, "Using_Versions") != NULL;
1748}
1749/* Get the module's kernel version in the canonical integer form. */
1750
1751static int
1752old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1753{
1754 struct obj_symbol *sym;
1755 char *p, *q;
1756 int a, b, c;
1757
1758 sym = obj_find_symbol(f, "kernel_version");
1759 if (sym == NULL)
1760 return -1;
1761
1762 p = f->sections[sym->secidx]->contents + sym->value;
1763 strncpy(str, p, STRVERSIONLEN);
1764
1765 a = strtoul(p, &p, 10);
1766 if (*p != '.')
1767 return -1;
1768 b = strtoul(p + 1, &p, 10);
1769 if (*p != '.')
1770 return -1;
1771 c = strtoul(p + 1, &q, 10);
1772 if (p + 1 == q)
1773 return -1;
1774
1775 return a << 16 | b << 8 | c;
1776}
1777
1778#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1779
Eric Andersenf5d5e772001-01-24 23:34:48 +00001780#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00001781
1782/* Fetch all the symbols and divvy them up as appropriate for the modules. */
1783
Eric Andersen8c185f92000-09-22 00:38:07 +00001784static int old_get_kernel_symbols(const char *m_name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001785{
1786 struct old_kernel_sym *ks, *k;
1787 struct new_module_symbol *s;
1788 struct external_module *mod;
1789 int nks, nms, nmod, i;
1790
1791 nks = get_kernel_syms(NULL);
Eric Andersenf2278152001-04-24 21:41:41 +00001792 if (nks <= 0) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00001793 if (nks)
1794 perror_msg("get_kernel_syms: %s", m_name);
1795 else
1796 error_msg("No kernel symbols");
Eric Andersen9f16d612000-06-12 23:11:16 +00001797 return 0;
1798 }
1799
1800 ks = k = xmalloc(nks * sizeof(*ks));
1801
1802 if (get_kernel_syms(ks) != nks) {
1803 perror("inconsistency with get_kernel_syms -- is someone else "
1804 "playing with modules?");
1805 free(ks);
1806 return 0;
1807 }
1808
1809 /* Collect the module information. */
1810
1811 mod = NULL;
1812 nmod = -1;
1813
1814 while (k->name[0] == '#' && k->name[1]) {
1815 struct old_kernel_sym *k2;
Eric Andersen9f16d612000-06-12 23:11:16 +00001816
1817 /* Find out how many symbols this module has. */
1818 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1819 continue;
1820 nms = k2 - k - 1;
1821
1822 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1823 mod[nmod].name = k->name + 1;
1824 mod[nmod].addr = k->value;
1825 mod[nmod].used = 0;
1826 mod[nmod].nsyms = nms;
1827 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1828
1829 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1830 s->name = (unsigned long) k->name;
1831 s->value = k->value;
1832 }
1833
1834 k = k2;
1835 }
1836
1837 ext_modules = mod;
1838 n_ext_modules = nmod + 1;
1839
1840 /* Now collect the symbols for the kernel proper. */
1841
1842 if (k->name[0] == '#')
1843 ++k;
1844
1845 nksyms = nms = nks - (k - ks);
1846 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1847
1848 for (i = 0; i < nms; ++i, ++s, ++k) {
1849 s->name = (unsigned long) k->name;
1850 s->value = k->value;
1851 }
1852
1853 return 1;
1854}
1855
1856/* Return the kernel symbol checksum version, or zero if not used. */
1857
1858static int old_is_kernel_checksummed(void)
1859{
1860 /* Using_Versions is the first symbol. */
1861 if (nksyms > 0
1862 && strcmp((char *) ksyms[0].name,
1863 "Using_Versions") == 0) return ksyms[0].value;
1864 else
1865 return 0;
1866}
1867
1868
1869static int old_create_mod_use_count(struct obj_file *f)
1870{
1871 struct obj_section *sec;
1872
1873 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1874 sizeof(long));
1875
1876 obj_add_symbol(f, "mod_use_count_", -1,
1877 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1878 sizeof(long));
1879
1880 return 1;
1881}
1882
1883static int
1884old_init_module(const char *m_name, struct obj_file *f,
1885 unsigned long m_size)
1886{
1887 char *image;
1888 struct old_mod_routines routines;
1889 struct old_symbol_table *symtab;
1890 int ret;
1891
1892 /* Create the symbol table */
1893 {
1894 int nsyms = 0, strsize = 0, total;
1895
1896 /* Size things first... */
1897 if (flag_export) {
1898 int i;
1899 for (i = 0; i < HASH_BUCKETS; ++i) {
1900 struct obj_symbol *sym;
1901 for (sym = f->symtab[i]; sym; sym = sym->next)
1902 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1903 && sym->secidx <= SHN_HIRESERVE)
1904 {
1905 sym->ksymidx = nsyms++;
1906 strsize += strlen(sym->name) + 1;
1907 }
1908 }
1909 }
1910
1911 total = (sizeof(struct old_symbol_table)
1912 + nsyms * sizeof(struct old_module_symbol)
1913 + n_ext_modules_used * sizeof(struct old_module_ref)
1914 + strsize);
1915 symtab = xmalloc(total);
1916 symtab->size = total;
1917 symtab->n_symbols = nsyms;
1918 symtab->n_refs = n_ext_modules_used;
1919
1920 if (flag_export && nsyms) {
1921 struct old_module_symbol *ksym;
1922 char *str;
1923 int i;
1924
1925 ksym = symtab->symbol;
1926 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1927 + n_ext_modules_used * sizeof(struct old_module_ref));
1928
1929 for (i = 0; i < HASH_BUCKETS; ++i) {
1930 struct obj_symbol *sym;
1931 for (sym = f->symtab[i]; sym; sym = sym->next)
1932 if (sym->ksymidx >= 0) {
1933 ksym->addr = obj_symbol_final_value(f, sym);
1934 ksym->name =
1935 (unsigned long) str - (unsigned long) symtab;
1936
Matt Kraai70a78552001-01-04 02:00:17 +00001937 strcpy(str, sym->name);
1938 str += strlen(sym->name) + 1;
Eric Andersen9f16d612000-06-12 23:11:16 +00001939 ksym++;
1940 }
1941 }
1942 }
1943
1944 if (n_ext_modules_used) {
1945 struct old_module_ref *ref;
1946 int i;
1947
1948 ref = (struct old_module_ref *)
1949 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1950
1951 for (i = 0; i < n_ext_modules; ++i)
1952 if (ext_modules[i].used)
1953 ref++->module = ext_modules[i].addr;
1954 }
1955 }
1956
1957 /* Fill in routines. */
1958
1959 routines.init =
1960 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1961 routines.cleanup =
1962 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1963
1964 /* Whew! All of the initialization is complete. Collect the final
1965 module image and give it to the kernel. */
1966
1967 image = xmalloc(m_size);
1968 obj_create_image(f, image);
1969
1970 /* image holds the complete relocated module, accounting correctly for
1971 mod_use_count. However the old module kernel support assume that
1972 it is receiving something which does not contain mod_use_count. */
1973 ret = old_sys_init_module(m_name, image + sizeof(long),
1974 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1975 : 0), &routines, symtab);
1976 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00001977 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001978
1979 free(image);
1980 free(symtab);
1981
1982 return ret == 0;
1983}
1984
1985#else
1986
1987#define old_create_mod_use_count(x) TRUE
1988#define old_init_module(x, y, z) TRUE
1989
Eric Andersenf5d5e772001-01-24 23:34:48 +00001990#endif /* BB_FEATURE_OLD_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00001991
1992
1993
1994/*======================================================================*/
1995/* Functions relating to module loading after 2.1.18. */
1996
1997static int
1998new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1999{
2000 while (argc > 0) {
2001 char *p, *q, *key;
2002 struct obj_symbol *sym;
2003 char *contents, *loc;
2004 int min, max, n;
2005
2006 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00002007 if ((q = strchr(p, '=')) == NULL) {
2008 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00002009 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00002010 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002011
2012 key = alloca(q - p + 6);
2013 memcpy(key, "parm_", 5);
2014 memcpy(key + 5, p, q - p);
2015 key[q - p + 5] = 0;
2016
2017 p = get_modinfo_value(f, key);
2018 key += 5;
2019 if (p == NULL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002020 error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002021 return 0;
2022 }
2023
2024 sym = obj_find_symbol(f, key);
2025
2026 /* Also check that the parameter was not resolved from the kernel. */
2027 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002028 error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002029 return 0;
2030 }
2031
2032 if (isdigit(*p)) {
2033 min = strtoul(p, &p, 10);
2034 if (*p == '-')
2035 max = strtoul(p + 1, &p, 10);
2036 else
2037 max = min;
2038 } else
2039 min = max = 1;
2040
2041 contents = f->sections[sym->secidx]->contents;
2042 loc = contents + sym->value;
2043 n = (*++q != '\0');
2044
2045 while (1) {
2046 if ((*p == 's') || (*p == 'c')) {
2047 char *str;
2048
2049 /* Do C quoting if we begin with a ", else slurp the lot. */
2050 if (*q == '"') {
2051 char *r;
2052
2053 str = alloca(strlen(q));
2054 for (r = str, q++; *q != '"'; ++q, ++r) {
2055 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00002056 error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002057 key);
2058 return 0;
2059 } else if (*q == '\\')
2060 switch (*++q) {
2061 case 'a':
2062 *r = '\a';
2063 break;
2064 case 'b':
2065 *r = '\b';
2066 break;
2067 case 'e':
2068 *r = '\033';
2069 break;
2070 case 'f':
2071 *r = '\f';
2072 break;
2073 case 'n':
2074 *r = '\n';
2075 break;
2076 case 'r':
2077 *r = '\r';
2078 break;
2079 case 't':
2080 *r = '\t';
2081 break;
2082
2083 case '0':
2084 case '1':
2085 case '2':
2086 case '3':
2087 case '4':
2088 case '5':
2089 case '6':
2090 case '7':
2091 {
2092 int c = *q - '0';
2093 if (q[1] >= '0' && q[1] <= '7') {
2094 c = (c * 8) + *++q - '0';
2095 if (q[1] >= '0' && q[1] <= '7')
2096 c = (c * 8) + *++q - '0';
2097 }
2098 *r = c;
2099 }
2100 break;
2101
2102 default:
2103 *r = *q;
2104 break;
2105 } else
2106 *r = *q;
2107 }
2108 *r = '\0';
2109 ++q;
2110 } else {
2111 char *r;
2112
2113 /* In this case, the string is not quoted. We will break
2114 it using the coma (like for ints). If the user wants to
2115 include comas in a string, he just has to quote it */
2116
2117 /* Search the next coma */
2118 r = strchr(q, ',');
2119
2120 /* Found ? */
2121 if (r != (char *) NULL) {
2122 /* Recopy the current field */
2123 str = alloca(r - q + 1);
2124 memcpy(str, q, r - q);
2125
2126 /* I don't know if it is usefull, as the previous case
2127 doesn't null terminate the string ??? */
2128 str[r - q] = '\0';
2129
2130 /* Keep next fields */
2131 q = r;
2132 } else {
2133 /* last string */
2134 str = q;
2135 q = "";
2136 }
2137 }
2138
2139 if (*p == 's') {
2140 /* Normal string */
2141 obj_string_patch(f, sym->secidx, loc - contents, str);
2142 loc += tgt_sizeof_char_p;
2143 } else {
2144 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002145 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002146
2147 /* Get the size of each member */
2148 /* Probably we should do that outside the loop ? */
2149 if (!isdigit(*(p + 1))) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00002150 error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002151 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002152 return 0;
2153 }
2154 charssize = strtoul(p + 1, (char **) NULL, 10);
2155
2156 /* Check length */
2157 if (strlen(str) >= charssize) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002158 error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002159 charssize - 1);
2160 return 0;
2161 }
2162
2163 /* Copy to location */
2164 strcpy((char *) loc, str);
2165 loc += charssize;
2166 }
2167 } else {
2168 long v = strtoul(q, &q, 0);
2169 switch (*p) {
2170 case 'b':
2171 *loc++ = v;
2172 break;
2173 case 'h':
2174 *(short *) loc = v;
2175 loc += tgt_sizeof_short;
2176 break;
2177 case 'i':
2178 *(int *) loc = v;
2179 loc += tgt_sizeof_int;
2180 break;
2181 case 'l':
2182 *(long *) loc = v;
2183 loc += tgt_sizeof_long;
2184 break;
2185
2186 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002187 error_msg("unknown parameter type '%c' for %s", *p, key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002188 return 0;
2189 }
2190 }
2191
2192 retry_end_of_value:
2193 switch (*q) {
2194 case '\0':
2195 goto end_of_arg;
2196
2197 case ' ':
2198 case '\t':
2199 case '\n':
2200 case '\r':
2201 ++q;
2202 goto retry_end_of_value;
2203
2204 case ',':
2205 if (++n > max) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002206 error_msg("too many values for %s (max %d)", key, max);
Eric Andersen9f16d612000-06-12 23:11:16 +00002207 return 0;
2208 }
2209 ++q;
2210 break;
2211
2212 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002213 error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002214 return 0;
2215 }
2216 }
2217
2218 end_of_arg:
2219 if (n < min) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002220 error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002221 return 0;
2222 }
2223
2224 argc--, argv++;
2225 }
2226
2227 return 1;
2228}
2229
2230#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2231static int new_is_module_checksummed(struct obj_file *f)
2232{
2233 const char *p = get_modinfo_value(f, "using_checksums");
2234 if (p)
2235 return atoi(p);
2236 else
2237 return 0;
2238}
2239
2240/* Get the module's kernel version in the canonical integer form. */
2241
2242static int
2243new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2244{
2245 char *p, *q;
2246 int a, b, c;
2247
2248 p = get_modinfo_value(f, "kernel_version");
2249 if (p == NULL)
2250 return -1;
2251 strncpy(str, p, STRVERSIONLEN);
2252
2253 a = strtoul(p, &p, 10);
2254 if (*p != '.')
2255 return -1;
2256 b = strtoul(p + 1, &p, 10);
2257 if (*p != '.')
2258 return -1;
2259 c = strtoul(p + 1, &q, 10);
2260 if (p + 1 == q)
2261 return -1;
2262
2263 return a << 16 | b << 8 | c;
2264}
2265
2266#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2267
2268
Eric Andersenf5d5e772001-01-24 23:34:48 +00002269#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00002270
2271/* Fetch the loaded modules, and all currently exported symbols. */
2272
2273static int new_get_kernel_symbols(void)
2274{
2275 char *module_names, *mn;
2276 struct external_module *modules, *m;
2277 struct new_module_symbol *syms, *s;
2278 size_t ret, bufsize, nmod, nsyms, i, j;
2279
2280 /* Collect the loaded modules. */
2281
2282 module_names = xmalloc(bufsize = 256);
2283 retry_modules_load:
2284 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002285 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002286 module_names = xrealloc(module_names, bufsize = ret);
2287 goto retry_modules_load;
2288 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002289 perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002290 return 0;
2291 }
2292
2293 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002294
2295 /* Collect the modules' symbols. */
2296
Mark Whitley94fd4802001-03-12 23:08:34 +00002297 if (nmod){
2298 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2299 memset(modules, 0, nmod * sizeof(*modules));
2300 for (i = 0, mn = module_names, m = modules;
2301 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2302 struct new_module_info info;
2303
2304 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2305 if (errno == ENOENT) {
2306 /* The module was removed out from underneath us. */
2307 continue;
2308 }
2309 perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002310 return 0;
2311 }
Mark Whitley94fd4802001-03-12 23:08:34 +00002312
2313 syms = xmalloc(bufsize = 1024);
2314 retry_mod_sym_load:
2315 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2316 switch (errno) {
2317 case ENOSPC:
2318 syms = xrealloc(syms, bufsize = ret);
2319 goto retry_mod_sym_load;
2320 case ENOENT:
2321 /* The module was removed out from underneath us. */
2322 continue;
2323 default:
2324 perror_msg("query_module: QM_SYMBOLS: %s", mn);
2325 return 0;
2326 }
2327 }
2328 nsyms = ret;
2329
2330 m->name = mn;
2331 m->addr = info.addr;
2332 m->nsyms = nsyms;
2333 m->syms = syms;
2334
2335 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2336 s->name += (unsigned long) syms;
2337 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002338 }
2339 }
2340
2341 /* Collect the kernel's symbols. */
2342
2343 syms = xmalloc(bufsize = 16 * 1024);
2344 retry_kern_sym_load:
2345 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002346 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002347 syms = xrealloc(syms, bufsize = ret);
2348 goto retry_kern_sym_load;
2349 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002350 perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002351 return 0;
2352 }
2353 nksyms = nsyms = ret;
2354 ksyms = syms;
2355
2356 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2357 s->name += (unsigned long) syms;
2358 }
2359 return 1;
2360}
2361
2362
2363/* Return the kernel symbol checksum version, or zero if not used. */
2364
2365static int new_is_kernel_checksummed(void)
2366{
2367 struct new_module_symbol *s;
2368 size_t i;
2369
2370 /* Using_Versions is not the first symbol, but it should be in there. */
2371
2372 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2373 if (strcmp((char *) s->name, "Using_Versions") == 0)
2374 return s->value;
2375
2376 return 0;
2377}
2378
2379
2380static int new_create_this_module(struct obj_file *f, const char *m_name)
2381{
2382 struct obj_section *sec;
2383
2384 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2385 sizeof(struct new_module));
2386 memset(sec->contents, 0, sizeof(struct new_module));
2387
2388 obj_add_symbol(f, "__this_module", -1,
2389 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2390 sizeof(struct new_module));
2391
2392 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2393 m_name);
2394
2395 return 1;
2396}
2397
2398
2399static int new_create_module_ksymtab(struct obj_file *f)
2400{
2401 struct obj_section *sec;
2402 int i;
2403
2404 /* We must always add the module references. */
2405
2406 if (n_ext_modules_used) {
2407 struct new_module_ref *dep;
2408 struct obj_symbol *tm;
2409
2410 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2411 (sizeof(struct new_module_ref)
2412 * n_ext_modules_used));
2413 if (!sec)
2414 return 0;
2415
2416 tm = obj_find_symbol(f, "__this_module");
2417 dep = (struct new_module_ref *) sec->contents;
2418 for (i = 0; i < n_ext_modules; ++i)
2419 if (ext_modules[i].used) {
2420 dep->dep = ext_modules[i].addr;
2421 obj_symbol_patch(f, sec->idx,
2422 (char *) &dep->ref - sec->contents, tm);
2423 dep->next_ref = 0;
2424 ++dep;
2425 }
2426 }
2427
2428 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2429 size_t nsyms;
2430 int *loaded;
2431
2432 sec =
2433 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2434 0);
2435
2436 /* We don't want to export symbols residing in sections that
2437 aren't loaded. There are a number of these created so that
2438 we make sure certain module options don't appear twice. */
2439
2440 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2441 while (--i >= 0)
2442 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2443
2444 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2445 struct obj_symbol *sym;
2446 for (sym = f->symtab[i]; sym; sym = sym->next)
2447 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2448 && sym->secidx <= SHN_HIRESERVE
2449 && (sym->secidx >= SHN_LORESERVE
2450 || loaded[sym->secidx])) {
2451 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2452
2453 obj_symbol_patch(f, sec->idx, ofs, sym);
2454 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2455 sym->name);
2456
2457 nsyms++;
2458 }
2459 }
2460
2461 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2462 }
2463
2464 return 1;
2465}
2466
2467
2468static int
2469new_init_module(const char *m_name, struct obj_file *f,
2470 unsigned long m_size)
2471{
2472 struct new_module *module;
2473 struct obj_section *sec;
2474 void *image;
2475 int ret;
2476 tgt_long m_addr;
2477
2478 sec = obj_find_section(f, ".this");
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002479 if (!sec || !sec->contents) {
2480 perror_msg_and_die("corrupt module %s?",m_name);
2481 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002482 module = (struct new_module *) sec->contents;
2483 m_addr = sec->header.sh_addr;
2484
2485 module->size_of_struct = sizeof(*module);
2486 module->size = m_size;
2487 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2488
2489 sec = obj_find_section(f, "__ksymtab");
2490 if (sec && sec->header.sh_size) {
2491 module->syms = sec->header.sh_addr;
2492 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2493 }
2494
2495 if (n_ext_modules_used) {
2496 sec = obj_find_section(f, ".kmodtab");
2497 module->deps = sec->header.sh_addr;
2498 module->ndeps = n_ext_modules_used;
2499 }
2500
2501 module->init =
2502 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2503 module->cleanup =
2504 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2505
2506 sec = obj_find_section(f, "__ex_table");
2507 if (sec) {
2508 module->ex_table_start = sec->header.sh_addr;
2509 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2510 }
2511
2512 sec = obj_find_section(f, ".text.init");
2513 if (sec) {
2514 module->runsize = sec->header.sh_addr - m_addr;
2515 }
2516 sec = obj_find_section(f, ".data.init");
2517 if (sec) {
2518 if (!module->runsize ||
2519 module->runsize > sec->header.sh_addr - m_addr)
2520 module->runsize = sec->header.sh_addr - m_addr;
2521 }
2522
2523 if (!arch_init_module(f, module))
2524 return 0;
2525
2526 /* Whew! All of the initialization is complete. Collect the final
2527 module image and give it to the kernel. */
2528
2529 image = xmalloc(m_size);
2530 obj_create_image(f, image);
2531
Eric Andersen64c8b172001-04-05 07:33:10 +00002532 ret = new_sys_init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002533 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002534 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002535
2536 free(image);
2537
2538 return ret == 0;
2539}
2540
2541#else
2542
2543#define new_init_module(x, y, z) TRUE
2544#define new_create_this_module(x, y) 0
2545#define new_create_module_ksymtab(x)
Eric Andersen21adca72000-12-06 18:18:26 +00002546#define query_module(v, w, x, y, z) -1
Eric Andersen9f16d612000-06-12 23:11:16 +00002547
Eric Andersenf5d5e772001-01-24 23:34:48 +00002548#endif /* BB_FEATURE_NEW_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00002549
2550
2551/*======================================================================*/
2552
2553int
2554obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2555 const char *string)
2556{
2557 struct obj_string_patch *p;
2558 struct obj_section *strsec;
2559 size_t len = strlen(string) + 1;
2560 char *loc;
2561
2562 p = xmalloc(sizeof(*p));
2563 p->next = f->string_patches;
2564 p->reloc_secidx = secidx;
2565 p->reloc_offset = offset;
2566 f->string_patches = p;
2567
2568 strsec = obj_find_section(f, ".kstrtab");
2569 if (strsec == NULL) {
2570 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2571 p->string_offset = 0;
2572 loc = strsec->contents;
2573 } else {
2574 p->string_offset = strsec->header.sh_size;
2575 loc = obj_extend_section(strsec, len);
2576 }
2577 memcpy(loc, string, len);
2578
2579 return 1;
2580}
2581
2582int
2583obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2584 struct obj_symbol *sym)
2585{
2586 struct obj_symbol_patch *p;
2587
2588 p = xmalloc(sizeof(*p));
2589 p->next = f->symbol_patches;
2590 p->reloc_secidx = secidx;
2591 p->reloc_offset = offset;
2592 p->sym = sym;
2593 f->symbol_patches = p;
2594
2595 return 1;
2596}
2597
2598int obj_check_undefineds(struct obj_file *f)
2599{
2600 unsigned long i;
2601 int ret = 1;
2602
2603 for (i = 0; i < HASH_BUCKETS; ++i) {
2604 struct obj_symbol *sym;
2605 for (sym = f->symtab[i]; sym; sym = sym->next)
2606 if (sym->secidx == SHN_UNDEF) {
2607 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2608 sym->secidx = SHN_ABS;
2609 sym->value = 0;
2610 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002611 error_msg("unresolved symbol %s", sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002612 ret = 0;
2613 }
2614 }
2615 }
2616
2617 return ret;
2618}
2619
2620void obj_allocate_commons(struct obj_file *f)
2621{
2622 struct common_entry {
2623 struct common_entry *next;
2624 struct obj_symbol *sym;
2625 } *common_head = NULL;
2626
2627 unsigned long i;
2628
2629 for (i = 0; i < HASH_BUCKETS; ++i) {
2630 struct obj_symbol *sym;
2631 for (sym = f->symtab[i]; sym; sym = sym->next)
2632 if (sym->secidx == SHN_COMMON) {
2633 /* Collect all COMMON symbols and sort them by size so as to
2634 minimize space wasted by alignment requirements. */
2635 {
2636 struct common_entry **p, *n;
2637 for (p = &common_head; *p; p = &(*p)->next)
2638 if (sym->size <= (*p)->sym->size)
2639 break;
2640
2641 n = alloca(sizeof(*n));
2642 n->next = *p;
2643 n->sym = sym;
2644 *p = n;
2645 }
2646 }
2647 }
2648
2649 for (i = 1; i < f->local_symtab_size; ++i) {
2650 struct obj_symbol *sym = f->local_symtab[i];
2651 if (sym && sym->secidx == SHN_COMMON) {
2652 struct common_entry **p, *n;
2653 for (p = &common_head; *p; p = &(*p)->next)
2654 if (sym == (*p)->sym)
2655 break;
2656 else if (sym->size < (*p)->sym->size) {
2657 n = alloca(sizeof(*n));
2658 n->next = *p;
2659 n->sym = sym;
2660 *p = n;
2661 break;
2662 }
2663 }
2664 }
2665
2666 if (common_head) {
2667 /* Find the bss section. */
2668 for (i = 0; i < f->header.e_shnum; ++i)
2669 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2670 break;
2671
2672 /* If for some reason there hadn't been one, create one. */
2673 if (i == f->header.e_shnum) {
2674 struct obj_section *sec;
2675
2676 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2677 f->sections[i] = sec = arch_new_section();
2678 f->header.e_shnum = i + 1;
2679
2680 memset(sec, 0, sizeof(*sec));
2681 sec->header.sh_type = SHT_PROGBITS;
2682 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2683 sec->name = ".bss";
2684 sec->idx = i;
2685 }
2686
2687 /* Allocate the COMMONS. */
2688 {
2689 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2690 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2691 struct common_entry *c;
2692
2693 for (c = common_head; c; c = c->next) {
2694 ElfW(Addr) align = c->sym->value;
2695
2696 if (align > max_align)
2697 max_align = align;
2698 if (bss_size & (align - 1))
2699 bss_size = (bss_size | (align - 1)) + 1;
2700
2701 c->sym->secidx = i;
2702 c->sym->value = bss_size;
2703
2704 bss_size += c->sym->size;
2705 }
2706
2707 f->sections[i]->header.sh_size = bss_size;
2708 f->sections[i]->header.sh_addralign = max_align;
2709 }
2710 }
2711
2712 /* For the sake of patch relocation and parameter initialization,
2713 allocate zeroed data for NOBITS sections now. Note that after
2714 this we cannot assume NOBITS are really empty. */
2715 for (i = 0; i < f->header.e_shnum; ++i) {
2716 struct obj_section *s = f->sections[i];
2717 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00002718 if (s->header.sh_size != 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002719 s->contents = memset(xmalloc(s->header.sh_size),
2720 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00002721 else
2722 s->contents = NULL;
2723
Eric Andersen9f16d612000-06-12 23:11:16 +00002724 s->header.sh_type = SHT_PROGBITS;
2725 }
2726 }
2727}
2728
2729unsigned long obj_load_size(struct obj_file *f)
2730{
2731 unsigned long dot = 0;
2732 struct obj_section *sec;
2733
2734 /* Finalize the positions of the sections relative to one another. */
2735
2736 for (sec = f->load_order; sec; sec = sec->load_next) {
2737 ElfW(Addr) align;
2738
2739 align = sec->header.sh_addralign;
2740 if (align && (dot & (align - 1)))
2741 dot = (dot | (align - 1)) + 1;
2742
2743 sec->header.sh_addr = dot;
2744 dot += sec->header.sh_size;
2745 }
2746
2747 return dot;
2748}
2749
2750int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2751{
2752 int i, n = f->header.e_shnum;
2753 int ret = 1;
2754
2755 /* Finalize the addresses of the sections. */
2756
2757 f->baseaddr = base;
2758 for (i = 0; i < n; ++i)
2759 f->sections[i]->header.sh_addr += base;
2760
2761 /* And iterate over all of the relocations. */
2762
2763 for (i = 0; i < n; ++i) {
2764 struct obj_section *relsec, *symsec, *targsec, *strsec;
2765 ElfW(RelM) * rel, *relend;
2766 ElfW(Sym) * symtab;
2767 const char *strtab;
2768
2769 relsec = f->sections[i];
2770 if (relsec->header.sh_type != SHT_RELM)
2771 continue;
2772
2773 symsec = f->sections[relsec->header.sh_link];
2774 targsec = f->sections[relsec->header.sh_info];
2775 strsec = f->sections[symsec->header.sh_link];
2776
2777 rel = (ElfW(RelM) *) relsec->contents;
2778 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2779 symtab = (ElfW(Sym) *) symsec->contents;
2780 strtab = (const char *) strsec->contents;
2781
2782 for (; rel < relend; ++rel) {
2783 ElfW(Addr) value = 0;
2784 struct obj_symbol *intsym = NULL;
2785 unsigned long symndx;
2786 ElfW(Sym) * extsym = 0;
2787 const char *errmsg;
2788
2789 /* Attempt to find a value to use for this relocation. */
2790
2791 symndx = ELFW(R_SYM) (rel->r_info);
2792 if (symndx) {
2793 /* Note we've already checked for undefined symbols. */
2794
2795 extsym = &symtab[symndx];
2796 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2797 /* Local symbols we look up in the local table to be sure
2798 we get the one that is really intended. */
2799 intsym = f->local_symtab[symndx];
2800 } else {
2801 /* Others we look up in the hash table. */
2802 const char *name;
2803 if (extsym->st_name)
2804 name = strtab + extsym->st_name;
2805 else
2806 name = f->sections[extsym->st_shndx]->name;
2807 intsym = obj_find_symbol(f, name);
2808 }
2809
2810 value = obj_symbol_final_value(f, intsym);
2811 intsym->referenced = 1;
2812 }
2813#if SHT_RELM == SHT_RELA
2814#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2815 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2816 if (!extsym || !extsym->st_name ||
2817 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2818#endif
2819 value += rel->r_addend;
2820#endif
2821
2822 /* Do it! */
2823 switch (arch_apply_relocation
2824 (f, targsec, symsec, intsym, rel, value)) {
2825 case obj_reloc_ok:
2826 break;
2827
2828 case obj_reloc_overflow:
2829 errmsg = "Relocation overflow";
2830 goto bad_reloc;
2831 case obj_reloc_dangerous:
2832 errmsg = "Dangerous relocation";
2833 goto bad_reloc;
2834 case obj_reloc_unhandled:
2835 errmsg = "Unhandled relocation";
2836 bad_reloc:
2837 if (extsym) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002838 error_msg("%s of type %ld for %s", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002839 (long) ELFW(R_TYPE) (rel->r_info),
2840 strtab + extsym->st_name);
2841 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002842 error_msg("%s of type %ld", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002843 (long) ELFW(R_TYPE) (rel->r_info));
2844 }
2845 ret = 0;
2846 break;
2847 }
2848 }
2849 }
2850
2851 /* Finally, take care of the patches. */
2852
2853 if (f->string_patches) {
2854 struct obj_string_patch *p;
2855 struct obj_section *strsec;
2856 ElfW(Addr) strsec_base;
2857 strsec = obj_find_section(f, ".kstrtab");
2858 strsec_base = strsec->header.sh_addr;
2859
2860 for (p = f->string_patches; p; p = p->next) {
2861 struct obj_section *targsec = f->sections[p->reloc_secidx];
2862 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2863 = strsec_base + p->string_offset;
2864 }
2865 }
2866
2867 if (f->symbol_patches) {
2868 struct obj_symbol_patch *p;
2869
2870 for (p = f->symbol_patches; p; p = p->next) {
2871 struct obj_section *targsec = f->sections[p->reloc_secidx];
2872 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2873 = obj_symbol_final_value(f, p->sym);
2874 }
2875 }
2876
2877 return ret;
2878}
2879
2880int obj_create_image(struct obj_file *f, char *image)
2881{
2882 struct obj_section *sec;
2883 ElfW(Addr) base = f->baseaddr;
2884
2885 for (sec = f->load_order; sec; sec = sec->load_next) {
2886 char *secimg;
2887
Eric Andersen2bf658d2001-02-24 20:01:53 +00002888 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002889 continue;
2890
2891 secimg = image + (sec->header.sh_addr - base);
2892
2893 /* Note that we allocated data for NOBITS sections earlier. */
2894 memcpy(secimg, sec->contents, sec->header.sh_size);
2895 }
2896
2897 return 1;
2898}
2899
2900/*======================================================================*/
2901
2902struct obj_file *obj_load(FILE * fp)
2903{
2904 struct obj_file *f;
2905 ElfW(Shdr) * section_headers;
2906 int shnum, i;
2907 char *shstrtab;
2908
2909 /* Read the file header. */
2910
2911 f = arch_new_file();
2912 memset(f, 0, sizeof(*f));
2913 f->symbol_cmp = strcmp;
2914 f->symbol_hash = obj_elf_hash;
2915 f->load_order_search_start = &f->load_order;
2916
2917 fseek(fp, 0, SEEK_SET);
2918 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002919 perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00002920 return NULL;
2921 }
2922
2923 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2924 || f->header.e_ident[EI_MAG1] != ELFMAG1
2925 || f->header.e_ident[EI_MAG2] != ELFMAG2
2926 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002927 error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00002928 return NULL;
2929 }
2930 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2931 || f->header.e_ident[EI_DATA] != ELFDATAM
2932 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2933 || !MATCH_MACHINE(f->header.e_machine)) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002934 error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002935 return NULL;
2936 }
2937 if (f->header.e_type != ET_REL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002938 error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00002939 return NULL;
2940 }
2941
2942 /* Read the section headers. */
2943
2944 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002945 error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00002946 (unsigned long) f->header.e_shentsize,
2947 (unsigned long) sizeof(ElfW(Shdr)));
2948 return NULL;
2949 }
2950
2951 shnum = f->header.e_shnum;
2952 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2953 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2954
2955 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2956 fseek(fp, f->header.e_shoff, SEEK_SET);
2957 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002958 perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00002959 return NULL;
2960 }
2961
2962 /* Read the section data. */
2963
2964 for (i = 0; i < shnum; ++i) {
2965 struct obj_section *sec;
2966
2967 f->sections[i] = sec = arch_new_section();
2968 memset(sec, 0, sizeof(*sec));
2969
2970 sec->header = section_headers[i];
2971 sec->idx = i;
2972
Eric Andersen2bf658d2001-02-24 20:01:53 +00002973 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002974 case SHT_NULL:
2975 case SHT_NOTE:
2976 case SHT_NOBITS:
2977 /* ignore */
2978 break;
2979
2980 case SHT_PROGBITS:
2981 case SHT_SYMTAB:
2982 case SHT_STRTAB:
2983 case SHT_RELM:
2984 if (sec->header.sh_size > 0) {
2985 sec->contents = xmalloc(sec->header.sh_size);
2986 fseek(fp, sec->header.sh_offset, SEEK_SET);
2987 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002988 perror_msg("error reading ELF section data");
Eric Andersen9f16d612000-06-12 23:11:16 +00002989 return NULL;
2990 }
2991 } else {
2992 sec->contents = NULL;
2993 }
2994 break;
2995
2996#if SHT_RELM == SHT_REL
2997 case SHT_RELA:
Matt Kraaidd19c692001-01-31 19:00:21 +00002998 error_msg("RELA relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002999 return NULL;
3000#else
3001 case SHT_REL:
Matt Kraaidd19c692001-01-31 19:00:21 +00003002 error_msg("REL relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00003003 return NULL;
3004#endif
3005
3006 default:
3007 if (sec->header.sh_type >= SHT_LOPROC) {
3008 /* Assume processor specific section types are debug
3009 info and can safely be ignored. If this is ever not
3010 the case (Hello MIPS?), don't put ifdefs here but
3011 create an arch_load_proc_section(). */
3012 break;
3013 }
3014
Matt Kraaidd19c692001-01-31 19:00:21 +00003015 error_msg("can't handle sections of type %ld",
Eric Andersen9f16d612000-06-12 23:11:16 +00003016 (long) sec->header.sh_type);
3017 return NULL;
3018 }
3019 }
3020
3021 /* Do what sort of interpretation as needed by each section. */
3022
3023 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3024
3025 for (i = 0; i < shnum; ++i) {
3026 struct obj_section *sec = f->sections[i];
3027 sec->name = shstrtab + sec->header.sh_name;
3028 }
3029
3030 for (i = 0; i < shnum; ++i) {
3031 struct obj_section *sec = f->sections[i];
3032
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003033 /* .modinfo should be contents only but gcc has no attribute for that.
3034 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3035 */
3036 if (strcmp(sec->name, ".modinfo") == 0)
3037 sec->header.sh_flags &= ~SHF_ALLOC;
3038
Eric Andersen9f16d612000-06-12 23:11:16 +00003039 if (sec->header.sh_flags & SHF_ALLOC)
3040 obj_insert_section_load_order(f, sec);
3041
3042 switch (sec->header.sh_type) {
3043 case SHT_SYMTAB:
3044 {
3045 unsigned long nsym, j;
3046 char *strtab;
3047 ElfW(Sym) * sym;
3048
3049 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003050 error_msg("symbol size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003051 (unsigned long) sec->header.sh_entsize,
3052 (unsigned long) sizeof(ElfW(Sym)));
3053 return NULL;
3054 }
3055
3056 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3057 strtab = f->sections[sec->header.sh_link]->contents;
3058 sym = (ElfW(Sym) *) sec->contents;
3059
3060 /* Allocate space for a table of local symbols. */
3061 j = f->local_symtab_size = sec->header.sh_info;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003062 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003063
3064 /* Insert all symbols into the hash table. */
3065 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3066 const char *name;
3067 if (sym->st_name)
3068 name = strtab + sym->st_name;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003069 else
Eric Andersen9f16d612000-06-12 23:11:16 +00003070 name = f->sections[sym->st_shndx]->name;
3071
3072 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3073 sym->st_value, sym->st_size);
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003074 }
3075 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003076 break;
3077
3078 case SHT_RELM:
3079 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003080 error_msg("relocation entry size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003081 (unsigned long) sec->header.sh_entsize,
3082 (unsigned long) sizeof(ElfW(RelM)));
3083 return NULL;
3084 }
3085 break;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003086 /* XXX Relocation code from modutils-2.3.19 is not here.
3087 * Why? That's about 20 lines of code from obj/obj_load.c,
3088 * which gets done in a second pass through the sections.
3089 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003090 }
3091 }
3092
3093 return f;
3094}
3095
3096static void hide_special_symbols(struct obj_file *f)
3097{
3098 static const char *const specials[] = {
3099 "cleanup_module",
3100 "init_module",
3101 "kernel_version",
3102 NULL
3103 };
3104
3105 struct obj_symbol *sym;
3106 const char *const *p;
3107
3108 for (p = specials; *p; ++p)
3109 if ((sym = obj_find_symbol(f, *p)) != NULL)
3110 sym->info =
3111 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3112}
3113
3114
3115
3116extern int insmod_main( int argc, char **argv)
3117{
Eric Andersena18aaf12001-01-24 19:07:09 +00003118 int opt;
Eric Andersen9f16d612000-06-12 23:11:16 +00003119 int k_crcs;
3120 int k_new_syscalls;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003121 int len;
3122 char *tmp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003123 unsigned long m_size;
3124 ElfW(Addr) m_addr;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003125 FILE *fp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003126 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003127 struct stat st;
Eric Andersen9f16d612000-06-12 23:11:16 +00003128 char m_name[BUFSIZ + 1] = "\0";
Matt Kraai3e856ce2000-12-01 02:55:13 +00003129 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003130 int m_has_modinfo;
3131#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3132 int k_version;
3133 char k_strversion[STRVERSIONLEN];
3134 char m_strversion[STRVERSIONLEN];
3135 int m_version;
3136 int m_crcs;
3137#endif
3138
Erik Andersene49d5ec2000-02-08 19:58:47 +00003139 /* Parse any options */
Eric Andersen155c89b2001-01-25 04:11:06 +00003140 while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
Eric Andersena18aaf12001-01-24 19:07:09 +00003141 switch (opt) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003142 case 'f': /* force loading */
3143 flag_force_load = 1;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003144 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003145 case 'k': /* module loaded by kerneld, auto-cleanable */
3146 flag_autoclean = 1;
3147 break;
3148 case 'v': /* verbose output */
3149 flag_verbose = 1;
3150 break;
3151 case 'x': /* do not export externs */
3152 flag_export = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003153 break;
Eric Andersen155c89b2001-01-25 04:11:06 +00003154 case 'o': /* name the output module */
3155 strncpy(m_name, optarg, BUFSIZ);
3156 break;
Eric Andersena18aaf12001-01-24 19:07:09 +00003157 case 'L': /* Stub warning */
3158 /* This is needed for compatibility with modprobe.
3159 * In theory, this does locking, but we don't do
3160 * that. So be careful and plan your life around not
3161 * loading the same module 50 times concurrently. */
3162 break;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003163 default:
Eric Andersen67991cf2001-02-14 21:23:06 +00003164 show_usage();
Erik Andersene49d5ec2000-02-08 19:58:47 +00003165 }
Erik Andersend387d011999-12-21 02:55:11 +00003166 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003167
3168 if (argv[optind] == NULL) {
Eric Andersen67991cf2001-02-14 21:23:06 +00003169 show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003170 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003171
Erik Andersene49d5ec2000-02-08 19:58:47 +00003172 /* Grab the module name */
Eric Andersena18aaf12001-01-24 19:07:09 +00003173 if ((tmp = strrchr(argv[optind], '/')) != NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003174 tmp++;
Eric Andersen9f16d612000-06-12 23:11:16 +00003175 } else {
Eric Andersena18aaf12001-01-24 19:07:09 +00003176 tmp = argv[optind];
Eric Andersen9f16d612000-06-12 23:11:16 +00003177 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003178 len = strlen(tmp);
3179
3180 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3181 len -= 2;
Eric Andersenf2278152001-04-24 21:41:41 +00003182 memcpy(m_fullName, tmp, len);
3183 m_fullName[len]='\0';
Eric Andersen114ad9c2001-01-26 01:52:14 +00003184 if (*m_name == '\0') {
3185 strcpy(m_name, m_fullName);
Eric Andersen155c89b2001-01-25 04:11:06 +00003186 }
Eric Andersen114ad9c2001-01-26 01:52:14 +00003187 strcat(m_fullName, ".o");
Erik Andersene49d5ec2000-02-08 19:58:47 +00003188
3189 /* Get a filedesc for the module */
Eric Andersen02b9f422001-02-15 19:07:43 +00003190 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3191 (fp = fopen(argv[optind], "r")) == NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003192 /* Hmpf. Could not open it. Search through _PATH_MODULES to find a module named m_name */
Mark Whitleyf57c9442000-12-07 19:56:48 +00003193 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
Matt Kraai0f8f7b82000-08-01 18:16:56 +00003194 findNamedModule, 0, m_fullName) == FALSE)
Eric Andersen9f16d612000-06-12 23:11:16 +00003195 {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003196 if (m_filename[0] == '\0'
Eric Andersen9f16d612000-06-12 23:11:16 +00003197 || ((fp = fopen(m_filename, "r")) == NULL))
3198 {
Matt Kraaidd19c692001-01-31 19:00:21 +00003199 error_msg("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
Matt Kraai3e856ce2000-12-01 02:55:13 +00003200 return EXIT_FAILURE;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003201 }
Matt Kraai0f8f7b82000-08-01 18:16:56 +00003202 } else
Matt Kraaidd19c692001-01-31 19:00:21 +00003203 error_msg_and_die("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
Erik Andersene49d5ec2000-02-08 19:58:47 +00003204 } else
Eric Andersenf2278152001-04-24 21:41:41 +00003205 safe_strncpy(m_filename, argv[optind], sizeof(m_filename));
Erik Andersend387d011999-12-21 02:55:11 +00003206
3207
Matt Kraaia9819b22000-12-22 01:48:07 +00003208 if ((f = obj_load(fp)) == NULL)
3209 perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00003210
Eric Andersen9f16d612000-06-12 23:11:16 +00003211 if (get_modinfo_value(f, "kernel_version") == NULL)
3212 m_has_modinfo = 0;
3213 else
3214 m_has_modinfo = 1;
3215
3216#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3217 /* Version correspondence? */
3218
3219 k_version = get_kernel_version(k_strversion);
3220 if (m_has_modinfo) {
3221 m_version = new_get_module_version(f, m_strversion);
3222 } else {
3223 m_version = old_get_module_version(f, m_strversion);
3224 if (m_version == -1) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003225 error_msg("couldn't find the kernel version the module was "
Matt Kraaidd19c692001-01-31 19:00:21 +00003226 "compiled for");
Eric Andersen9f16d612000-06-12 23:11:16 +00003227 goto out;
3228 }
3229 }
3230
3231 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3232 if (flag_force_load) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003233 error_msg("Warning: 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 } else {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003238 error_msg("kernel-module version mismatch\n"
Eric Andersen9f16d612000-06-12 23:11:16 +00003239 "\t%s was compiled for kernel version %s\n"
Matt Kraaidd19c692001-01-31 19:00:21 +00003240 "\twhile this kernel is version %s.",
Eric Andersen9f16d612000-06-12 23:11:16 +00003241 m_filename, m_strversion, k_strversion);
3242 goto out;
3243 }
3244 }
3245 k_crcs = 0;
3246#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3247
3248 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3249
3250 if (k_new_syscalls) {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003251#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00003252 if (!new_get_kernel_symbols())
3253 goto out;
3254 k_crcs = new_is_kernel_checksummed();
3255#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003256 error_msg("Not configured to support new kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003257 goto out;
3258#endif
3259 } else {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003260#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen8c185f92000-09-22 00:38:07 +00003261 if (!old_get_kernel_symbols(m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00003262 goto out;
3263 k_crcs = old_is_kernel_checksummed();
3264#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003265 error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003266 goto out;
3267#endif
3268 }
3269
3270#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3271 if (m_has_modinfo)
3272 m_crcs = new_is_module_checksummed(f);
3273 else
3274 m_crcs = old_is_module_checksummed(f);
3275
3276 if (m_crcs != k_crcs)
3277 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3278#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3279
Erik Andersene49d5ec2000-02-08 19:58:47 +00003280 /* Let the module know about the kernel symbols. */
3281 add_kernel_symbols(f);
3282
Eric Andersen9f16d612000-06-12 23:11:16 +00003283 /* Allocate common symbols, symbol tables, and string tables. */
3284
3285 if (k_new_syscalls
3286 ? !new_create_this_module(f, m_name)
3287 : !old_create_mod_use_count(f))
3288 {
3289 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003290 }
3291
Eric Andersen9f16d612000-06-12 23:11:16 +00003292 if (!obj_check_undefineds(f)) {
3293 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003294 }
3295 obj_allocate_commons(f);
3296
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003297 /* done with the module name, on to the optional var=value arguments */
3298 ++optind;
3299
Eric Andersen9f16d612000-06-12 23:11:16 +00003300 if (optind < argc) {
3301 if (m_has_modinfo
3302 ? !new_process_module_arguments(f, argc - optind, argv + optind)
3303 : !old_process_module_arguments(f, argc - optind, argv + optind))
3304 {
3305 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003306 }
3307 }
3308
Eric Andersen9f16d612000-06-12 23:11:16 +00003309 arch_create_got(f);
3310 hide_special_symbols(f);
3311
3312 if (k_new_syscalls)
3313 new_create_module_ksymtab(f);
3314
Erik Andersene49d5ec2000-02-08 19:58:47 +00003315 /* Find current size of the module */
3316 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00003317
3318
Erik Andersene49d5ec2000-02-08 19:58:47 +00003319 m_addr = create_module(m_name, m_size);
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003320 if (m_addr==-1) switch (errno) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003321 case EEXIST:
Matt Kraaidd19c692001-01-31 19:00:21 +00003322 error_msg("A module named %s already exists", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003323 goto out;
3324 case ENOMEM:
Matt Kraaidd19c692001-01-31 19:00:21 +00003325 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
Eric Andersen9f16d612000-06-12 23:11:16 +00003326 m_size);
3327 goto out;
Erik Andersend387d011999-12-21 02:55:11 +00003328 default:
Matt Kraai1fa1ade2000-12-18 03:57:16 +00003329 perror_msg("create_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003330 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003331 }
Erik Andersend387d011999-12-21 02:55:11 +00003332
Eric Andersen9f16d612000-06-12 23:11:16 +00003333 if (!obj_relocate(f, m_addr)) {
3334 delete_module(m_name);
3335 goto out;
3336 }
Erik Andersend387d011999-12-21 02:55:11 +00003337
Eric Andersen9f16d612000-06-12 23:11:16 +00003338 if (k_new_syscalls
3339 ? !new_init_module(m_name, f, m_size)
3340 : !old_init_module(m_name, f, m_size))
3341 {
3342 delete_module(m_name);
3343 goto out;
3344 }
3345
Matt Kraai3e856ce2000-12-01 02:55:13 +00003346 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00003347
3348out:
Erik Andersene49d5ec2000-02-08 19:58:47 +00003349 fclose(fp);
Eric Andersenbb245ba2000-06-19 19:53:30 +00003350 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00003351}