blob: bc7f6589acfacdfb6d6dcc010221d763b4508ee0 [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 Andersen14d35432001-05-14 17:07:32 +0000127#ident "$Id: insmod.c,v 1.61 2001/05/14 17:07:32 andersen Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000128
129/* This file contains the structures used by the 2.0 and 2.1 kernels.
130 We do not use the kernel headers directly because we do not wish
131 to be dependant on a particular kernel version to compile insmod. */
132
133
134/*======================================================================*/
135/* The structures used by Linux 2.0. */
136
137/* The symbol format used by get_kernel_syms(2). */
138struct old_kernel_sym
139{
140 unsigned long value;
141 char name[60];
142};
143
144struct old_module_ref
145{
146 unsigned long module; /* kernel addresses */
147 unsigned long next;
148};
149
150struct old_module_symbol
151{
152 unsigned long addr;
153 unsigned long name;
154};
155
156struct old_symbol_table
157{
158 int size; /* total, including string table!!! */
159 int n_symbols;
160 int n_refs;
161 struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */
162 struct old_module_ref ref[0]; /* actual size defined by n_refs */
163};
164
165struct old_mod_routines
166{
167 unsigned long init;
168 unsigned long cleanup;
169};
170
171struct old_module
172{
173 unsigned long next;
174 unsigned long ref; /* the list of modules that refer to me */
175 unsigned long symtab;
176 unsigned long name;
177 int size; /* size of module in pages */
178 unsigned long addr; /* address of module */
179 int state;
180 unsigned long cleanup; /* cleanup routine */
181};
182
183/* Sent to init_module(2) or'ed into the code size parameter. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000184static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */
Eric Andersen9f16d612000-06-12 23:11:16 +0000185
186int get_kernel_syms(struct old_kernel_sym *);
187int old_sys_init_module(const char *name, char *code, unsigned codesize,
188 struct old_mod_routines *, struct old_symbol_table *);
189
190/*======================================================================*/
191/* For sizeof() which are related to the module platform and not to the
192 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */
193
194#define tgt_sizeof_char sizeof(char)
195#define tgt_sizeof_short sizeof(short)
196#define tgt_sizeof_int sizeof(int)
197#define tgt_sizeof_long sizeof(long)
198#define tgt_sizeof_char_p sizeof(char *)
199#define tgt_sizeof_void_p sizeof(void *)
200#define tgt_long long
201
202#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
203#undef tgt_sizeof_long
204#undef tgt_sizeof_char_p
205#undef tgt_sizeof_void_p
206#undef tgt_long
Mark Whitley59ab0252001-01-23 22:30:04 +0000207static const int tgt_sizeof_long = 8;
208static const int tgt_sizeof_char_p = 8;
209static const int tgt_sizeof_void_p = 8;
Eric Andersen9f16d612000-06-12 23:11:16 +0000210#define tgt_long long long
211#endif
212
213/*======================================================================*/
214/* The structures used in Linux 2.1. */
215
216/* Note: new_module_symbol does not use tgt_long intentionally */
217struct new_module_symbol
218{
219 unsigned long value;
220 unsigned long name;
221};
222
223struct new_module_persist;
224
225struct new_module_ref
226{
227 unsigned tgt_long dep; /* kernel addresses */
228 unsigned tgt_long ref;
229 unsigned tgt_long next_ref;
230};
231
232struct new_module
233{
234 unsigned tgt_long size_of_struct; /* == sizeof(module) */
235 unsigned tgt_long next;
236 unsigned tgt_long name;
237 unsigned tgt_long size;
238
239 tgt_long usecount;
240 unsigned tgt_long flags; /* AUTOCLEAN et al */
241
242 unsigned nsyms;
243 unsigned ndeps;
244
245 unsigned tgt_long syms;
246 unsigned tgt_long deps;
247 unsigned tgt_long refs;
248 unsigned tgt_long init;
249 unsigned tgt_long cleanup;
250 unsigned tgt_long ex_table_start;
251 unsigned tgt_long ex_table_end;
252#ifdef __alpha__
253 unsigned tgt_long gp;
254#endif
255 /* Everything after here is extension. */
256 unsigned tgt_long persist_start;
257 unsigned tgt_long persist_end;
258 unsigned tgt_long can_unload;
259 unsigned tgt_long runsize;
260};
261
262struct new_module_info
263{
264 unsigned long addr;
265 unsigned long size;
266 unsigned long flags;
267 long usecount;
268};
269
270/* Bits of module.flags. */
Mark Whitley59ab0252001-01-23 22:30:04 +0000271static const int NEW_MOD_RUNNING = 1;
272static const int NEW_MOD_DELETED = 2;
273static const int NEW_MOD_AUTOCLEAN = 4;
274static const int NEW_MOD_VISITED = 8;
275static const int NEW_MOD_USED_ONCE = 16;
Eric Andersen9f16d612000-06-12 23:11:16 +0000276
Eric Andersen64c8b172001-04-05 07:33:10 +0000277int new_sys_init_module(const char *name, const struct new_module *);
Eric Andersen9f16d612000-06-12 23:11:16 +0000278int query_module(const char *name, int which, void *buf, size_t bufsize,
279 size_t *ret);
280
281/* Values for query_module's which. */
282
Mark Whitley59ab0252001-01-23 22:30:04 +0000283static const int QM_MODULES = 1;
284static const int QM_DEPS = 2;
285static const int QM_REFS = 3;
286static const int QM_SYMBOLS = 4;
287static const int QM_INFO = 5;
Eric Andersen9f16d612000-06-12 23:11:16 +0000288
289/*======================================================================*/
290/* The system calls unchanged between 2.0 and 2.1. */
291
292unsigned long create_module(const char *, size_t);
293int delete_module(const char *);
294
295
296#endif /* module.h */
297
298//----------------------------------------------------------------------------
299//--------end of modutils module.h
300//----------------------------------------------------------------------------
301
302
303
304//----------------------------------------------------------------------------
305//--------modutils obj.h, lines 253-462
306//----------------------------------------------------------------------------
307
308/* Elf object file loading and relocation routines.
309 Copyright 1996, 1997 Linux International.
310
311 Contributed by Richard Henderson <rth@tamu.edu>
312
313 This file is part of the Linux modutils.
314
315 This program is free software; you can redistribute it and/or modify it
316 under the terms of the GNU General Public License as published by the
317 Free Software Foundation; either version 2 of the License, or (at your
318 option) any later version.
319
320 This program is distributed in the hope that it will be useful, but
321 WITHOUT ANY WARRANTY; without even the implied warranty of
322 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
323 General Public License for more details.
324
325 You should have received a copy of the GNU General Public License
326 along with this program; if not, write to the Free Software Foundation,
327 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
328
329
330#ifndef MODUTILS_OBJ_H
Mark Whitley59ab0252001-01-23 22:30:04 +0000331static const int MODUTILS_OBJ_H = 1;
Eric Andersen9f16d612000-06-12 23:11:16 +0000332
Eric Andersen14d35432001-05-14 17:07:32 +0000333#ident "$Id: insmod.c,v 1.61 2001/05/14 17:07:32 andersen Exp $"
Eric Andersen9f16d612000-06-12 23:11:16 +0000334
335/* The relocatable object is manipulated using elfin types. */
336
337#include <stdio.h>
338#include <elf.h>
339
340
341/* Machine-specific elf macros for i386 et al. */
342
Eric Andersenfe4208f2000-09-24 03:44:29 +0000343/* the SH changes have only been tested on the SH4 in =little endian= mode */
344/* I'm not sure about big endian, so let's warn: */
345
346#if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
347#error insmod.c may require changes for use on big endian SH4/SH3
348#endif
349
350/* it may or may not work on the SH1/SH2... So let's error on those
351 also */
352#if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
353#error insmod.c may require changes for non-SH3/SH4 use
354#endif
355
Eric Andersen9f16d612000-06-12 23:11:16 +0000356#define ELFCLASSM ELFCLASS32
Eric Andersenfe4208f2000-09-24 03:44:29 +0000357
358#if defined(__sh__)
359
360#define MATCH_MACHINE(x) (x == EM_SH)
361#define SHT_RELM SHT_RELA
362#define Elf32_RelM Elf32_Rela
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000363#define ELFDATAM ELFDATA2LSB
Eric Andersenfe4208f2000-09-24 03:44:29 +0000364
Eric Andersen21adca72000-12-06 18:18:26 +0000365#elif defined(__arm__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000366
Eric Andersen21adca72000-12-06 18:18:26 +0000367#define MATCH_MACHINE(x) (x == EM_ARM)
368#define SHT_RELM SHT_REL
369#define Elf32_RelM Elf32_Rel
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000370#define ELFDATAM ELFDATA2LSB
371
372#elif defined(__powerpc__)
373
374#define MATCH_MACHINE(x) (x == EM_PPC)
375#define SHT_RELM SHT_RELA
376#define Elf32_RelM Elf32_Rela
377#define ELFDATAM ELFDATA2MSB
Eric Andersen21adca72000-12-06 18:18:26 +0000378
Eric Andersen2bf658d2001-02-24 20:01:53 +0000379#elif defined(__mips__)
380
Eric Andersen82bb8a22001-03-22 19:01:16 +0000381/* Account for ELF spec changes. */
382#ifndef EM_MIPS_RS3_LE
383#ifdef EM_MIPS_RS4_BE
384#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
385#else
386#define EM_MIPS_RS3_LE 10
387#endif
388#endif /* !EM_MIPS_RS3_LE */
389
Eric Andersen2bf658d2001-02-24 20:01:53 +0000390#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
391#define SHT_RELM SHT_REL
392#define Elf32_RelM Elf32_Rel
393#ifdef __MIPSEB__
394#define ELFDATAM ELFDATA2MSB
395#endif
396#ifdef __MIPSEL__
397#define ELFDATAM ELFDATA2LSB
398#endif
399
Eric Andersen21adca72000-12-06 18:18:26 +0000400#elif defined(__i386__)
401
402/* presumably we can use these for anything but the SH and ARM*/
Eric Andersenfe4208f2000-09-24 03:44:29 +0000403/* this is the previous behavior, but it does result in
404 insmod.c being broken on anything except i386 */
Pavel Roskin43f3e612000-09-28 20:52:55 +0000405#ifndef EM_486
406#define MATCH_MACHINE(x) (x == EM_386)
407#else
Eric Andersenfe4208f2000-09-24 03:44:29 +0000408#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
Pavel Roskin43f3e612000-09-28 20:52:55 +0000409#endif
410
Eric Andersen9f16d612000-06-12 23:11:16 +0000411#define SHT_RELM SHT_REL
412#define Elf32_RelM Elf32_Rel
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000413#define ELFDATAM ELFDATA2LSB
Eric Andersen9f16d612000-06-12 23:11:16 +0000414
Eric Andersen21adca72000-12-06 18:18:26 +0000415#else
Eric Andersend5cad142001-01-26 02:23:57 +0000416#error Sorry, but insmod.c does not yet support this architecture...
Eric Andersenfe4208f2000-09-24 03:44:29 +0000417#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000418
419#ifndef ElfW
420# if ELFCLASSM == ELFCLASS32
421# define ElfW(x) Elf32_ ## x
422# define ELFW(x) ELF32_ ## x
423# else
424# define ElfW(x) Elf64_ ## x
425# define ELFW(x) ELF64_ ## x
426# endif
427#endif
428
429/* For some reason this is missing from libc5. */
430#ifndef ELF32_ST_INFO
431# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
432#endif
433
434#ifndef ELF64_ST_INFO
435# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
436#endif
437
438struct obj_string_patch;
439struct obj_symbol_patch;
440
441struct obj_section
442{
443 ElfW(Shdr) header;
444 const char *name;
445 char *contents;
446 struct obj_section *load_next;
447 int idx;
448};
449
450struct obj_symbol
451{
452 struct obj_symbol *next; /* hash table link */
453 const char *name;
454 unsigned long value;
455 unsigned long size;
456 int secidx; /* the defining section index/module */
457 int info;
458 int ksymidx; /* for export to the kernel symtab */
459 int referenced; /* actually used in the link */
460};
461
462/* Hardcode the hash table size. We shouldn't be needing so many
463 symbols that we begin to degrade performance, and we get a big win
464 by giving the compiler a constant divisor. */
465
466#define HASH_BUCKETS 521
467
468struct obj_file
469{
470 ElfW(Ehdr) header;
471 ElfW(Addr) baseaddr;
472 struct obj_section **sections;
473 struct obj_section *load_order;
474 struct obj_section **load_order_search_start;
475 struct obj_string_patch *string_patches;
476 struct obj_symbol_patch *symbol_patches;
477 int (*symbol_cmp)(const char *, const char *);
478 unsigned long (*symbol_hash)(const char *);
479 unsigned long local_symtab_size;
480 struct obj_symbol **local_symtab;
481 struct obj_symbol *symtab[HASH_BUCKETS];
482};
483
484enum obj_reloc
485{
486 obj_reloc_ok,
487 obj_reloc_overflow,
488 obj_reloc_dangerous,
489 obj_reloc_unhandled
490};
491
492struct obj_string_patch
493{
494 struct obj_string_patch *next;
495 int reloc_secidx;
496 ElfW(Addr) reloc_offset;
497 ElfW(Addr) string_offset;
498};
499
500struct obj_symbol_patch
501{
502 struct obj_symbol_patch *next;
503 int reloc_secidx;
504 ElfW(Addr) reloc_offset;
505 struct obj_symbol *sym;
506};
507
508
509/* Generic object manipulation routines. */
510
511unsigned long obj_elf_hash(const char *);
512
513unsigned long obj_elf_hash_n(const char *, unsigned long len);
514
515struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name,
516 unsigned long symidx, int info, int secidx,
517 ElfW(Addr) value, unsigned long size);
518
519struct obj_symbol *obj_find_symbol (struct obj_file *f,
520 const char *name);
521
522ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
523 struct obj_symbol *sym);
524
525void obj_set_symbol_compare(struct obj_file *f,
526 int (*cmp)(const char *, const char *),
527 unsigned long (*hash)(const char *));
528
529struct obj_section *obj_find_section (struct obj_file *f,
530 const char *name);
531
532void obj_insert_section_load_order (struct obj_file *f,
533 struct obj_section *sec);
534
535struct obj_section *obj_create_alloced_section (struct obj_file *f,
536 const char *name,
537 unsigned long align,
538 unsigned long size);
539
540struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
541 const char *name,
542 unsigned long align,
543 unsigned long size);
544
545void *obj_extend_section (struct obj_section *sec, unsigned long more);
546
547int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
548 const char *string);
549
550int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
551 struct obj_symbol *sym);
552
553int obj_check_undefineds(struct obj_file *f);
554
555void obj_allocate_commons(struct obj_file *f);
556
557unsigned long obj_load_size (struct obj_file *f);
558
559int obj_relocate (struct obj_file *f, ElfW(Addr) base);
560
561struct obj_file *obj_load(FILE *f);
562
563int obj_create_image (struct obj_file *f, char *image);
564
565/* Architecture specific manipulation routines. */
566
567struct obj_file *arch_new_file (void);
568
569struct obj_section *arch_new_section (void);
570
571struct obj_symbol *arch_new_symbol (void);
572
573enum obj_reloc arch_apply_relocation (struct obj_file *f,
574 struct obj_section *targsec,
575 struct obj_section *symsec,
576 struct obj_symbol *sym,
577 ElfW(RelM) *rel, ElfW(Addr) value);
578
579int arch_create_got (struct obj_file *f);
580
581struct new_module;
582int arch_init_module (struct obj_file *f, struct new_module *);
583
584#endif /* obj.h */
585//----------------------------------------------------------------------------
586//--------end of modutils obj.h
587//----------------------------------------------------------------------------
588
589
590
591
Erik Andersen02104321999-12-17 18:57:34 +0000592
Erik Andersend387d011999-12-21 02:55:11 +0000593#define _PATH_MODULES "/lib/modules"
Mark Whitley59ab0252001-01-23 22:30:04 +0000594static const int STRVERSIONLEN = 32;
Erik Andersend387d011999-12-21 02:55:11 +0000595
Eric Andersen9f16d612000-06-12 23:11:16 +0000596/*======================================================================*/
597
598int flag_force_load = 0;
599int flag_autoclean = 0;
600int flag_verbose = 0;
601int flag_export = 1;
602
603
604/*======================================================================*/
605
Eric Andersenfe4208f2000-09-24 03:44:29 +0000606/* previously, these were named i386_* but since we could be
607 compiling for the sh, I've renamed them to the more general
608 arch_* These structures are the same between the x86 and SH,
609 and we can't support anything else right now anyway. In the
610 future maybe they should be #if defined'd */
611
Eric Andersen21adca72000-12-06 18:18:26 +0000612/* Done ;-) */
613
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000614
615
616#if defined(BB_USE_PLT_ENTRIES)
617struct arch_plt_entry
Eric Andersen21adca72000-12-06 18:18:26 +0000618{
619 int offset;
620 int allocated:1;
621 int inited:1; /* has been set up */
622};
623#endif
624
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000625#if defined(BB_USE_GOT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000626struct arch_got_entry {
Eric Andersen9f16d612000-06-12 23:11:16 +0000627 int offset;
628 unsigned offset_done:1;
629 unsigned reloc_done:1;
630};
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000631#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000632
Eric Andersen2bf658d2001-02-24 20:01:53 +0000633#if defined(__mips__)
634struct mips_hi16
635{
636 struct mips_hi16 *next;
637 Elf32_Addr *addr;
638 Elf32_Addr value;
639};
640#endif
641
Eric Andersenfe4208f2000-09-24 03:44:29 +0000642struct arch_file {
Eric Andersen9f16d612000-06-12 23:11:16 +0000643 struct obj_file root;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000644#if defined(BB_USE_PLT_ENTRIES)
645 struct obj_section *plt;
Eric Andersen21adca72000-12-06 18:18:26 +0000646#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000647#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000648 struct obj_section *got;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000649#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000650#if defined(__mips__)
651 struct mips_hi16 *mips_hi16_list;
652#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000653};
654
Eric Andersenfe4208f2000-09-24 03:44:29 +0000655struct arch_symbol {
Eric Andersen9f16d612000-06-12 23:11:16 +0000656 struct obj_symbol root;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000657#if defined(BB_USE_PLT_ENTRIES)
658 struct arch_plt_entry pltent;
Eric Andersen21adca72000-12-06 18:18:26 +0000659#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000660#if defined(BB_USE_GOT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000661 struct arch_got_entry gotent;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000662#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000663};
664
665
Eric Andersen9f16d612000-06-12 23:11:16 +0000666struct external_module {
667 const char *name;
668 ElfW(Addr) addr;
669 int used;
670 size_t nsyms;
671 struct new_module_symbol *syms;
672};
673
674struct new_module_symbol *ksyms;
675size_t nksyms;
676
677struct external_module *ext_modules;
678int n_ext_modules;
679int n_ext_modules_used;
Erik Andersen02104321999-12-17 18:57:34 +0000680extern int delete_module(const char *);
Eric Andersena2a978a2001-04-05 06:08:14 +0000681
Eric Andersen14d35432001-05-14 17:07:32 +0000682static char m_filename[FILENAME_MAX + 1];
683static char m_fullName[FILENAME_MAX + 1];
Erik Andersen02104321999-12-17 18:57:34 +0000684
Eric Andersenfe4208f2000-09-24 03:44:29 +0000685
Erik Andersen02104321999-12-17 18:57:34 +0000686
Eric Andersen9f16d612000-06-12 23:11:16 +0000687/*======================================================================*/
Erik Andersen02104321999-12-17 18:57:34 +0000688
Eric Andersen9f16d612000-06-12 23:11:16 +0000689
Eric Andersen14d35432001-05-14 17:07:32 +0000690static int check_module_name_match(const char *filename, struct stat *statbuf,
691 void *userdata)
Eric Andersen9f16d612000-06-12 23:11:16 +0000692{
Eric Andersen14d35432001-05-14 17:07:32 +0000693 char *fullname = (char *) userdata;
Eric Andersen9f16d612000-06-12 23:11:16 +0000694
Eric Andersen14d35432001-05-14 17:07:32 +0000695 if (fullname[0] == '\0')
Erik Andersene49d5ec2000-02-08 19:58:47 +0000696 return (FALSE);
697 else {
Eric Andersen14d35432001-05-14 17:07:32 +0000698 char *tmp, *tmp1 = strdup(filename);
699 tmp = get_last_path_component(tmp1);
700 if (strcmp(tmp, fullname) == 0) {
701 free(tmp1);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000702 /* Stop searching if we find a match */
Eric Andersen14d35432001-05-14 17:07:32 +0000703 safe_strncpy(m_filename, filename, sizeof(m_filename));
704 return (TRUE);
Erik Andersene49d5ec2000-02-08 19:58:47 +0000705 }
Eric Andersen14d35432001-05-14 17:07:32 +0000706 free(tmp1);
Erik Andersend387d011999-12-21 02:55:11 +0000707 }
Eric Andersen14d35432001-05-14 17:07:32 +0000708 return (FALSE);
Erik Andersend387d011999-12-21 02:55:11 +0000709}
710
Erik Andersen02104321999-12-17 18:57:34 +0000711
Eric Andersen9f16d612000-06-12 23:11:16 +0000712/*======================================================================*/
713
714struct obj_file *arch_new_file(void)
Erik Andersen02104321999-12-17 18:57:34 +0000715{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000716 struct arch_file *f;
Eric Andersen9f16d612000-06-12 23:11:16 +0000717 f = xmalloc(sizeof(*f));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000718
719#if defined(BB_USE_PLT_ENTRIES)
720 f->plt = NULL;
721#endif
722#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000723 f->got = NULL;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000724#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +0000725#if defined(__mips__)
726 f->mips_hi16_list = NULL;
727#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000728
Eric Andersen9f16d612000-06-12 23:11:16 +0000729 return &f->root;
730}
731
732struct obj_section *arch_new_section(void)
733{
734 return xmalloc(sizeof(struct obj_section));
735}
736
737struct obj_symbol *arch_new_symbol(void)
738{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000739 struct arch_symbol *sym;
Eric Andersen9f16d612000-06-12 23:11:16 +0000740 sym = xmalloc(sizeof(*sym));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000741
742#if defined(BB_USE_PLT_ENTRIES)
743 memset(&sym->pltent, 0, sizeof(sym->pltent));
744#endif
745#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +0000746 memset(&sym->gotent, 0, sizeof(sym->gotent));
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000747#endif
748
Eric Andersen9f16d612000-06-12 23:11:16 +0000749 return &sym->root;
750}
Eric Andersenfe4208f2000-09-24 03:44:29 +0000751
Eric Andersen9f16d612000-06-12 23:11:16 +0000752enum obj_reloc
753arch_apply_relocation(struct obj_file *f,
754 struct obj_section *targsec,
755 struct obj_section *symsec,
756 struct obj_symbol *sym,
Eric Andersen21adca72000-12-06 18:18:26 +0000757 ElfW(RelM) *rel, ElfW(Addr) v)
Eric Andersen9f16d612000-06-12 23:11:16 +0000758{
Eric Andersenfe4208f2000-09-24 03:44:29 +0000759 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen82bb8a22001-03-22 19:01:16 +0000760#if !(defined(__mips__))
Eric Andersenfe4208f2000-09-24 03:44:29 +0000761 struct arch_symbol *isym = (struct arch_symbol *) sym;
Eric Andersen82bb8a22001-03-22 19:01:16 +0000762#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000763
Eric Andersen21adca72000-12-06 18:18:26 +0000764 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
765 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000766#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000767 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000768#endif
769#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +0000770 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000771 struct arch_plt_entry *pe;
Eric Andersen21adca72000-12-06 18:18:26 +0000772 unsigned long *ip;
773#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000774 enum obj_reloc ret = obj_reloc_ok;
775
776 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersenfe4208f2000-09-24 03:44:29 +0000777
778/* even though these constants seem to be the same for
779 the i386 and the sh, we "#if define" them for clarity
780 and in case that ever changes */
781#if defined(__sh__)
782 case R_SH_NONE:
Eric Andersen21adca72000-12-06 18:18:26 +0000783#elif defined(__arm__)
784 case R_ARM_NONE:
785#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +0000786 case R_386_NONE:
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000787#elif defined(__powerpc__)
788 case R_PPC_NONE:
Eric Andersen2bf658d2001-02-24 20:01:53 +0000789#elif defined(__mips__)
790 case R_MIPS_NONE:
Eric Andersenfe4208f2000-09-24 03:44:29 +0000791#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000792 break;
793
Eric Andersenfe4208f2000-09-24 03:44:29 +0000794#if defined(__sh__)
795 case R_SH_DIR32:
Eric Andersen21adca72000-12-06 18:18:26 +0000796#elif defined(__arm__)
797 case R_ARM_ABS32:
798#elif defined(__i386__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000799 case R_386_32:
800#elif defined(__powerpc__)
801 case R_PPC_ADDR32:
Eric Andersen2bf658d2001-02-24 20:01:53 +0000802#elif defined(__mips__)
803 case R_MIPS_32:
Eric Andersenfe4208f2000-09-24 03:44:29 +0000804#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000805 *loc += v;
806 break;
807
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000808#if defined(__powerpc__)
809 case R_PPC_ADDR16_HA:
810 *(unsigned short *)loc = (v + 0x8000) >> 16;
811 break;
812
813 case R_PPC_ADDR16_HI:
814 *(unsigned short *)loc = v >> 16;
815 break;
816
817 case R_PPC_ADDR16_LO:
818 *(unsigned short *)loc = v;
819 break;
820#endif
821
Eric Andersen2bf658d2001-02-24 20:01:53 +0000822#if defined(__mips__)
823 case R_MIPS_26:
824 if (v % 4)
825 ret = obj_reloc_dangerous;
826 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
827 ret = obj_reloc_overflow;
828 *loc =
829 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
830 0x03ffffff);
831 break;
832
833 case R_MIPS_HI16:
834 {
835 struct mips_hi16 *n;
836
837 /* We cannot relocate this one now because we don't know the value
838 of the carry we need to add. Save the information, and let LO16
839 do the actual relocation. */
840 n = (struct mips_hi16 *) xmalloc(sizeof *n);
841 n->addr = loc;
842 n->value = v;
843 n->next = ifile->mips_hi16_list;
844 ifile->mips_hi16_list = n;
845 break;
846 }
847
848 case R_MIPS_LO16:
849 {
850 unsigned long insnlo = *loc;
851 Elf32_Addr val, vallo;
852
853 /* Sign extend the addend we extract from the lo insn. */
854 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
855
856 if (ifile->mips_hi16_list != NULL) {
857 struct mips_hi16 *l;
858
859 l = ifile->mips_hi16_list;
860 while (l != NULL) {
861 struct mips_hi16 *next;
862 unsigned long insn;
863
864 /* The value for the HI16 had best be the same. */
865 assert(v == l->value);
866
867 /* Do the HI16 relocation. Note that we actually don't
868 need to know anything about the LO16 itself, except where
869 to find the low 16 bits of the addend needed by the LO16. */
870 insn = *l->addr;
871 val =
872 ((insn & 0xffff) << 16) +
873 vallo;
874 val += v;
875
876 /* Account for the sign extension that will happen in the
877 low bits. */
878 val =
879 ((val >> 16) +
880 ((val & 0x8000) !=
881 0)) & 0xffff;
882
883 insn = (insn & ~0xffff) | val;
884 *l->addr = insn;
885
886 next = l->next;
887 free(l);
888 l = next;
889 }
890
891 ifile->mips_hi16_list = NULL;
892 }
893
894 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
895 val = v + vallo;
896 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
897 *loc = insnlo;
898 break;
899 }
900#endif
901
Eric Andersen21adca72000-12-06 18:18:26 +0000902#if defined(__arm__)
903#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000904 case R_SH_REL32:
Eric Andersen9f16d612000-06-12 23:11:16 +0000905 *loc += v - dot;
906 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000907#elif defined(__i386__)
908 case R_386_PLT32:
909 case R_386_PC32:
910 *loc += v - dot;
911 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000912#elif defined(__powerpc__)
913 case R_PPC_REL32:
914 *loc = v - dot;
915 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000916#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000917
Eric Andersenfe4208f2000-09-24 03:44:29 +0000918#if defined(__sh__)
919 case R_SH_PLT32:
920 *loc = v - dot;
921 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000922#elif defined(__i386__)
923#endif
924
925#if defined(BB_USE_PLT_ENTRIES)
926
927#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000928 case R_ARM_PC24:
929 case R_ARM_PLT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000930#endif
931#if defined(__powerpc__)
932 case R_PPC_REL24:
933#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000934 /* find the plt entry and initialize it if necessary */
935 assert(isym != NULL);
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000936
937 pe = (struct arch_plt_entry*) &isym->pltent;
938
Eric Andersen21adca72000-12-06 18:18:26 +0000939 if (! pe->inited) {
940 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000941
942 /* generate some machine code */
943
944#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000945 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
946 ip[1] = v; /* sym@ */
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000947#endif
948#if defined(__powerpc__)
949 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */
950 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */
951 ip[2] = 0x7d6903a6; /* mtctr r11 */
952 ip[3] = 0x4e800420; /* bctr */
953#endif
Eric Andersen21adca72000-12-06 18:18:26 +0000954 pe->inited = 1;
955 }
956
957 /* relative distance to target */
958 v -= dot;
959 /* if the target is too far away.... */
960 if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
961 /* go via the plt */
962 v = plt + pe->offset - dot;
963 }
964 if (v & 3)
965 ret = obj_reloc_dangerous;
966
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000967 /* merge the offset into the instruction. */
968#if defined(__arm__)
Eric Andersen21adca72000-12-06 18:18:26 +0000969 /* Convert to words. */
970 v >>= 2;
971
Eric Andersen21adca72000-12-06 18:18:26 +0000972 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
Eric Andersenfe4208f2000-09-24 03:44:29 +0000973#endif
Eric Andersen90fe7fe2001-02-20 20:47:08 +0000974#if defined(__powerpc__)
975 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
976#endif
977 break;
978#endif /* BB_USE_PLT_ENTRIES */
Eric Andersenfe4208f2000-09-24 03:44:29 +0000979
Eric Andersen21adca72000-12-06 18:18:26 +0000980#if defined(__arm__)
981#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000982 case R_SH_GLOB_DAT:
983 case R_SH_JMP_SLOT:
984 *loc = v;
985 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000986#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +0000987 case R_386_GLOB_DAT:
988 case R_386_JMP_SLOT:
989 *loc = v;
990 break;
Eric Andersenfe4208f2000-09-24 03:44:29 +0000991#endif
Eric Andersen9f16d612000-06-12 23:11:16 +0000992
Eric Andersen21adca72000-12-06 18:18:26 +0000993#if defined(__arm__)
994#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000995 case R_SH_RELATIVE:
996 *loc += f->baseaddr + rel->r_addend;
997 break;
Eric Andersen21adca72000-12-06 18:18:26 +0000998#elif defined(__i386__)
Eric Andersenfe4208f2000-09-24 03:44:29 +0000999 case R_386_RELATIVE:
Eric Andersen9f16d612000-06-12 23:11:16 +00001000 *loc += f->baseaddr;
1001 break;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001002#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001003
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001004#if defined(BB_USE_GOT_ENTRIES)
1005
Eric Andersenfe4208f2000-09-24 03:44:29 +00001006#if defined(__sh__)
1007 case R_SH_GOTPC:
Eric Andersen21adca72000-12-06 18:18:26 +00001008#elif defined(__arm__)
1009 case R_ARM_GOTPC:
1010#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001011 case R_386_GOTPC:
Eric Andersenfe4208f2000-09-24 03:44:29 +00001012#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001013 assert(got != 0);
1014#if defined(__sh__)
1015 *loc += got - dot + rel->r_addend;;
1016#elif defined(__i386__) || defined(__arm__)
1017 *loc += got - dot;
1018#endif
1019 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001020
Eric Andersenfe4208f2000-09-24 03:44:29 +00001021#if defined(__sh__)
1022 case R_SH_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001023#elif defined(__arm__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001024 case R_ARM_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001025#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001026 case R_386_GOT32:
Eric Andersen21adca72000-12-06 18:18:26 +00001027#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001028 assert(isym != NULL);
Eric Andersen21adca72000-12-06 18:18:26 +00001029 /* needs an entry in the .got: set it, once */
Eric Andersen9f16d612000-06-12 23:11:16 +00001030 if (!isym->gotent.reloc_done) {
1031 isym->gotent.reloc_done = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001032 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
Eric Andersen9f16d612000-06-12 23:11:16 +00001033 }
Eric Andersen21adca72000-12-06 18:18:26 +00001034 /* make the reloc with_respect_to_.got */
1035#if defined(__sh__)
1036 *loc += isym->gotent.offset + rel->r_addend;
1037#elif defined(__i386__) || defined(__arm__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001038 *loc += isym->gotent.offset;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001039#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001040 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00001041
Eric Andersen21adca72000-12-06 18:18:26 +00001042 /* address relative to the got */
Eric Andersenfe4208f2000-09-24 03:44:29 +00001043#if defined(__sh__)
1044 case R_SH_GOTOFF:
Eric Andersen21adca72000-12-06 18:18:26 +00001045#elif defined(__arm__)
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001046 case R_ARM_GOTOFF:
Eric Andersen21adca72000-12-06 18:18:26 +00001047#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001048 case R_386_GOTOFF:
Eric Andersenfe4208f2000-09-24 03:44:29 +00001049#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001050 assert(got != 0);
1051 *loc += v - got;
1052 break;
1053
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001054#endif /* BB_USE_GOT_ENTRIES */
1055
Eric Andersen9f16d612000-06-12 23:11:16 +00001056 default:
Eric Andersen21125542000-12-13 16:41:29 +00001057 printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
Eric Andersen9f16d612000-06-12 23:11:16 +00001058 ret = obj_reloc_unhandled;
1059 break;
1060 }
1061
1062 return ret;
1063}
1064
1065int arch_create_got(struct obj_file *f)
1066{
Eric Andersen2bf658d2001-02-24 20:01:53 +00001067#if defined(BB_USE_GOT_ENTRIES) || defined(BB_USE_PLT_ENTRIES)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001068 struct arch_file *ifile = (struct arch_file *) f;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001069 int i;
1070#if defined(BB_USE_GOT_ENTRIES)
1071 int got_offset = 0, gotneeded = 0;
1072#endif
1073#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001074 int plt_offset = 0, pltneeded = 0;
Eric Andersenfe4208f2000-09-24 03:44:29 +00001075#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001076 struct obj_section *relsec, *symsec, *strsec;
1077 ElfW(RelM) *rel, *relend;
1078 ElfW(Sym) *symtab, *extsym;
1079 const char *strtab, *name;
1080 struct arch_symbol *intsym;
Eric Andersen9f16d612000-06-12 23:11:16 +00001081
Eric Andersen21adca72000-12-06 18:18:26 +00001082 for (i = 0; i < f->header.e_shnum; ++i) {
1083 relsec = f->sections[i];
1084 if (relsec->header.sh_type != SHT_RELM)
Eric Andersen9f16d612000-06-12 23:11:16 +00001085 continue;
1086
Eric Andersen21adca72000-12-06 18:18:26 +00001087 symsec = f->sections[relsec->header.sh_link];
1088 strsec = f->sections[symsec->header.sh_link];
Eric Andersen9f16d612000-06-12 23:11:16 +00001089
Eric Andersen21adca72000-12-06 18:18:26 +00001090 rel = (ElfW(RelM) *) relsec->contents;
1091 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1092 symtab = (ElfW(Sym) *) symsec->contents;
Eric Andersen9f16d612000-06-12 23:11:16 +00001093 strtab = (const char *) strsec->contents;
1094
1095 for (; rel < relend; ++rel) {
Eric Andersen21adca72000-12-06 18:18:26 +00001096 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
Eric Andersen9f16d612000-06-12 23:11:16 +00001097
1098 switch (ELF32_R_TYPE(rel->r_info)) {
Eric Andersen21adca72000-12-06 18:18:26 +00001099#if defined(__arm__)
1100 case R_ARM_GOT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001101 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001102#elif defined(__sh__)
Eric Andersenfe4208f2000-09-24 03:44:29 +00001103 case R_SH_GOT32:
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001104 break;
Eric Andersen21adca72000-12-06 18:18:26 +00001105#elif defined(__i386__)
Eric Andersen9f16d612000-06-12 23:11:16 +00001106 case R_386_GOT32:
1107 break;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001108#endif
1109
1110#if defined(__powerpc__)
1111 case R_PPC_REL24:
1112 pltneeded = 1;
1113 break;
1114#endif
Eric Andersen21adca72000-12-06 18:18:26 +00001115
1116#if defined(__arm__)
1117 case R_ARM_PC24:
1118 case R_ARM_PLT32:
1119 pltneeded = 1;
1120 break;
1121
1122 case R_ARM_GOTPC:
1123 case R_ARM_GOTOFF:
1124 gotneeded = 1;
1125 if (got_offset == 0)
1126 got_offset = 4;
1127#elif defined(__sh__)
1128 case R_SH_GOTPC:
1129 case R_SH_GOTOFF:
1130 gotneeded = 1;
1131#elif defined(__i386__)
1132 case R_386_GOTPC:
1133 case R_386_GOTOFF:
1134 gotneeded = 1;
1135#endif
1136
1137 default:
1138 continue;
Eric Andersen9f16d612000-06-12 23:11:16 +00001139 }
1140
Eric Andersen21adca72000-12-06 18:18:26 +00001141 if (extsym->st_name != 0) {
Eric Andersen9f16d612000-06-12 23:11:16 +00001142 name = strtab + extsym->st_name;
Eric Andersen21adca72000-12-06 18:18:26 +00001143 } else {
Eric Andersen9f16d612000-06-12 23:11:16 +00001144 name = f->sections[extsym->st_shndx]->name;
Eric Andersen21adca72000-12-06 18:18:26 +00001145 }
1146 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001147#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen9f16d612000-06-12 23:11:16 +00001148 if (!intsym->gotent.offset_done) {
1149 intsym->gotent.offset_done = 1;
Eric Andersen21adca72000-12-06 18:18:26 +00001150 intsym->gotent.offset = got_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001151 got_offset += BB_GOT_ENTRY_SIZE;
Eric Andersen21adca72000-12-06 18:18:26 +00001152 }
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001153#endif
1154#if defined(BB_USE_PLT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001155 if (pltneeded && intsym->pltent.allocated == 0) {
1156 intsym->pltent.allocated = 1;
1157 intsym->pltent.offset = plt_offset;
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001158 plt_offset += BB_PLT_ENTRY_SIZE;
Eric Andersen21adca72000-12-06 18:18:26 +00001159 intsym->pltent.inited = 0;
1160 pltneeded = 0;
1161 }
1162#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001163 }
1164 }
Eric Andersen21adca72000-12-06 18:18:26 +00001165
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001166#if defined(BB_USE_GOT_ENTRIES)
Eric Andersen21adca72000-12-06 18:18:26 +00001167 if (got_offset) {
Eric Andersene76c3b02001-04-05 03:14:39 +00001168 struct obj_section* myrelsec = obj_find_section(f, ".got");
Eric Andersen21adca72000-12-06 18:18:26 +00001169
Eric Andersene76c3b02001-04-05 03:14:39 +00001170 if (myrelsec) {
1171 obj_extend_section(myrelsec, got_offset);
Eric Andersen21adca72000-12-06 18:18:26 +00001172 } else {
Eric Andersene76c3b02001-04-05 03:14:39 +00001173 myrelsec = obj_create_alloced_section(f, ".got",
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001174 BB_GOT_ENTRY_SIZE,
1175 got_offset);
Eric Andersene76c3b02001-04-05 03:14:39 +00001176 assert(myrelsec);
Eric Andersen21adca72000-12-06 18:18:26 +00001177 }
1178
Eric Andersene76c3b02001-04-05 03:14:39 +00001179 ifile->got = myrelsec;
Eric Andersen9f16d612000-06-12 23:11:16 +00001180 }
Eric Andersen21adca72000-12-06 18:18:26 +00001181#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001182
Eric Andersen90fe7fe2001-02-20 20:47:08 +00001183#if defined(BB_USE_PLT_ENTRIES)
1184 if (plt_offset)
1185 ifile->plt = obj_create_alloced_section(f, ".plt",
1186 BB_PLT_ENTRY_SIZE,
1187 plt_offset);
1188#endif
Eric Andersen2bf658d2001-02-24 20:01:53 +00001189#endif
Eric Andersen9f16d612000-06-12 23:11:16 +00001190 return 1;
1191}
1192
1193int arch_init_module(struct obj_file *f, struct new_module *mod)
1194{
1195 return 1;
1196}
1197
1198
1199/*======================================================================*/
1200
1201/* Standard ELF hash function. */
1202inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1203{
1204 unsigned long h = 0;
1205 unsigned long g;
1206 unsigned char ch;
1207
1208 while (n > 0) {
1209 ch = *name++;
1210 h = (h << 4) + ch;
1211 if ((g = (h & 0xf0000000)) != 0) {
1212 h ^= g >> 24;
1213 h &= ~g;
1214 }
1215 n--;
1216 }
1217 return h;
1218}
1219
1220unsigned long obj_elf_hash(const char *name)
1221{
1222 return obj_elf_hash_n(name, strlen(name));
1223}
1224
1225#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1226/* Get the kernel version in the canonical integer form. */
1227
1228static int get_kernel_version(char str[STRVERSIONLEN])
1229{
1230 struct utsname uts_info;
1231 char *p, *q;
1232 int a, b, c;
1233
1234 if (uname(&uts_info) < 0)
1235 return -1;
1236 strncpy(str, uts_info.release, STRVERSIONLEN);
1237 p = uts_info.release;
1238
1239 a = strtoul(p, &p, 10);
1240 if (*p != '.')
1241 return -1;
1242 b = strtoul(p + 1, &p, 10);
1243 if (*p != '.')
1244 return -1;
1245 c = strtoul(p + 1, &q, 10);
1246 if (p + 1 == q)
1247 return -1;
1248
1249 return a << 16 | b << 8 | c;
1250}
1251
1252/* String comparison for non-co-versioned kernel and module. */
1253
1254static int ncv_strcmp(const char *a, const char *b)
1255{
1256 size_t alen = strlen(a), blen = strlen(b);
1257
1258 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1259 return strncmp(a, b, alen);
1260 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1261 return strncmp(a, b, blen);
1262 else
1263 return strcmp(a, b);
1264}
1265
1266/* String hashing for non-co-versioned kernel and module. Here
1267 we are simply forced to drop the crc from the hash. */
1268
1269static unsigned long ncv_symbol_hash(const char *str)
1270{
1271 size_t len = strlen(str);
1272 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1273 len -= 10;
1274 return obj_elf_hash_n(str, len);
1275}
1276
1277void
1278obj_set_symbol_compare(struct obj_file *f,
1279 int (*cmp) (const char *, const char *),
1280 unsigned long (*hash) (const char *))
1281{
1282 if (cmp)
1283 f->symbol_cmp = cmp;
1284 if (hash) {
1285 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1286 int i;
1287
1288 f->symbol_hash = hash;
1289
1290 memcpy(tmptab, f->symtab, sizeof(tmptab));
1291 memset(f->symtab, 0, sizeof(f->symtab));
1292
1293 for (i = 0; i < HASH_BUCKETS; ++i)
1294 for (sym = tmptab[i]; sym; sym = next) {
1295 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1296 next = sym->next;
1297 sym->next = f->symtab[h];
1298 f->symtab[h] = sym;
1299 }
1300 }
1301}
1302
1303#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1304
1305
1306struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
1307 unsigned long symidx, int info,
1308 int secidx, ElfW(Addr) value,
1309 unsigned long size)
1310{
1311 struct obj_symbol *sym;
1312 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1313 int n_type = ELFW(ST_TYPE) (info);
1314 int n_binding = ELFW(ST_BIND) (info);
1315
1316 for (sym = f->symtab[hash]; sym; sym = sym->next)
1317 if (f->symbol_cmp(sym->name, name) == 0) {
1318 int o_secidx = sym->secidx;
1319 int o_info = sym->info;
1320 int o_type = ELFW(ST_TYPE) (o_info);
1321 int o_binding = ELFW(ST_BIND) (o_info);
1322
1323 /* A redefinition! Is it legal? */
1324
1325 if (secidx == SHN_UNDEF)
1326 return sym;
1327 else if (o_secidx == SHN_UNDEF)
1328 goto found;
1329 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1330 /* Cope with local and global symbols of the same name
1331 in the same object file, as might have been created
1332 by ld -r. The only reason locals are now seen at this
1333 level at all is so that we can do semi-sensible things
1334 with parameters. */
1335
1336 struct obj_symbol *nsym, **p;
1337
1338 nsym = arch_new_symbol();
1339 nsym->next = sym->next;
1340 nsym->ksymidx = -1;
1341
1342 /* Excise the old (local) symbol from the hash chain. */
1343 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1344 continue;
1345 *p = sym = nsym;
1346 goto found;
1347 } else if (n_binding == STB_LOCAL) {
1348 /* Another symbol of the same name has already been defined.
1349 Just add this to the local table. */
1350 sym = arch_new_symbol();
1351 sym->next = NULL;
1352 sym->ksymidx = -1;
1353 f->local_symtab[symidx] = sym;
1354 goto found;
1355 } else if (n_binding == STB_WEAK)
1356 return sym;
1357 else if (o_binding == STB_WEAK)
1358 goto found;
1359 /* Don't unify COMMON symbols with object types the programmer
1360 doesn't expect. */
1361 else if (secidx == SHN_COMMON
1362 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1363 return sym;
1364 else if (o_secidx == SHN_COMMON
1365 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1366 goto found;
1367 else {
1368 /* Don't report an error if the symbol is coming from
1369 the kernel or some external module. */
1370 if (secidx <= SHN_HIRESERVE)
Matt Kraaidd19c692001-01-31 19:00:21 +00001371 error_msg("%s multiply defined", name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001372 return sym;
1373 }
1374 }
1375
1376 /* Completely new symbol. */
1377 sym = arch_new_symbol();
1378 sym->next = f->symtab[hash];
1379 f->symtab[hash] = sym;
1380 sym->ksymidx = -1;
1381
1382 if (ELFW(ST_BIND) (info) == STB_LOCAL)
1383 f->local_symtab[symidx] = sym;
1384
1385 found:
1386 sym->name = name;
1387 sym->value = value;
1388 sym->size = size;
1389 sym->secidx = secidx;
1390 sym->info = info;
1391
1392 return sym;
1393}
1394
1395struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
1396{
1397 struct obj_symbol *sym;
1398 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1399
1400 for (sym = f->symtab[hash]; sym; sym = sym->next)
1401 if (f->symbol_cmp(sym->name, name) == 0)
1402 return sym;
1403
1404 return NULL;
1405}
1406
1407ElfW(Addr)
1408 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1409{
1410 if (sym) {
1411 if (sym->secidx >= SHN_LORESERVE)
1412 return sym->value;
1413
1414 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1415 } else {
1416 /* As a special case, a NULL sym has value zero. */
1417 return 0;
1418 }
1419}
1420
1421struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1422{
1423 int i, n = f->header.e_shnum;
1424
1425 for (i = 0; i < n; ++i)
1426 if (strcmp(f->sections[i]->name, name) == 0)
1427 return f->sections[i];
1428
1429 return NULL;
1430}
1431
1432static int obj_load_order_prio(struct obj_section *a)
1433{
1434 unsigned long af, ac;
1435
1436 af = a->header.sh_flags;
1437
1438 ac = 0;
1439 if (a->name[0] != '.' || strlen(a->name) != 10 ||
1440 strcmp(a->name + 5, ".init"))
1441 ac |= 32;
1442 if (af & SHF_ALLOC)
1443 ac |= 16;
1444 if (!(af & SHF_WRITE))
1445 ac |= 8;
1446 if (af & SHF_EXECINSTR)
1447 ac |= 4;
1448 if (a->header.sh_type != SHT_NOBITS)
1449 ac |= 2;
1450
1451 return ac;
1452}
1453
1454void
1455obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1456{
1457 struct obj_section **p;
1458 int prio = obj_load_order_prio(sec);
1459 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1460 if (obj_load_order_prio(*p) < prio)
1461 break;
1462 sec->load_next = *p;
1463 *p = sec;
1464}
1465
1466struct obj_section *obj_create_alloced_section(struct obj_file *f,
1467 const char *name,
1468 unsigned long align,
1469 unsigned long size)
1470{
1471 int newidx = f->header.e_shnum++;
1472 struct obj_section *sec;
1473
1474 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1475 f->sections[newidx] = sec = arch_new_section();
1476
1477 memset(sec, 0, sizeof(*sec));
1478 sec->header.sh_type = SHT_PROGBITS;
1479 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1480 sec->header.sh_size = size;
1481 sec->header.sh_addralign = align;
1482 sec->name = name;
1483 sec->idx = newidx;
1484 if (size)
1485 sec->contents = xmalloc(size);
1486
1487 obj_insert_section_load_order(f, sec);
1488
1489 return sec;
1490}
1491
1492struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1493 const char *name,
1494 unsigned long align,
1495 unsigned long size)
1496{
1497 int newidx = f->header.e_shnum++;
1498 struct obj_section *sec;
1499
1500 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1501 f->sections[newidx] = sec = arch_new_section();
1502
1503 memset(sec, 0, sizeof(*sec));
1504 sec->header.sh_type = SHT_PROGBITS;
1505 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1506 sec->header.sh_size = size;
1507 sec->header.sh_addralign = align;
1508 sec->name = name;
1509 sec->idx = newidx;
1510 if (size)
1511 sec->contents = xmalloc(size);
1512
1513 sec->load_next = f->load_order;
1514 f->load_order = sec;
1515 if (f->load_order_search_start == &f->load_order)
1516 f->load_order_search_start = &sec->load_next;
1517
1518 return sec;
1519}
1520
1521void *obj_extend_section(struct obj_section *sec, unsigned long more)
1522{
1523 unsigned long oldsize = sec->header.sh_size;
Eric Andersen7f3b86e2001-04-26 19:29:58 +00001524 if (more) {
1525 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1526 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001527 return sec->contents + oldsize;
1528}
1529
1530
1531
1532/* Conditionally add the symbols from the given symbol set to the
1533 new module. */
1534
1535static int
1536add_symbols_from(
1537 struct obj_file *f,
1538 int idx, struct new_module_symbol *syms, size_t nsyms)
1539{
1540 struct new_module_symbol *s;
1541 size_t i;
1542 int used = 0;
1543
1544 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1545
1546 /* Only add symbols that are already marked external. If we
1547 override locals we may cause problems for argument initialization.
1548 We will also create a false dependency on the module. */
1549 struct obj_symbol *sym;
1550
1551 sym = obj_find_symbol(f, (char *) s->name);
1552 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1553 sym = obj_add_symbol(f, (char *) s->name, -1,
1554 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1555 idx, s->value, 0);
1556 /* Did our symbol just get installed? If so, mark the
1557 module as "used". */
1558 if (sym->secidx == idx)
1559 used = 1;
1560 }
1561 }
1562
1563 return used;
1564}
1565
1566static void add_kernel_symbols(struct obj_file *f)
1567{
1568 struct external_module *m;
Pavel Roskinff5a9032000-07-14 16:23:32 +00001569 int i, nused = 0;
Eric Andersen9f16d612000-06-12 23:11:16 +00001570
1571 /* Add module symbols first. */
1572
1573 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1574 if (m->nsyms
1575 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1576 m->nsyms)) m->used = 1, ++nused;
1577
1578 n_ext_modules_used = nused;
1579
1580 /* And finally the symbols from the kernel proper. */
1581
1582 if (nksyms)
1583 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1584}
1585
1586static char *get_modinfo_value(struct obj_file *f, const char *key)
1587{
1588 struct obj_section *sec;
1589 char *p, *v, *n, *ep;
1590 size_t klen = strlen(key);
1591
1592 sec = obj_find_section(f, ".modinfo");
1593 if (sec == NULL)
1594 return NULL;
1595 p = sec->contents;
1596 ep = p + sec->header.sh_size;
1597 while (p < ep) {
1598 v = strchr(p, '=');
1599 n = strchr(p, '\0');
1600 if (v) {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001601 if (p + klen == v && strncmp(p, key, klen) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001602 return v + 1;
1603 } else {
Pavel Roskinff5a9032000-07-14 16:23:32 +00001604 if (p + klen == n && strcmp(p, key) == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00001605 return n;
1606 }
1607 p = n + 1;
1608 }
1609
1610 return NULL;
1611}
1612
1613
1614/*======================================================================*/
1615/* Functions relating to module loading in pre 2.1 kernels. */
1616
1617static int
1618old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1619{
1620 while (argc > 0) {
1621 char *p, *q;
1622 struct obj_symbol *sym;
1623 int *loc;
1624
1625 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00001626 if ((q = strchr(p, '=')) == NULL) {
1627 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00001628 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00001629 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001630 *q++ = '\0';
1631
1632 sym = obj_find_symbol(f, p);
1633
1634 /* Also check that the parameter was not resolved from the kernel. */
1635 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00001636 error_msg("symbol for parameter %s not found", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001637 return 0;
1638 }
1639
1640 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1641
1642 /* Do C quoting if we begin with a ". */
1643 if (*q == '"') {
1644 char *r, *str;
1645
1646 str = alloca(strlen(q));
1647 for (r = str, q++; *q != '"'; ++q, ++r) {
1648 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00001649 error_msg("improperly terminated string argument for %s", p);
Eric Andersen9f16d612000-06-12 23:11:16 +00001650 return 0;
1651 } else if (*q == '\\')
1652 switch (*++q) {
1653 case 'a':
1654 *r = '\a';
1655 break;
1656 case 'b':
1657 *r = '\b';
1658 break;
1659 case 'e':
1660 *r = '\033';
1661 break;
1662 case 'f':
1663 *r = '\f';
1664 break;
1665 case 'n':
1666 *r = '\n';
1667 break;
1668 case 'r':
1669 *r = '\r';
1670 break;
1671 case 't':
1672 *r = '\t';
1673 break;
1674
1675 case '0':
1676 case '1':
1677 case '2':
1678 case '3':
1679 case '4':
1680 case '5':
1681 case '6':
1682 case '7':
1683 {
1684 int c = *q - '0';
1685 if (q[1] >= '0' && q[1] <= '7') {
1686 c = (c * 8) + *++q - '0';
1687 if (q[1] >= '0' && q[1] <= '7')
1688 c = (c * 8) + *++q - '0';
1689 }
1690 *r = c;
1691 }
1692 break;
1693
1694 default:
1695 *r = *q;
1696 break;
1697 } else
1698 *r = *q;
1699 }
1700 *r = '\0';
1701 obj_string_patch(f, sym->secidx, sym->value, str);
1702 } else if (*q >= '0' && *q <= '9') {
1703 do
1704 *loc++ = strtoul(q, &q, 0);
1705 while (*q++ == ',');
1706 } else {
1707 char *contents = f->sections[sym->secidx]->contents;
Eric Andersene76c3b02001-04-05 03:14:39 +00001708 char *myloc = contents + sym->value;
Eric Andersen9f16d612000-06-12 23:11:16 +00001709 char *r; /* To search for commas */
1710
1711 /* Break the string with comas */
1712 while ((r = strchr(q, ',')) != (char *) NULL) {
1713 *r++ = '\0';
Eric Andersene76c3b02001-04-05 03:14:39 +00001714 obj_string_patch(f, sym->secidx, myloc - contents, q);
1715 myloc += sizeof(char *);
Eric Andersen9f16d612000-06-12 23:11:16 +00001716 q = r;
1717 }
1718
1719 /* last part */
Eric Andersene76c3b02001-04-05 03:14:39 +00001720 obj_string_patch(f, sym->secidx, myloc - contents, q);
Eric Andersen9f16d612000-06-12 23:11:16 +00001721 }
1722
1723 argc--, argv++;
1724 }
1725
1726 return 1;
1727}
1728
1729#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1730static int old_is_module_checksummed(struct obj_file *f)
1731{
1732 return obj_find_symbol(f, "Using_Versions") != NULL;
1733}
1734/* Get the module's kernel version in the canonical integer form. */
1735
1736static int
1737old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1738{
1739 struct obj_symbol *sym;
1740 char *p, *q;
1741 int a, b, c;
1742
1743 sym = obj_find_symbol(f, "kernel_version");
1744 if (sym == NULL)
1745 return -1;
1746
1747 p = f->sections[sym->secidx]->contents + sym->value;
1748 strncpy(str, p, STRVERSIONLEN);
1749
1750 a = strtoul(p, &p, 10);
1751 if (*p != '.')
1752 return -1;
1753 b = strtoul(p + 1, &p, 10);
1754 if (*p != '.')
1755 return -1;
1756 c = strtoul(p + 1, &q, 10);
1757 if (p + 1 == q)
1758 return -1;
1759
1760 return a << 16 | b << 8 | c;
1761}
1762
1763#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1764
Eric Andersenf5d5e772001-01-24 23:34:48 +00001765#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00001766
1767/* Fetch all the symbols and divvy them up as appropriate for the modules. */
1768
Eric Andersen8c185f92000-09-22 00:38:07 +00001769static int old_get_kernel_symbols(const char *m_name)
Eric Andersen9f16d612000-06-12 23:11:16 +00001770{
1771 struct old_kernel_sym *ks, *k;
1772 struct new_module_symbol *s;
1773 struct external_module *mod;
1774 int nks, nms, nmod, i;
1775
1776 nks = get_kernel_syms(NULL);
Eric Andersenf2278152001-04-24 21:41:41 +00001777 if (nks <= 0) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00001778 if (nks)
1779 perror_msg("get_kernel_syms: %s", m_name);
1780 else
1781 error_msg("No kernel symbols");
Eric Andersen9f16d612000-06-12 23:11:16 +00001782 return 0;
1783 }
1784
1785 ks = k = xmalloc(nks * sizeof(*ks));
1786
1787 if (get_kernel_syms(ks) != nks) {
1788 perror("inconsistency with get_kernel_syms -- is someone else "
1789 "playing with modules?");
1790 free(ks);
1791 return 0;
1792 }
1793
1794 /* Collect the module information. */
1795
1796 mod = NULL;
1797 nmod = -1;
1798
1799 while (k->name[0] == '#' && k->name[1]) {
1800 struct old_kernel_sym *k2;
Eric Andersen9f16d612000-06-12 23:11:16 +00001801
1802 /* Find out how many symbols this module has. */
1803 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1804 continue;
1805 nms = k2 - k - 1;
1806
1807 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1808 mod[nmod].name = k->name + 1;
1809 mod[nmod].addr = k->value;
1810 mod[nmod].used = 0;
1811 mod[nmod].nsyms = nms;
1812 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1813
1814 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1815 s->name = (unsigned long) k->name;
1816 s->value = k->value;
1817 }
1818
1819 k = k2;
1820 }
1821
1822 ext_modules = mod;
1823 n_ext_modules = nmod + 1;
1824
1825 /* Now collect the symbols for the kernel proper. */
1826
1827 if (k->name[0] == '#')
1828 ++k;
1829
1830 nksyms = nms = nks - (k - ks);
1831 ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1832
1833 for (i = 0; i < nms; ++i, ++s, ++k) {
1834 s->name = (unsigned long) k->name;
1835 s->value = k->value;
1836 }
1837
1838 return 1;
1839}
1840
1841/* Return the kernel symbol checksum version, or zero if not used. */
1842
1843static int old_is_kernel_checksummed(void)
1844{
1845 /* Using_Versions is the first symbol. */
1846 if (nksyms > 0
1847 && strcmp((char *) ksyms[0].name,
1848 "Using_Versions") == 0) return ksyms[0].value;
1849 else
1850 return 0;
1851}
1852
1853
1854static int old_create_mod_use_count(struct obj_file *f)
1855{
1856 struct obj_section *sec;
1857
1858 sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1859 sizeof(long));
1860
1861 obj_add_symbol(f, "mod_use_count_", -1,
1862 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1863 sizeof(long));
1864
1865 return 1;
1866}
1867
1868static int
1869old_init_module(const char *m_name, struct obj_file *f,
1870 unsigned long m_size)
1871{
1872 char *image;
1873 struct old_mod_routines routines;
1874 struct old_symbol_table *symtab;
1875 int ret;
1876
1877 /* Create the symbol table */
1878 {
1879 int nsyms = 0, strsize = 0, total;
1880
1881 /* Size things first... */
1882 if (flag_export) {
1883 int i;
1884 for (i = 0; i < HASH_BUCKETS; ++i) {
1885 struct obj_symbol *sym;
1886 for (sym = f->symtab[i]; sym; sym = sym->next)
1887 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1888 && sym->secidx <= SHN_HIRESERVE)
1889 {
1890 sym->ksymidx = nsyms++;
1891 strsize += strlen(sym->name) + 1;
1892 }
1893 }
1894 }
1895
1896 total = (sizeof(struct old_symbol_table)
1897 + nsyms * sizeof(struct old_module_symbol)
1898 + n_ext_modules_used * sizeof(struct old_module_ref)
1899 + strsize);
1900 symtab = xmalloc(total);
1901 symtab->size = total;
1902 symtab->n_symbols = nsyms;
1903 symtab->n_refs = n_ext_modules_used;
1904
1905 if (flag_export && nsyms) {
1906 struct old_module_symbol *ksym;
1907 char *str;
1908 int i;
1909
1910 ksym = symtab->symbol;
1911 str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1912 + n_ext_modules_used * sizeof(struct old_module_ref));
1913
1914 for (i = 0; i < HASH_BUCKETS; ++i) {
1915 struct obj_symbol *sym;
1916 for (sym = f->symtab[i]; sym; sym = sym->next)
1917 if (sym->ksymidx >= 0) {
1918 ksym->addr = obj_symbol_final_value(f, sym);
1919 ksym->name =
1920 (unsigned long) str - (unsigned long) symtab;
1921
Matt Kraai70a78552001-01-04 02:00:17 +00001922 strcpy(str, sym->name);
1923 str += strlen(sym->name) + 1;
Eric Andersen9f16d612000-06-12 23:11:16 +00001924 ksym++;
1925 }
1926 }
1927 }
1928
1929 if (n_ext_modules_used) {
1930 struct old_module_ref *ref;
1931 int i;
1932
1933 ref = (struct old_module_ref *)
1934 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1935
1936 for (i = 0; i < n_ext_modules; ++i)
1937 if (ext_modules[i].used)
1938 ref++->module = ext_modules[i].addr;
1939 }
1940 }
1941
1942 /* Fill in routines. */
1943
1944 routines.init =
1945 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1946 routines.cleanup =
1947 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1948
1949 /* Whew! All of the initialization is complete. Collect the final
1950 module image and give it to the kernel. */
1951
1952 image = xmalloc(m_size);
1953 obj_create_image(f, image);
1954
1955 /* image holds the complete relocated module, accounting correctly for
1956 mod_use_count. However the old module kernel support assume that
1957 it is receiving something which does not contain mod_use_count. */
1958 ret = old_sys_init_module(m_name, image + sizeof(long),
1959 m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1960 : 0), &routines, symtab);
1961 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00001962 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00001963
1964 free(image);
1965 free(symtab);
1966
1967 return ret == 0;
1968}
1969
1970#else
1971
1972#define old_create_mod_use_count(x) TRUE
1973#define old_init_module(x, y, z) TRUE
1974
Eric Andersenf5d5e772001-01-24 23:34:48 +00001975#endif /* BB_FEATURE_OLD_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00001976
1977
1978
1979/*======================================================================*/
1980/* Functions relating to module loading after 2.1.18. */
1981
1982static int
1983new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1984{
1985 while (argc > 0) {
1986 char *p, *q, *key;
1987 struct obj_symbol *sym;
1988 char *contents, *loc;
1989 int min, max, n;
1990
1991 p = *argv;
Eric Andersenef40aa82000-06-26 11:16:22 +00001992 if ((q = strchr(p, '=')) == NULL) {
1993 argc--;
Eric Andersen9f16d612000-06-12 23:11:16 +00001994 continue;
Eric Andersenef40aa82000-06-26 11:16:22 +00001995 }
Eric Andersen9f16d612000-06-12 23:11:16 +00001996
1997 key = alloca(q - p + 6);
1998 memcpy(key, "parm_", 5);
1999 memcpy(key + 5, p, q - p);
2000 key[q - p + 5] = 0;
2001
2002 p = get_modinfo_value(f, key);
2003 key += 5;
2004 if (p == NULL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002005 error_msg("invalid parameter %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002006 return 0;
2007 }
2008
2009 sym = obj_find_symbol(f, key);
2010
2011 /* Also check that the parameter was not resolved from the kernel. */
2012 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002013 error_msg("symbol for parameter %s not found", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002014 return 0;
2015 }
2016
2017 if (isdigit(*p)) {
2018 min = strtoul(p, &p, 10);
2019 if (*p == '-')
2020 max = strtoul(p + 1, &p, 10);
2021 else
2022 max = min;
2023 } else
2024 min = max = 1;
2025
2026 contents = f->sections[sym->secidx]->contents;
2027 loc = contents + sym->value;
2028 n = (*++q != '\0');
2029
2030 while (1) {
2031 if ((*p == 's') || (*p == 'c')) {
2032 char *str;
2033
2034 /* Do C quoting if we begin with a ", else slurp the lot. */
2035 if (*q == '"') {
2036 char *r;
2037
2038 str = alloca(strlen(q));
2039 for (r = str, q++; *q != '"'; ++q, ++r) {
2040 if (*q == '\0') {
Matt Kraaidd19c692001-01-31 19:00:21 +00002041 error_msg("improperly terminated string argument for %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00002042 key);
2043 return 0;
2044 } else if (*q == '\\')
2045 switch (*++q) {
2046 case 'a':
2047 *r = '\a';
2048 break;
2049 case 'b':
2050 *r = '\b';
2051 break;
2052 case 'e':
2053 *r = '\033';
2054 break;
2055 case 'f':
2056 *r = '\f';
2057 break;
2058 case 'n':
2059 *r = '\n';
2060 break;
2061 case 'r':
2062 *r = '\r';
2063 break;
2064 case 't':
2065 *r = '\t';
2066 break;
2067
2068 case '0':
2069 case '1':
2070 case '2':
2071 case '3':
2072 case '4':
2073 case '5':
2074 case '6':
2075 case '7':
2076 {
2077 int c = *q - '0';
2078 if (q[1] >= '0' && q[1] <= '7') {
2079 c = (c * 8) + *++q - '0';
2080 if (q[1] >= '0' && q[1] <= '7')
2081 c = (c * 8) + *++q - '0';
2082 }
2083 *r = c;
2084 }
2085 break;
2086
2087 default:
2088 *r = *q;
2089 break;
2090 } else
2091 *r = *q;
2092 }
2093 *r = '\0';
2094 ++q;
2095 } else {
2096 char *r;
2097
2098 /* In this case, the string is not quoted. We will break
2099 it using the coma (like for ints). If the user wants to
2100 include comas in a string, he just has to quote it */
2101
2102 /* Search the next coma */
2103 r = strchr(q, ',');
2104
2105 /* Found ? */
2106 if (r != (char *) NULL) {
2107 /* Recopy the current field */
2108 str = alloca(r - q + 1);
2109 memcpy(str, q, r - q);
2110
2111 /* I don't know if it is usefull, as the previous case
2112 doesn't null terminate the string ??? */
2113 str[r - q] = '\0';
2114
2115 /* Keep next fields */
2116 q = r;
2117 } else {
2118 /* last string */
2119 str = q;
2120 q = "";
2121 }
2122 }
2123
2124 if (*p == 's') {
2125 /* Normal string */
2126 obj_string_patch(f, sym->secidx, loc - contents, str);
2127 loc += tgt_sizeof_char_p;
2128 } else {
2129 /* Array of chars (in fact, matrix !) */
Pavel Roskinff5a9032000-07-14 16:23:32 +00002130 unsigned long charssize; /* size of each member */
Eric Andersen9f16d612000-06-12 23:11:16 +00002131
2132 /* Get the size of each member */
2133 /* Probably we should do that outside the loop ? */
2134 if (!isdigit(*(p + 1))) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00002135 error_msg("parameter type 'c' for %s must be followed by"
Matt Kraaidd19c692001-01-31 19:00:21 +00002136 " the maximum size", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002137 return 0;
2138 }
2139 charssize = strtoul(p + 1, (char **) NULL, 10);
2140
2141 /* Check length */
2142 if (strlen(str) >= charssize) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002143 error_msg("string too long for %s (max %ld)", key,
Eric Andersen9f16d612000-06-12 23:11:16 +00002144 charssize - 1);
2145 return 0;
2146 }
2147
2148 /* Copy to location */
2149 strcpy((char *) loc, str);
2150 loc += charssize;
2151 }
2152 } else {
2153 long v = strtoul(q, &q, 0);
2154 switch (*p) {
2155 case 'b':
2156 *loc++ = v;
2157 break;
2158 case 'h':
2159 *(short *) loc = v;
2160 loc += tgt_sizeof_short;
2161 break;
2162 case 'i':
2163 *(int *) loc = v;
2164 loc += tgt_sizeof_int;
2165 break;
2166 case 'l':
2167 *(long *) loc = v;
2168 loc += tgt_sizeof_long;
2169 break;
2170
2171 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002172 error_msg("unknown parameter type '%c' for %s", *p, key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002173 return 0;
2174 }
2175 }
2176
2177 retry_end_of_value:
2178 switch (*q) {
2179 case '\0':
2180 goto end_of_arg;
2181
2182 case ' ':
2183 case '\t':
2184 case '\n':
2185 case '\r':
2186 ++q;
2187 goto retry_end_of_value;
2188
2189 case ',':
2190 if (++n > max) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002191 error_msg("too many values for %s (max %d)", key, max);
Eric Andersen9f16d612000-06-12 23:11:16 +00002192 return 0;
2193 }
2194 ++q;
2195 break;
2196
2197 default:
Matt Kraaidd19c692001-01-31 19:00:21 +00002198 error_msg("invalid argument syntax for %s", key);
Eric Andersen9f16d612000-06-12 23:11:16 +00002199 return 0;
2200 }
2201 }
2202
2203 end_of_arg:
2204 if (n < min) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002205 error_msg("too few values for %s (min %d)", key, min);
Eric Andersen9f16d612000-06-12 23:11:16 +00002206 return 0;
2207 }
2208
2209 argc--, argv++;
2210 }
2211
2212 return 1;
2213}
2214
2215#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2216static int new_is_module_checksummed(struct obj_file *f)
2217{
2218 const char *p = get_modinfo_value(f, "using_checksums");
2219 if (p)
2220 return atoi(p);
2221 else
2222 return 0;
2223}
2224
2225/* Get the module's kernel version in the canonical integer form. */
2226
2227static int
2228new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2229{
2230 char *p, *q;
2231 int a, b, c;
2232
2233 p = get_modinfo_value(f, "kernel_version");
2234 if (p == NULL)
2235 return -1;
2236 strncpy(str, p, STRVERSIONLEN);
2237
2238 a = strtoul(p, &p, 10);
2239 if (*p != '.')
2240 return -1;
2241 b = strtoul(p + 1, &p, 10);
2242 if (*p != '.')
2243 return -1;
2244 c = strtoul(p + 1, &q, 10);
2245 if (p + 1 == q)
2246 return -1;
2247
2248 return a << 16 | b << 8 | c;
2249}
2250
2251#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2252
2253
Eric Andersenf5d5e772001-01-24 23:34:48 +00002254#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00002255
2256/* Fetch the loaded modules, and all currently exported symbols. */
2257
2258static int new_get_kernel_symbols(void)
2259{
2260 char *module_names, *mn;
2261 struct external_module *modules, *m;
2262 struct new_module_symbol *syms, *s;
2263 size_t ret, bufsize, nmod, nsyms, i, j;
2264
2265 /* Collect the loaded modules. */
2266
2267 module_names = xmalloc(bufsize = 256);
2268 retry_modules_load:
2269 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002270 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002271 module_names = xrealloc(module_names, bufsize = ret);
2272 goto retry_modules_load;
2273 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002274 perror_msg("QM_MODULES");
Eric Andersen9f16d612000-06-12 23:11:16 +00002275 return 0;
2276 }
2277
2278 n_ext_modules = nmod = ret;
Eric Andersen9f16d612000-06-12 23:11:16 +00002279
2280 /* Collect the modules' symbols. */
2281
Mark Whitley94fd4802001-03-12 23:08:34 +00002282 if (nmod){
2283 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2284 memset(modules, 0, nmod * sizeof(*modules));
2285 for (i = 0, mn = module_names, m = modules;
2286 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2287 struct new_module_info info;
2288
2289 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2290 if (errno == ENOENT) {
2291 /* The module was removed out from underneath us. */
2292 continue;
2293 }
2294 perror_msg("query_module: QM_INFO: %s", mn);
Eric Andersen9f16d612000-06-12 23:11:16 +00002295 return 0;
2296 }
Mark Whitley94fd4802001-03-12 23:08:34 +00002297
2298 syms = xmalloc(bufsize = 1024);
2299 retry_mod_sym_load:
2300 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2301 switch (errno) {
2302 case ENOSPC:
2303 syms = xrealloc(syms, bufsize = ret);
2304 goto retry_mod_sym_load;
2305 case ENOENT:
2306 /* The module was removed out from underneath us. */
2307 continue;
2308 default:
2309 perror_msg("query_module: QM_SYMBOLS: %s", mn);
2310 return 0;
2311 }
2312 }
2313 nsyms = ret;
2314
2315 m->name = mn;
2316 m->addr = info.addr;
2317 m->nsyms = nsyms;
2318 m->syms = syms;
2319
2320 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2321 s->name += (unsigned long) syms;
2322 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002323 }
2324 }
2325
2326 /* Collect the kernel's symbols. */
2327
2328 syms = xmalloc(bufsize = 16 * 1024);
2329 retry_kern_sym_load:
2330 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00002331 if (errno == ENOSPC && bufsize < ret) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002332 syms = xrealloc(syms, bufsize = ret);
2333 goto retry_kern_sym_load;
2334 }
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002335 perror_msg("kernel: QM_SYMBOLS");
Eric Andersen9f16d612000-06-12 23:11:16 +00002336 return 0;
2337 }
2338 nksyms = nsyms = ret;
2339 ksyms = syms;
2340
2341 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2342 s->name += (unsigned long) syms;
2343 }
2344 return 1;
2345}
2346
2347
2348/* Return the kernel symbol checksum version, or zero if not used. */
2349
2350static int new_is_kernel_checksummed(void)
2351{
2352 struct new_module_symbol *s;
2353 size_t i;
2354
2355 /* Using_Versions is not the first symbol, but it should be in there. */
2356
2357 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2358 if (strcmp((char *) s->name, "Using_Versions") == 0)
2359 return s->value;
2360
2361 return 0;
2362}
2363
2364
2365static int new_create_this_module(struct obj_file *f, const char *m_name)
2366{
2367 struct obj_section *sec;
2368
2369 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2370 sizeof(struct new_module));
2371 memset(sec->contents, 0, sizeof(struct new_module));
2372
2373 obj_add_symbol(f, "__this_module", -1,
2374 ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2375 sizeof(struct new_module));
2376
2377 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2378 m_name);
2379
2380 return 1;
2381}
2382
2383
2384static int new_create_module_ksymtab(struct obj_file *f)
2385{
2386 struct obj_section *sec;
2387 int i;
2388
2389 /* We must always add the module references. */
2390
2391 if (n_ext_modules_used) {
2392 struct new_module_ref *dep;
2393 struct obj_symbol *tm;
2394
2395 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2396 (sizeof(struct new_module_ref)
2397 * n_ext_modules_used));
2398 if (!sec)
2399 return 0;
2400
2401 tm = obj_find_symbol(f, "__this_module");
2402 dep = (struct new_module_ref *) sec->contents;
2403 for (i = 0; i < n_ext_modules; ++i)
2404 if (ext_modules[i].used) {
2405 dep->dep = ext_modules[i].addr;
2406 obj_symbol_patch(f, sec->idx,
2407 (char *) &dep->ref - sec->contents, tm);
2408 dep->next_ref = 0;
2409 ++dep;
2410 }
2411 }
2412
2413 if (flag_export && !obj_find_section(f, "__ksymtab")) {
2414 size_t nsyms;
2415 int *loaded;
2416
2417 sec =
2418 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2419 0);
2420
2421 /* We don't want to export symbols residing in sections that
2422 aren't loaded. There are a number of these created so that
2423 we make sure certain module options don't appear twice. */
2424
2425 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2426 while (--i >= 0)
2427 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2428
2429 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2430 struct obj_symbol *sym;
2431 for (sym = f->symtab[i]; sym; sym = sym->next)
2432 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2433 && sym->secidx <= SHN_HIRESERVE
2434 && (sym->secidx >= SHN_LORESERVE
2435 || loaded[sym->secidx])) {
2436 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2437
2438 obj_symbol_patch(f, sec->idx, ofs, sym);
2439 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2440 sym->name);
2441
2442 nsyms++;
2443 }
2444 }
2445
2446 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2447 }
2448
2449 return 1;
2450}
2451
2452
2453static int
2454new_init_module(const char *m_name, struct obj_file *f,
2455 unsigned long m_size)
2456{
2457 struct new_module *module;
2458 struct obj_section *sec;
2459 void *image;
2460 int ret;
2461 tgt_long m_addr;
2462
2463 sec = obj_find_section(f, ".this");
Eric Andersen7f3b86e2001-04-26 19:29:58 +00002464 if (!sec || !sec->contents) {
2465 perror_msg_and_die("corrupt module %s?",m_name);
2466 }
Eric Andersen9f16d612000-06-12 23:11:16 +00002467 module = (struct new_module *) sec->contents;
2468 m_addr = sec->header.sh_addr;
2469
2470 module->size_of_struct = sizeof(*module);
2471 module->size = m_size;
2472 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2473
2474 sec = obj_find_section(f, "__ksymtab");
2475 if (sec && sec->header.sh_size) {
2476 module->syms = sec->header.sh_addr;
2477 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2478 }
2479
2480 if (n_ext_modules_used) {
2481 sec = obj_find_section(f, ".kmodtab");
2482 module->deps = sec->header.sh_addr;
2483 module->ndeps = n_ext_modules_used;
2484 }
2485
2486 module->init =
2487 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2488 module->cleanup =
2489 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2490
2491 sec = obj_find_section(f, "__ex_table");
2492 if (sec) {
2493 module->ex_table_start = sec->header.sh_addr;
2494 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2495 }
2496
2497 sec = obj_find_section(f, ".text.init");
2498 if (sec) {
2499 module->runsize = sec->header.sh_addr - m_addr;
2500 }
2501 sec = obj_find_section(f, ".data.init");
2502 if (sec) {
2503 if (!module->runsize ||
2504 module->runsize > sec->header.sh_addr - m_addr)
2505 module->runsize = sec->header.sh_addr - m_addr;
2506 }
2507
2508 if (!arch_init_module(f, module))
2509 return 0;
2510
2511 /* Whew! All of the initialization is complete. Collect the final
2512 module image and give it to the kernel. */
2513
2514 image = xmalloc(m_size);
2515 obj_create_image(f, image);
2516
Eric Andersen64c8b172001-04-05 07:33:10 +00002517 ret = new_sys_init_module(m_name, (struct new_module *) image);
Eric Andersen9f16d612000-06-12 23:11:16 +00002518 if (ret)
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002519 perror_msg("init_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002520
2521 free(image);
2522
2523 return ret == 0;
2524}
2525
2526#else
2527
2528#define new_init_module(x, y, z) TRUE
2529#define new_create_this_module(x, y) 0
2530#define new_create_module_ksymtab(x)
Eric Andersen21adca72000-12-06 18:18:26 +00002531#define query_module(v, w, x, y, z) -1
Eric Andersen9f16d612000-06-12 23:11:16 +00002532
Eric Andersenf5d5e772001-01-24 23:34:48 +00002533#endif /* BB_FEATURE_NEW_MODULE_INTERFACE */
Eric Andersen9f16d612000-06-12 23:11:16 +00002534
2535
2536/*======================================================================*/
2537
2538int
2539obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2540 const char *string)
2541{
2542 struct obj_string_patch *p;
2543 struct obj_section *strsec;
2544 size_t len = strlen(string) + 1;
2545 char *loc;
2546
2547 p = xmalloc(sizeof(*p));
2548 p->next = f->string_patches;
2549 p->reloc_secidx = secidx;
2550 p->reloc_offset = offset;
2551 f->string_patches = p;
2552
2553 strsec = obj_find_section(f, ".kstrtab");
2554 if (strsec == NULL) {
2555 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2556 p->string_offset = 0;
2557 loc = strsec->contents;
2558 } else {
2559 p->string_offset = strsec->header.sh_size;
2560 loc = obj_extend_section(strsec, len);
2561 }
2562 memcpy(loc, string, len);
2563
2564 return 1;
2565}
2566
2567int
2568obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2569 struct obj_symbol *sym)
2570{
2571 struct obj_symbol_patch *p;
2572
2573 p = xmalloc(sizeof(*p));
2574 p->next = f->symbol_patches;
2575 p->reloc_secidx = secidx;
2576 p->reloc_offset = offset;
2577 p->sym = sym;
2578 f->symbol_patches = p;
2579
2580 return 1;
2581}
2582
2583int obj_check_undefineds(struct obj_file *f)
2584{
2585 unsigned long i;
2586 int ret = 1;
2587
2588 for (i = 0; i < HASH_BUCKETS; ++i) {
2589 struct obj_symbol *sym;
2590 for (sym = f->symtab[i]; sym; sym = sym->next)
2591 if (sym->secidx == SHN_UNDEF) {
2592 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2593 sym->secidx = SHN_ABS;
2594 sym->value = 0;
2595 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002596 error_msg("unresolved symbol %s", sym->name);
Eric Andersen9f16d612000-06-12 23:11:16 +00002597 ret = 0;
2598 }
2599 }
2600 }
2601
2602 return ret;
2603}
2604
2605void obj_allocate_commons(struct obj_file *f)
2606{
2607 struct common_entry {
2608 struct common_entry *next;
2609 struct obj_symbol *sym;
2610 } *common_head = NULL;
2611
2612 unsigned long i;
2613
2614 for (i = 0; i < HASH_BUCKETS; ++i) {
2615 struct obj_symbol *sym;
2616 for (sym = f->symtab[i]; sym; sym = sym->next)
2617 if (sym->secidx == SHN_COMMON) {
2618 /* Collect all COMMON symbols and sort them by size so as to
2619 minimize space wasted by alignment requirements. */
2620 {
2621 struct common_entry **p, *n;
2622 for (p = &common_head; *p; p = &(*p)->next)
2623 if (sym->size <= (*p)->sym->size)
2624 break;
2625
2626 n = alloca(sizeof(*n));
2627 n->next = *p;
2628 n->sym = sym;
2629 *p = n;
2630 }
2631 }
2632 }
2633
2634 for (i = 1; i < f->local_symtab_size; ++i) {
2635 struct obj_symbol *sym = f->local_symtab[i];
2636 if (sym && sym->secidx == SHN_COMMON) {
2637 struct common_entry **p, *n;
2638 for (p = &common_head; *p; p = &(*p)->next)
2639 if (sym == (*p)->sym)
2640 break;
2641 else if (sym->size < (*p)->sym->size) {
2642 n = alloca(sizeof(*n));
2643 n->next = *p;
2644 n->sym = sym;
2645 *p = n;
2646 break;
2647 }
2648 }
2649 }
2650
2651 if (common_head) {
2652 /* Find the bss section. */
2653 for (i = 0; i < f->header.e_shnum; ++i)
2654 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2655 break;
2656
2657 /* If for some reason there hadn't been one, create one. */
2658 if (i == f->header.e_shnum) {
2659 struct obj_section *sec;
2660
2661 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2662 f->sections[i] = sec = arch_new_section();
2663 f->header.e_shnum = i + 1;
2664
2665 memset(sec, 0, sizeof(*sec));
2666 sec->header.sh_type = SHT_PROGBITS;
2667 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2668 sec->name = ".bss";
2669 sec->idx = i;
2670 }
2671
2672 /* Allocate the COMMONS. */
2673 {
2674 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2675 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2676 struct common_entry *c;
2677
2678 for (c = common_head; c; c = c->next) {
2679 ElfW(Addr) align = c->sym->value;
2680
2681 if (align > max_align)
2682 max_align = align;
2683 if (bss_size & (align - 1))
2684 bss_size = (bss_size | (align - 1)) + 1;
2685
2686 c->sym->secidx = i;
2687 c->sym->value = bss_size;
2688
2689 bss_size += c->sym->size;
2690 }
2691
2692 f->sections[i]->header.sh_size = bss_size;
2693 f->sections[i]->header.sh_addralign = max_align;
2694 }
2695 }
2696
2697 /* For the sake of patch relocation and parameter initialization,
2698 allocate zeroed data for NOBITS sections now. Note that after
2699 this we cannot assume NOBITS are really empty. */
2700 for (i = 0; i < f->header.e_shnum; ++i) {
2701 struct obj_section *s = f->sections[i];
2702 if (s->header.sh_type == SHT_NOBITS) {
Eric Andersen21adca72000-12-06 18:18:26 +00002703 if (s->header.sh_size != 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002704 s->contents = memset(xmalloc(s->header.sh_size),
2705 0, s->header.sh_size);
Eric Andersen21adca72000-12-06 18:18:26 +00002706 else
2707 s->contents = NULL;
2708
Eric Andersen9f16d612000-06-12 23:11:16 +00002709 s->header.sh_type = SHT_PROGBITS;
2710 }
2711 }
2712}
2713
2714unsigned long obj_load_size(struct obj_file *f)
2715{
2716 unsigned long dot = 0;
2717 struct obj_section *sec;
2718
2719 /* Finalize the positions of the sections relative to one another. */
2720
2721 for (sec = f->load_order; sec; sec = sec->load_next) {
2722 ElfW(Addr) align;
2723
2724 align = sec->header.sh_addralign;
2725 if (align && (dot & (align - 1)))
2726 dot = (dot | (align - 1)) + 1;
2727
2728 sec->header.sh_addr = dot;
2729 dot += sec->header.sh_size;
2730 }
2731
2732 return dot;
2733}
2734
2735int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2736{
2737 int i, n = f->header.e_shnum;
2738 int ret = 1;
2739
2740 /* Finalize the addresses of the sections. */
2741
2742 f->baseaddr = base;
2743 for (i = 0; i < n; ++i)
2744 f->sections[i]->header.sh_addr += base;
2745
2746 /* And iterate over all of the relocations. */
2747
2748 for (i = 0; i < n; ++i) {
2749 struct obj_section *relsec, *symsec, *targsec, *strsec;
2750 ElfW(RelM) * rel, *relend;
2751 ElfW(Sym) * symtab;
2752 const char *strtab;
2753
2754 relsec = f->sections[i];
2755 if (relsec->header.sh_type != SHT_RELM)
2756 continue;
2757
2758 symsec = f->sections[relsec->header.sh_link];
2759 targsec = f->sections[relsec->header.sh_info];
2760 strsec = f->sections[symsec->header.sh_link];
2761
2762 rel = (ElfW(RelM) *) relsec->contents;
2763 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2764 symtab = (ElfW(Sym) *) symsec->contents;
2765 strtab = (const char *) strsec->contents;
2766
2767 for (; rel < relend; ++rel) {
2768 ElfW(Addr) value = 0;
2769 struct obj_symbol *intsym = NULL;
2770 unsigned long symndx;
2771 ElfW(Sym) * extsym = 0;
2772 const char *errmsg;
2773
2774 /* Attempt to find a value to use for this relocation. */
2775
2776 symndx = ELFW(R_SYM) (rel->r_info);
2777 if (symndx) {
2778 /* Note we've already checked for undefined symbols. */
2779
2780 extsym = &symtab[symndx];
2781 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2782 /* Local symbols we look up in the local table to be sure
2783 we get the one that is really intended. */
2784 intsym = f->local_symtab[symndx];
2785 } else {
2786 /* Others we look up in the hash table. */
2787 const char *name;
2788 if (extsym->st_name)
2789 name = strtab + extsym->st_name;
2790 else
2791 name = f->sections[extsym->st_shndx]->name;
2792 intsym = obj_find_symbol(f, name);
2793 }
2794
2795 value = obj_symbol_final_value(f, intsym);
2796 intsym->referenced = 1;
2797 }
2798#if SHT_RELM == SHT_RELA
2799#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2800 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
2801 if (!extsym || !extsym->st_name ||
2802 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2803#endif
2804 value += rel->r_addend;
2805#endif
2806
2807 /* Do it! */
2808 switch (arch_apply_relocation
2809 (f, targsec, symsec, intsym, rel, value)) {
2810 case obj_reloc_ok:
2811 break;
2812
2813 case obj_reloc_overflow:
2814 errmsg = "Relocation overflow";
2815 goto bad_reloc;
2816 case obj_reloc_dangerous:
2817 errmsg = "Dangerous relocation";
2818 goto bad_reloc;
2819 case obj_reloc_unhandled:
2820 errmsg = "Unhandled relocation";
2821 bad_reloc:
2822 if (extsym) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002823 error_msg("%s of type %ld for %s", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002824 (long) ELFW(R_TYPE) (rel->r_info),
2825 strtab + extsym->st_name);
2826 } else {
Matt Kraaidd19c692001-01-31 19:00:21 +00002827 error_msg("%s of type %ld", errmsg,
Eric Andersen9f16d612000-06-12 23:11:16 +00002828 (long) ELFW(R_TYPE) (rel->r_info));
2829 }
2830 ret = 0;
2831 break;
2832 }
2833 }
2834 }
2835
2836 /* Finally, take care of the patches. */
2837
2838 if (f->string_patches) {
2839 struct obj_string_patch *p;
2840 struct obj_section *strsec;
2841 ElfW(Addr) strsec_base;
2842 strsec = obj_find_section(f, ".kstrtab");
2843 strsec_base = strsec->header.sh_addr;
2844
2845 for (p = f->string_patches; p; p = p->next) {
2846 struct obj_section *targsec = f->sections[p->reloc_secidx];
2847 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2848 = strsec_base + p->string_offset;
2849 }
2850 }
2851
2852 if (f->symbol_patches) {
2853 struct obj_symbol_patch *p;
2854
2855 for (p = f->symbol_patches; p; p = p->next) {
2856 struct obj_section *targsec = f->sections[p->reloc_secidx];
2857 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2858 = obj_symbol_final_value(f, p->sym);
2859 }
2860 }
2861
2862 return ret;
2863}
2864
2865int obj_create_image(struct obj_file *f, char *image)
2866{
2867 struct obj_section *sec;
2868 ElfW(Addr) base = f->baseaddr;
2869
2870 for (sec = f->load_order; sec; sec = sec->load_next) {
2871 char *secimg;
2872
Eric Andersen2bf658d2001-02-24 20:01:53 +00002873 if (sec->contents == 0 || sec->header.sh_size == 0)
Eric Andersen9f16d612000-06-12 23:11:16 +00002874 continue;
2875
2876 secimg = image + (sec->header.sh_addr - base);
2877
2878 /* Note that we allocated data for NOBITS sections earlier. */
2879 memcpy(secimg, sec->contents, sec->header.sh_size);
2880 }
2881
2882 return 1;
2883}
2884
2885/*======================================================================*/
2886
2887struct obj_file *obj_load(FILE * fp)
2888{
2889 struct obj_file *f;
2890 ElfW(Shdr) * section_headers;
2891 int shnum, i;
2892 char *shstrtab;
2893
2894 /* Read the file header. */
2895
2896 f = arch_new_file();
2897 memset(f, 0, sizeof(*f));
2898 f->symbol_cmp = strcmp;
2899 f->symbol_hash = obj_elf_hash;
2900 f->load_order_search_start = &f->load_order;
2901
2902 fseek(fp, 0, SEEK_SET);
2903 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002904 perror_msg("error reading ELF header");
Eric Andersen9f16d612000-06-12 23:11:16 +00002905 return NULL;
2906 }
2907
2908 if (f->header.e_ident[EI_MAG0] != ELFMAG0
2909 || f->header.e_ident[EI_MAG1] != ELFMAG1
2910 || f->header.e_ident[EI_MAG2] != ELFMAG2
2911 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002912 error_msg("not an ELF file");
Eric Andersen9f16d612000-06-12 23:11:16 +00002913 return NULL;
2914 }
2915 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2916 || f->header.e_ident[EI_DATA] != ELFDATAM
2917 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2918 || !MATCH_MACHINE(f->header.e_machine)) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002919 error_msg("ELF file not for this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002920 return NULL;
2921 }
2922 if (f->header.e_type != ET_REL) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002923 error_msg("ELF file not a relocatable object");
Eric Andersen9f16d612000-06-12 23:11:16 +00002924 return NULL;
2925 }
2926
2927 /* Read the section headers. */
2928
2929 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00002930 error_msg("section header size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00002931 (unsigned long) f->header.e_shentsize,
2932 (unsigned long) sizeof(ElfW(Shdr)));
2933 return NULL;
2934 }
2935
2936 shnum = f->header.e_shnum;
2937 f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2938 memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2939
2940 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2941 fseek(fp, f->header.e_shoff, SEEK_SET);
2942 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002943 perror_msg("error reading ELF section headers");
Eric Andersen9f16d612000-06-12 23:11:16 +00002944 return NULL;
2945 }
2946
2947 /* Read the section data. */
2948
2949 for (i = 0; i < shnum; ++i) {
2950 struct obj_section *sec;
2951
2952 f->sections[i] = sec = arch_new_section();
2953 memset(sec, 0, sizeof(*sec));
2954
2955 sec->header = section_headers[i];
2956 sec->idx = i;
2957
Eric Andersen2bf658d2001-02-24 20:01:53 +00002958 if(sec->header.sh_size) switch (sec->header.sh_type) {
Eric Andersen9f16d612000-06-12 23:11:16 +00002959 case SHT_NULL:
2960 case SHT_NOTE:
2961 case SHT_NOBITS:
2962 /* ignore */
2963 break;
2964
2965 case SHT_PROGBITS:
2966 case SHT_SYMTAB:
2967 case SHT_STRTAB:
2968 case SHT_RELM:
2969 if (sec->header.sh_size > 0) {
2970 sec->contents = xmalloc(sec->header.sh_size);
2971 fseek(fp, sec->header.sh_offset, SEEK_SET);
2972 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
Matt Kraai1fa1ade2000-12-18 03:57:16 +00002973 perror_msg("error reading ELF section data");
Eric Andersen9f16d612000-06-12 23:11:16 +00002974 return NULL;
2975 }
2976 } else {
2977 sec->contents = NULL;
2978 }
2979 break;
2980
2981#if SHT_RELM == SHT_REL
2982 case SHT_RELA:
Matt Kraaidd19c692001-01-31 19:00:21 +00002983 error_msg("RELA relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002984 return NULL;
2985#else
2986 case SHT_REL:
Matt Kraaidd19c692001-01-31 19:00:21 +00002987 error_msg("REL relocations not supported on this architecture");
Eric Andersen9f16d612000-06-12 23:11:16 +00002988 return NULL;
2989#endif
2990
2991 default:
2992 if (sec->header.sh_type >= SHT_LOPROC) {
2993 /* Assume processor specific section types are debug
2994 info and can safely be ignored. If this is ever not
2995 the case (Hello MIPS?), don't put ifdefs here but
2996 create an arch_load_proc_section(). */
2997 break;
2998 }
2999
Matt Kraaidd19c692001-01-31 19:00:21 +00003000 error_msg("can't handle sections of type %ld",
Eric Andersen9f16d612000-06-12 23:11:16 +00003001 (long) sec->header.sh_type);
3002 return NULL;
3003 }
3004 }
3005
3006 /* Do what sort of interpretation as needed by each section. */
3007
3008 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3009
3010 for (i = 0; i < shnum; ++i) {
3011 struct obj_section *sec = f->sections[i];
3012 sec->name = shstrtab + sec->header.sh_name;
3013 }
3014
3015 for (i = 0; i < shnum; ++i) {
3016 struct obj_section *sec = f->sections[i];
3017
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003018 /* .modinfo should be contents only but gcc has no attribute for that.
3019 * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3020 */
3021 if (strcmp(sec->name, ".modinfo") == 0)
3022 sec->header.sh_flags &= ~SHF_ALLOC;
3023
Eric Andersen9f16d612000-06-12 23:11:16 +00003024 if (sec->header.sh_flags & SHF_ALLOC)
3025 obj_insert_section_load_order(f, sec);
3026
3027 switch (sec->header.sh_type) {
3028 case SHT_SYMTAB:
3029 {
3030 unsigned long nsym, j;
3031 char *strtab;
3032 ElfW(Sym) * sym;
3033
3034 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003035 error_msg("symbol size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003036 (unsigned long) sec->header.sh_entsize,
3037 (unsigned long) sizeof(ElfW(Sym)));
3038 return NULL;
3039 }
3040
3041 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3042 strtab = f->sections[sec->header.sh_link]->contents;
3043 sym = (ElfW(Sym) *) sec->contents;
3044
3045 /* Allocate space for a table of local symbols. */
3046 j = f->local_symtab_size = sec->header.sh_info;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003047 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
Eric Andersen9f16d612000-06-12 23:11:16 +00003048
3049 /* Insert all symbols into the hash table. */
3050 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3051 const char *name;
3052 if (sym->st_name)
3053 name = strtab + sym->st_name;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003054 else
Eric Andersen9f16d612000-06-12 23:11:16 +00003055 name = f->sections[sym->st_shndx]->name;
3056
3057 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3058 sym->st_value, sym->st_size);
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003059 }
3060 }
Eric Andersen9f16d612000-06-12 23:11:16 +00003061 break;
3062
3063 case SHT_RELM:
3064 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
Matt Kraaidd19c692001-01-31 19:00:21 +00003065 error_msg("relocation entry size mismatch: %lu != %lu",
Eric Andersen9f16d612000-06-12 23:11:16 +00003066 (unsigned long) sec->header.sh_entsize,
3067 (unsigned long) sizeof(ElfW(RelM)));
3068 return NULL;
3069 }
3070 break;
Eric Andersen4f4bcfc2001-04-25 17:22:32 +00003071 /* XXX Relocation code from modutils-2.3.19 is not here.
3072 * Why? That's about 20 lines of code from obj/obj_load.c,
3073 * which gets done in a second pass through the sections.
3074 * This BusyBox insmod does similar work in obj_relocate(). */
Eric Andersen9f16d612000-06-12 23:11:16 +00003075 }
3076 }
3077
3078 return f;
3079}
3080
3081static void hide_special_symbols(struct obj_file *f)
3082{
3083 static const char *const specials[] = {
3084 "cleanup_module",
3085 "init_module",
3086 "kernel_version",
3087 NULL
3088 };
3089
3090 struct obj_symbol *sym;
3091 const char *const *p;
3092
3093 for (p = specials; *p; ++p)
3094 if ((sym = obj_find_symbol(f, *p)) != NULL)
3095 sym->info =
3096 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3097}
3098
3099
3100
3101extern int insmod_main( int argc, char **argv)
3102{
Eric Andersena18aaf12001-01-24 19:07:09 +00003103 int opt;
Eric Andersen9f16d612000-06-12 23:11:16 +00003104 int k_crcs;
3105 int k_new_syscalls;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003106 int len;
3107 char *tmp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003108 unsigned long m_size;
3109 ElfW(Addr) m_addr;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003110 FILE *fp;
Eric Andersen9f16d612000-06-12 23:11:16 +00003111 struct obj_file *f;
Eric Andersen02b9f422001-02-15 19:07:43 +00003112 struct stat st;
Eric Andersen14d35432001-05-14 17:07:32 +00003113 char m_name[FILENAME_MAX + 1] = "\0";
Matt Kraai3e856ce2000-12-01 02:55:13 +00003114 int exit_status = EXIT_FAILURE;
Eric Andersen9f16d612000-06-12 23:11:16 +00003115 int m_has_modinfo;
3116#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3117 int k_version;
3118 char k_strversion[STRVERSIONLEN];
3119 char m_strversion[STRVERSIONLEN];
3120 int m_version;
3121 int m_crcs;
3122#endif
3123
Erik Andersene49d5ec2000-02-08 19:58:47 +00003124 /* Parse any options */
Eric Andersen155c89b2001-01-25 04:11:06 +00003125 while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
Eric Andersena18aaf12001-01-24 19:07:09 +00003126 switch (opt) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003127 case 'f': /* force loading */
3128 flag_force_load = 1;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003129 break;
Eric Andersen9f16d612000-06-12 23:11:16 +00003130 case 'k': /* module loaded by kerneld, auto-cleanable */
3131 flag_autoclean = 1;
3132 break;
3133 case 'v': /* verbose output */
3134 flag_verbose = 1;
3135 break;
3136 case 'x': /* do not export externs */
3137 flag_export = 0;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003138 break;
Eric Andersen155c89b2001-01-25 04:11:06 +00003139 case 'o': /* name the output module */
Eric Andersen14d35432001-05-14 17:07:32 +00003140 strncpy(m_name, optarg, FILENAME_MAX);
Eric Andersen155c89b2001-01-25 04:11:06 +00003141 break;
Eric Andersena18aaf12001-01-24 19:07:09 +00003142 case 'L': /* Stub warning */
3143 /* This is needed for compatibility with modprobe.
3144 * In theory, this does locking, but we don't do
3145 * that. So be careful and plan your life around not
3146 * loading the same module 50 times concurrently. */
3147 break;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003148 default:
Eric Andersen67991cf2001-02-14 21:23:06 +00003149 show_usage();
Erik Andersene49d5ec2000-02-08 19:58:47 +00003150 }
Erik Andersend387d011999-12-21 02:55:11 +00003151 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003152
3153 if (argv[optind] == NULL) {
Eric Andersen67991cf2001-02-14 21:23:06 +00003154 show_usage();
Eric Andersen9f16d612000-06-12 23:11:16 +00003155 }
Eric Andersena18aaf12001-01-24 19:07:09 +00003156
Erik Andersene49d5ec2000-02-08 19:58:47 +00003157 /* Grab the module name */
Eric Andersena18aaf12001-01-24 19:07:09 +00003158 if ((tmp = strrchr(argv[optind], '/')) != NULL) {
Erik Andersene49d5ec2000-02-08 19:58:47 +00003159 tmp++;
Eric Andersen9f16d612000-06-12 23:11:16 +00003160 } else {
Eric Andersena18aaf12001-01-24 19:07:09 +00003161 tmp = argv[optind];
Eric Andersen9f16d612000-06-12 23:11:16 +00003162 }
Erik Andersene49d5ec2000-02-08 19:58:47 +00003163 len = strlen(tmp);
3164
3165 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3166 len -= 2;
Eric Andersenf2278152001-04-24 21:41:41 +00003167 memcpy(m_fullName, tmp, len);
3168 m_fullName[len]='\0';
Eric Andersen114ad9c2001-01-26 01:52:14 +00003169 if (*m_name == '\0') {
3170 strcpy(m_name, m_fullName);
Eric Andersen155c89b2001-01-25 04:11:06 +00003171 }
Eric Andersen114ad9c2001-01-26 01:52:14 +00003172 strcat(m_fullName, ".o");
Erik Andersene49d5ec2000-02-08 19:58:47 +00003173
Eric Andersen14d35432001-05-14 17:07:32 +00003174 /* Get a filedesc for the module. Check we we have a complete path */
Eric Andersen02b9f422001-02-15 19:07:43 +00003175 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3176 (fp = fopen(argv[optind], "r")) == NULL) {
Eric Andersen14d35432001-05-14 17:07:32 +00003177 struct utsname myuname;
3178
3179 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`,
3180 * but do not error out yet if we fail to find it... */
3181 if (uname(&myuname) == 0) {
3182 char module_dir[FILENAME_MAX];
3183 snprintf (module_dir, sizeof(module_dir), "%s/%s",
3184 _PATH_MODULES, myuname.release);
3185 recursive_action(module_dir, TRUE, FALSE, FALSE,
3186 check_module_name_match, 0, m_fullName);
3187 }
3188
3189 /* Check if we have found anything yet */
3190 if (m_filename[0] == '\0' || ((fp = fopen(m_filename, "r")) == NULL))
Eric Andersen9f16d612000-06-12 23:11:16 +00003191 {
Eric Andersen14d35432001-05-14 17:07:32 +00003192 /* No module found under /lib/modules/`uname -r`, this
3193 * time cast the net a bit wider. Search /lib/modules/ */
3194 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
3195 check_module_name_match, 0, m_fullName) == FALSE)
Eric Andersen9f16d612000-06-12 23:11:16 +00003196 {
Eric Andersen14d35432001-05-14 17:07:32 +00003197 if (m_filename[0] == '\0'
3198 || ((fp = fopen(m_filename, "r")) == NULL))
3199 {
3200 error_msg("%s: no module by that name found", m_fullName);
3201 return EXIT_FAILURE;
3202 }
3203 } else
3204 error_msg_and_die("%s: no module by that name found", m_fullName);
3205 }
3206 } else
Eric Andersenf2278152001-04-24 21:41:41 +00003207 safe_strncpy(m_filename, argv[optind], sizeof(m_filename));
Erik Andersend387d011999-12-21 02:55:11 +00003208
Eric Andersen14d35432001-05-14 17:07:32 +00003209 printf("Using %s\n", m_filename);
Erik Andersend387d011999-12-21 02:55:11 +00003210
Matt Kraaia9819b22000-12-22 01:48:07 +00003211 if ((f = obj_load(fp)) == NULL)
3212 perror_msg_and_die("Could not load the module");
Erik Andersend387d011999-12-21 02:55:11 +00003213
Eric Andersen9f16d612000-06-12 23:11:16 +00003214 if (get_modinfo_value(f, "kernel_version") == NULL)
3215 m_has_modinfo = 0;
3216 else
3217 m_has_modinfo = 1;
3218
3219#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3220 /* Version correspondence? */
3221
3222 k_version = get_kernel_version(k_strversion);
3223 if (m_has_modinfo) {
3224 m_version = new_get_module_version(f, m_strversion);
3225 } else {
3226 m_version = old_get_module_version(f, m_strversion);
3227 if (m_version == -1) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003228 error_msg("couldn't find the kernel version the module was "
Matt Kraaidd19c692001-01-31 19:00:21 +00003229 "compiled for");
Eric Andersen9f16d612000-06-12 23:11:16 +00003230 goto out;
3231 }
3232 }
3233
3234 if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3235 if (flag_force_load) {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003236 error_msg("Warning: kernel-module version mismatch\n"
Eric Andersen9f16d612000-06-12 23:11:16 +00003237 "\t%s was compiled for kernel version %s\n"
Matt Kraaidd19c692001-01-31 19:00:21 +00003238 "\twhile this kernel is version %s",
Eric Andersen9f16d612000-06-12 23:11:16 +00003239 m_filename, m_strversion, k_strversion);
3240 } else {
Mark Whitleyf57c9442000-12-07 19:56:48 +00003241 error_msg("kernel-module version mismatch\n"
Eric Andersen9f16d612000-06-12 23:11:16 +00003242 "\t%s was compiled for kernel version %s\n"
Matt Kraaidd19c692001-01-31 19:00:21 +00003243 "\twhile this kernel is version %s.",
Eric Andersen9f16d612000-06-12 23:11:16 +00003244 m_filename, m_strversion, k_strversion);
3245 goto out;
3246 }
3247 }
3248 k_crcs = 0;
3249#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3250
3251 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3252
3253 if (k_new_syscalls) {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003254#ifdef BB_FEATURE_NEW_MODULE_INTERFACE
Eric Andersen9f16d612000-06-12 23:11:16 +00003255 if (!new_get_kernel_symbols())
3256 goto out;
3257 k_crcs = new_is_kernel_checksummed();
3258#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003259 error_msg("Not configured to support new kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003260 goto out;
3261#endif
3262 } else {
Eric Andersenf5d5e772001-01-24 23:34:48 +00003263#ifdef BB_FEATURE_OLD_MODULE_INTERFACE
Eric Andersen8c185f92000-09-22 00:38:07 +00003264 if (!old_get_kernel_symbols(m_name))
Eric Andersen9f16d612000-06-12 23:11:16 +00003265 goto out;
3266 k_crcs = old_is_kernel_checksummed();
3267#else
Matt Kraaidd19c692001-01-31 19:00:21 +00003268 error_msg("Not configured to support old kernels");
Eric Andersen9f16d612000-06-12 23:11:16 +00003269 goto out;
3270#endif
3271 }
3272
3273#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3274 if (m_has_modinfo)
3275 m_crcs = new_is_module_checksummed(f);
3276 else
3277 m_crcs = old_is_module_checksummed(f);
3278
3279 if (m_crcs != k_crcs)
3280 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3281#endif /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3282
Erik Andersene49d5ec2000-02-08 19:58:47 +00003283 /* Let the module know about the kernel symbols. */
3284 add_kernel_symbols(f);
3285
Eric Andersen9f16d612000-06-12 23:11:16 +00003286 /* Allocate common symbols, symbol tables, and string tables. */
3287
3288 if (k_new_syscalls
3289 ? !new_create_this_module(f, m_name)
3290 : !old_create_mod_use_count(f))
3291 {
3292 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003293 }
3294
Eric Andersen9f16d612000-06-12 23:11:16 +00003295 if (!obj_check_undefineds(f)) {
3296 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003297 }
3298 obj_allocate_commons(f);
3299
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003300 /* done with the module name, on to the optional var=value arguments */
3301 ++optind;
3302
Eric Andersen9f16d612000-06-12 23:11:16 +00003303 if (optind < argc) {
3304 if (m_has_modinfo
3305 ? !new_process_module_arguments(f, argc - optind, argv + optind)
3306 : !old_process_module_arguments(f, argc - optind, argv + optind))
3307 {
3308 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003309 }
3310 }
3311
Eric Andersen9f16d612000-06-12 23:11:16 +00003312 arch_create_got(f);
3313 hide_special_symbols(f);
3314
3315 if (k_new_syscalls)
3316 new_create_module_ksymtab(f);
3317
Erik Andersene49d5ec2000-02-08 19:58:47 +00003318 /* Find current size of the module */
3319 m_size = obj_load_size(f);
Erik Andersend387d011999-12-21 02:55:11 +00003320
3321
Erik Andersene49d5ec2000-02-08 19:58:47 +00003322 m_addr = create_module(m_name, m_size);
Eric Andersen86f3d5b2001-01-24 23:59:50 +00003323 if (m_addr==-1) switch (errno) {
Eric Andersen9f16d612000-06-12 23:11:16 +00003324 case EEXIST:
Matt Kraaidd19c692001-01-31 19:00:21 +00003325 error_msg("A module named %s already exists", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003326 goto out;
3327 case ENOMEM:
Matt Kraaidd19c692001-01-31 19:00:21 +00003328 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
Eric Andersen9f16d612000-06-12 23:11:16 +00003329 m_size);
3330 goto out;
Erik Andersend387d011999-12-21 02:55:11 +00003331 default:
Matt Kraai1fa1ade2000-12-18 03:57:16 +00003332 perror_msg("create_module: %s", m_name);
Eric Andersen9f16d612000-06-12 23:11:16 +00003333 goto out;
Erik Andersene49d5ec2000-02-08 19:58:47 +00003334 }
Erik Andersend387d011999-12-21 02:55:11 +00003335
Eric Andersen9f16d612000-06-12 23:11:16 +00003336 if (!obj_relocate(f, m_addr)) {
3337 delete_module(m_name);
3338 goto out;
3339 }
Erik Andersend387d011999-12-21 02:55:11 +00003340
Eric Andersen9f16d612000-06-12 23:11:16 +00003341 if (k_new_syscalls
3342 ? !new_init_module(m_name, f, m_size)
3343 : !old_init_module(m_name, f, m_size))
3344 {
3345 delete_module(m_name);
3346 goto out;
3347 }
3348
Matt Kraai3e856ce2000-12-01 02:55:13 +00003349 exit_status = EXIT_SUCCESS;
Eric Andersen9f16d612000-06-12 23:11:16 +00003350
3351out:
Erik Andersene49d5ec2000-02-08 19:58:47 +00003352 fclose(fp);
Eric Andersenbb245ba2000-06-19 19:53:30 +00003353 return(exit_status);
Erik Andersen02104321999-12-17 18:57:34 +00003354}