libbb.h now includes ../busybox.h. This way, files in libbb that have
[oweals/busybox.git] / insmod.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini insmod implementation for busybox
4  * This version of insmod now supports x86, ARM, SH3/4, powerpc, and MIPS.
5  *
6  * Copyright (C) 1999,2000,2001 by Lineo, inc.
7  * Written by Erik Andersen <andersen@lineo.com>
8  * and Ron Alder <alder@lineo.com>
9  *
10  * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
11  * 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.
17  *
18  * 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  *
24  * 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  *
30  * 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
36  *
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
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <stddef.h>
56 #include <errno.h>
57 #include <unistd.h>
58 #include <dirent.h>
59 #include <ctype.h>
60 #include <assert.h>
61 #include <string.h>
62 #include <getopt.h>
63 #include <sys/utsname.h>
64 #include "busybox.h"
65
66 #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
72 #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
94 #if defined(__mips__)
95 // neither used
96 #endif
97
98 //----------------------------------------------------------------------------
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
125 static const int MODUTILS_MODULE_H = 1;
126
127 #ident "$Id: insmod.c,v 1.59 2001/04/25 17:22:32 andersen Exp $"
128
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).  */
138 struct old_kernel_sym
139 {
140   unsigned long value;
141   char name[60];
142 };
143
144 struct old_module_ref
145 {
146   unsigned long module;         /* kernel addresses */
147   unsigned long next;
148 };
149
150 struct old_module_symbol
151 {
152   unsigned long addr;
153   unsigned long name;
154 };
155
156 struct 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
165 struct old_mod_routines
166 {
167   unsigned long init;
168   unsigned long cleanup;
169 };
170
171 struct 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.  */
184 static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */
185
186 int get_kernel_syms(struct old_kernel_sym *);
187 int 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
207 static const int tgt_sizeof_long = 8;
208 static const int tgt_sizeof_char_p = 8;
209 static const int tgt_sizeof_void_p = 8;
210 #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 */
217 struct new_module_symbol
218 {
219   unsigned long value;
220   unsigned long name;
221 };
222
223 struct new_module_persist;
224
225 struct new_module_ref
226 {
227   unsigned tgt_long dep;                /* kernel addresses */
228   unsigned tgt_long ref;
229   unsigned tgt_long next_ref;
230 };
231
232 struct 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
262 struct 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.  */
271 static const int NEW_MOD_RUNNING = 1;
272 static const int NEW_MOD_DELETED = 2;
273 static const int NEW_MOD_AUTOCLEAN = 4;
274 static const int NEW_MOD_VISITED = 8;
275 static const int NEW_MOD_USED_ONCE = 16;
276
277 int new_sys_init_module(const char *name, const struct new_module *);
278 int 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
283 static const int QM_MODULES = 1;
284 static const int QM_DEPS = 2;
285 static const int QM_REFS = 3;
286 static const int QM_SYMBOLS = 4;
287 static const int QM_INFO = 5;
288
289 /*======================================================================*/
290 /* The system calls unchanged between 2.0 and 2.1.  */
291
292 unsigned long create_module(const char *, size_t);
293 int 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
331 static const int MODUTILS_OBJ_H = 1;
332
333 #ident "$Id: insmod.c,v 1.59 2001/04/25 17:22:32 andersen Exp $"
334
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
343 /* 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
356 #define ELFCLASSM       ELFCLASS32
357
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
363 #define ELFDATAM        ELFDATA2LSB
364
365 #elif defined(__arm__)
366
367 #define MATCH_MACHINE(x) (x == EM_ARM)
368 #define SHT_RELM        SHT_REL
369 #define Elf32_RelM      Elf32_Rel
370 #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
378
379 #elif defined(__mips__)
380
381 /* 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
390 #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
400 #elif defined(__i386__)
401
402 /* presumably we can use these for anything but the SH and ARM*/
403 /* this is the previous behavior, but it does result in
404    insmod.c being broken on anything except i386 */
405 #ifndef EM_486
406 #define MATCH_MACHINE(x)  (x == EM_386)
407 #else
408 #define MATCH_MACHINE(x)  (x == EM_386 || x == EM_486)
409 #endif
410
411 #define SHT_RELM        SHT_REL
412 #define Elf32_RelM      Elf32_Rel
413 #define ELFDATAM        ELFDATA2LSB
414
415 #else
416 #error Sorry, but insmod.c does not yet support this architecture...
417 #endif
418
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
438 struct obj_string_patch;
439 struct obj_symbol_patch;
440
441 struct 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
450 struct 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
468 struct 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
484 enum obj_reloc
485 {
486   obj_reloc_ok,
487   obj_reloc_overflow,
488   obj_reloc_dangerous,
489   obj_reloc_unhandled
490 };
491
492 struct 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
500 struct 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
511 unsigned long obj_elf_hash(const char *);
512
513 unsigned long obj_elf_hash_n(const char *, unsigned long len);
514
515 struct 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
519 struct obj_symbol *obj_find_symbol (struct obj_file *f,
520                                          const char *name);
521
522 ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
523                                   struct obj_symbol *sym);
524
525 void obj_set_symbol_compare(struct obj_file *f,
526                             int (*cmp)(const char *, const char *),
527                             unsigned long (*hash)(const char *));
528
529 struct obj_section *obj_find_section (struct obj_file *f,
530                                            const char *name);
531
532 void obj_insert_section_load_order (struct obj_file *f,
533                                     struct obj_section *sec);
534
535 struct obj_section *obj_create_alloced_section (struct obj_file *f,
536                                                 const char *name,
537                                                 unsigned long align,
538                                                 unsigned long size);
539
540 struct obj_section *obj_create_alloced_section_first (struct obj_file *f,
541                                                       const char *name,
542                                                       unsigned long align,
543                                                       unsigned long size);
544
545 void *obj_extend_section (struct obj_section *sec, unsigned long more);
546
547 int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
548                      const char *string);
549
550 int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
551                      struct obj_symbol *sym);
552
553 int obj_check_undefineds(struct obj_file *f);
554
555 void obj_allocate_commons(struct obj_file *f);
556
557 unsigned long obj_load_size (struct obj_file *f);
558
559 int obj_relocate (struct obj_file *f, ElfW(Addr) base);
560
561 struct obj_file *obj_load(FILE *f);
562
563 int obj_create_image (struct obj_file *f, char *image);
564
565 /* Architecture specific manipulation routines.  */
566
567 struct obj_file *arch_new_file (void);
568
569 struct obj_section *arch_new_section (void);
570
571 struct obj_symbol *arch_new_symbol (void);
572
573 enum 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
579 int arch_create_got (struct obj_file *f);
580
581 struct new_module;
582 int 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
592
593 #define _PATH_MODULES   "/lib/modules"
594 static const int STRVERSIONLEN = 32;
595
596 /*======================================================================*/
597
598 int flag_force_load = 0;
599 int flag_autoclean = 0;
600 int flag_verbose = 0;
601 int flag_export = 1;
602
603
604 /*======================================================================*/
605
606 /* 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
612 /* Done ;-) */
613
614
615
616 #if defined(BB_USE_PLT_ENTRIES)
617 struct arch_plt_entry
618 {
619   int offset;
620   int allocated:1;
621   int inited:1;                /* has been set up */
622 };
623 #endif
624
625 #if defined(BB_USE_GOT_ENTRIES)
626 struct arch_got_entry {
627         int offset;
628         unsigned offset_done:1;
629         unsigned reloc_done:1;
630 };
631 #endif
632
633 #if defined(__mips__)
634 struct mips_hi16
635 {
636   struct mips_hi16 *next;
637   Elf32_Addr *addr;
638   Elf32_Addr value;
639 };
640 #endif
641
642 struct arch_file {
643         struct obj_file root;
644 #if defined(BB_USE_PLT_ENTRIES)
645         struct obj_section *plt;
646 #endif
647 #if defined(BB_USE_GOT_ENTRIES)
648         struct obj_section *got;
649 #endif
650 #if defined(__mips__)
651         struct mips_hi16 *mips_hi16_list;
652 #endif
653 };
654
655 struct arch_symbol {
656         struct obj_symbol root;
657 #if defined(BB_USE_PLT_ENTRIES)
658         struct arch_plt_entry pltent;
659 #endif
660 #if defined(BB_USE_GOT_ENTRIES)
661         struct arch_got_entry gotent;
662 #endif
663 };
664
665
666 struct 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
674 struct new_module_symbol *ksyms;
675 size_t nksyms;
676
677 struct external_module *ext_modules;
678 int n_ext_modules;
679 int n_ext_modules_used;
680
681
682 extern int delete_module(const char *);
683
684
685 /* This is kind of troublesome. See, we don't actually support
686    the m68k or the arm the same way we support i386 and (now)
687    sh. In doing my SH patch, I just assumed that whatever works
688    for i386 also works for m68k and arm since currently insmod.c
689    does nothing special for them. If this isn't true, the below
690    line is rather misleading IMHO, and someone should either
691    change it or add more proper architecture-dependent support
692    for these boys.
693
694    -- Bryan Rittmeyer <bryan@ixiacom.com>                    */
695
696 static char m_filename[BUFSIZ + 1];
697 static char m_fullName[BUFSIZ + 1];
698
699 /*======================================================================*/
700
701
702 static int findNamedModule(const char *fileName, struct stat *statbuf,
703                                                    void *userDate)
704 {
705         char *fullName = (char *) userDate;
706
707
708         if (fullName[0] == '\0')
709                 return (FALSE);
710         else {
711                 char *tmp = strrchr((char *) fileName, '/');
712
713                 if (tmp == NULL)
714                         tmp = (char *) fileName;
715                 else
716                         tmp++;
717                 if (check_wildcard_match(tmp, fullName) == TRUE) {
718                         /* Stop searching if we find a match */
719                         safe_strncpy(m_filename, fileName, sizeof(m_filename));
720                         return (FALSE);
721                 }
722         }
723         return (TRUE);
724 }
725
726
727 /*======================================================================*/
728
729 struct obj_file *arch_new_file(void)
730 {
731         struct arch_file *f;
732         f = xmalloc(sizeof(*f));
733
734 #if defined(BB_USE_PLT_ENTRIES)
735         f->plt = NULL;
736 #endif
737 #if defined(BB_USE_GOT_ENTRIES)
738         f->got = NULL;
739 #endif
740 #if defined(__mips__)
741         f->mips_hi16_list = NULL;
742 #endif
743
744         return &f->root;
745 }
746
747 struct obj_section *arch_new_section(void)
748 {
749         return xmalloc(sizeof(struct obj_section));
750 }
751
752 struct obj_symbol *arch_new_symbol(void)
753 {
754         struct arch_symbol *sym;
755         sym = xmalloc(sizeof(*sym));
756
757 #if defined(BB_USE_PLT_ENTRIES)
758         memset(&sym->pltent, 0, sizeof(sym->pltent));
759 #endif
760 #if defined(BB_USE_GOT_ENTRIES)
761         memset(&sym->gotent, 0, sizeof(sym->gotent));
762 #endif
763
764         return &sym->root;
765 }
766
767 enum obj_reloc
768 arch_apply_relocation(struct obj_file *f,
769                                           struct obj_section *targsec,
770                                           struct obj_section *symsec,
771                                           struct obj_symbol *sym,
772                                       ElfW(RelM) *rel, ElfW(Addr) v)
773 {
774         struct arch_file *ifile = (struct arch_file *) f;
775 #if !(defined(__mips__))
776         struct arch_symbol *isym = (struct arch_symbol *) sym;
777 #endif
778
779         ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
780         ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
781 #if defined(BB_USE_GOT_ENTRIES)
782         ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
783 #endif
784 #if defined(BB_USE_PLT_ENTRIES)
785         ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
786         struct arch_plt_entry *pe;
787         unsigned long *ip;
788 #endif
789         enum obj_reloc ret = obj_reloc_ok;
790
791         switch (ELF32_R_TYPE(rel->r_info)) {
792
793 /* even though these constants seem to be the same for
794    the i386 and the sh, we "#if define" them for clarity
795    and in case that ever changes */
796 #if defined(__sh__)
797         case R_SH_NONE:
798 #elif defined(__arm__)
799         case R_ARM_NONE:
800 #elif defined(__i386__)
801         case R_386_NONE:
802 #elif defined(__powerpc__)
803         case R_PPC_NONE:
804 #elif defined(__mips__)
805         case R_MIPS_NONE:
806 #endif
807                 break;
808
809 #if defined(__sh__)
810         case R_SH_DIR32:
811 #elif defined(__arm__)
812         case R_ARM_ABS32:
813 #elif defined(__i386__)
814         case R_386_32:  
815 #elif defined(__powerpc__)
816         case R_PPC_ADDR32:
817 #elif defined(__mips__)
818         case R_MIPS_32:
819 #endif
820                 *loc += v;
821                 break;
822
823 #if defined(__powerpc__)
824         case R_PPC_ADDR16_HA:
825                 *(unsigned short *)loc = (v + 0x8000) >> 16;
826                 break;
827
828         case R_PPC_ADDR16_HI:
829                 *(unsigned short *)loc = v >> 16;
830                 break;
831
832         case R_PPC_ADDR16_LO:
833                 *(unsigned short *)loc = v;
834                 break;
835 #endif
836
837 #if defined(__mips__)
838         case R_MIPS_26:
839                 if (v % 4)
840                         ret = obj_reloc_dangerous;
841                 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
842                         ret = obj_reloc_overflow;
843                 *loc =
844                     (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
845                                             0x03ffffff);
846                 break;
847
848         case R_MIPS_HI16:
849                 {
850                         struct mips_hi16 *n;
851
852                         /* We cannot relocate this one now because we don't know the value
853                            of the carry we need to add.  Save the information, and let LO16
854                            do the actual relocation.  */
855                         n = (struct mips_hi16 *) xmalloc(sizeof *n);
856                         n->addr = loc;
857                         n->value = v;
858                         n->next = ifile->mips_hi16_list;
859                         ifile->mips_hi16_list = n;
860                         break;
861                 }
862
863         case R_MIPS_LO16:
864                 {
865                         unsigned long insnlo = *loc;
866                         Elf32_Addr val, vallo;
867
868                         /* Sign extend the addend we extract from the lo insn.  */
869                         vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
870
871                         if (ifile->mips_hi16_list != NULL) {
872                                 struct mips_hi16 *l;
873
874                                 l = ifile->mips_hi16_list;
875                                 while (l != NULL) {
876                                         struct mips_hi16 *next;
877                                         unsigned long insn;
878
879                                         /* The value for the HI16 had best be the same. */
880                                         assert(v == l->value);
881
882                                         /* Do the HI16 relocation.  Note that we actually don't
883                                            need to know anything about the LO16 itself, except where
884                                            to find the low 16 bits of the addend needed by the LO16.  */
885                                         insn = *l->addr;
886                                         val =
887                                             ((insn & 0xffff) << 16) +
888                                             vallo;
889                                         val += v;
890
891                                         /* Account for the sign extension that will happen in the
892                                            low bits.  */
893                                         val =
894                                             ((val >> 16) +
895                                              ((val & 0x8000) !=
896                                               0)) & 0xffff;
897
898                                         insn = (insn & ~0xffff) | val;
899                                         *l->addr = insn;
900
901                                         next = l->next;
902                                         free(l);
903                                         l = next;
904                                 }
905
906                                 ifile->mips_hi16_list = NULL;
907                         }
908
909                         /* Ok, we're done with the HI16 relocs.  Now deal with the LO16.  */
910                         val = v + vallo;
911                         insnlo = (insnlo & ~0xffff) | (val & 0xffff);
912                         *loc = insnlo;
913                         break;
914                 }
915 #endif
916
917 #if defined(__arm__)
918 #elif defined(__sh__)
919         case R_SH_REL32:
920                 *loc += v - dot;
921                 break;
922 #elif defined(__i386__)
923         case R_386_PLT32:
924         case R_386_PC32:
925                 *loc += v - dot;
926                 break;
927 #elif defined(__powerpc__)
928         case R_PPC_REL32:
929                 *loc = v - dot;
930                 break;
931 #endif
932
933 #if defined(__sh__)
934         case R_SH_PLT32:
935                 *loc = v - dot;
936                 break;
937 #elif defined(__i386__)
938 #endif
939
940 #if defined(BB_USE_PLT_ENTRIES)
941
942 #if defined(__arm__)
943     case R_ARM_PC24:
944     case R_ARM_PLT32:
945 #endif
946 #if defined(__powerpc__)
947         case R_PPC_REL24:
948 #endif
949       /* find the plt entry and initialize it if necessary */
950       assert(isym != NULL);
951
952       pe = (struct arch_plt_entry*) &isym->pltent;
953
954       if (! pe->inited) {
955                 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
956
957                 /* generate some machine code */
958
959 #if defined(__arm__)
960                 ip[0] = 0xe51ff004;                     /* ldr pc,[pc,#-4] */
961                 ip[1] = v;                              /* sym@ */
962 #endif
963 #if defined(__powerpc__)
964           ip[0] = 0x3d600000 + ((v + 0x8000) >> 16);  /* lis r11,sym@ha */
965           ip[1] = 0x396b0000 + (v & 0xffff);          /* addi r11,r11,sym@l */
966           ip[2] = 0x7d6903a6;                         /* mtctr r11 */
967           ip[3] = 0x4e800420;                         /* bctr */
968 #endif
969                 pe->inited = 1;
970           }
971
972       /* relative distance to target */
973       v -= dot;
974       /* if the target is too far away.... */
975       if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
976             /* go via the plt */
977             v = plt + pe->offset - dot;
978           }
979       if (v & 3)
980             ret = obj_reloc_dangerous;
981
982       /* merge the offset into the instruction. */
983 #if defined(__arm__)
984       /* Convert to words. */
985       v >>= 2;
986
987       *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
988 #endif
989 #if defined(__powerpc__)
990       *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
991 #endif
992       break;
993 #endif /* BB_USE_PLT_ENTRIES */
994
995 #if defined(__arm__)
996 #elif defined(__sh__)
997         case R_SH_GLOB_DAT:
998         case R_SH_JMP_SLOT:
999                 *loc = v;
1000                 break;
1001 #elif defined(__i386__)
1002         case R_386_GLOB_DAT:
1003         case R_386_JMP_SLOT:
1004                 *loc = v;
1005                 break;
1006 #endif
1007
1008 #if defined(__arm__)
1009 #elif defined(__sh__)
1010         case R_SH_RELATIVE:
1011                 *loc += f->baseaddr + rel->r_addend;
1012                 break;
1013 #elif defined(__i386__)
1014         case R_386_RELATIVE:
1015                 *loc += f->baseaddr;
1016                 break;
1017 #endif
1018
1019 #if defined(BB_USE_GOT_ENTRIES)
1020
1021 #if defined(__sh__)
1022         case R_SH_GOTPC:
1023 #elif defined(__arm__)
1024     case R_ARM_GOTPC:
1025 #elif defined(__i386__)
1026         case R_386_GOTPC:
1027 #endif
1028                 assert(got != 0);
1029 #if defined(__sh__)
1030                 *loc += got - dot + rel->r_addend;;
1031 #elif defined(__i386__) || defined(__arm__)
1032                 *loc += got - dot;
1033 #endif
1034                 break;
1035
1036 #if defined(__sh__)
1037         case R_SH_GOT32:
1038 #elif defined(__arm__)
1039         case R_ARM_GOT32:
1040 #elif defined(__i386__)
1041         case R_386_GOT32:
1042 #endif
1043                 assert(isym != NULL);
1044         /* needs an entry in the .got: set it, once */
1045                 if (!isym->gotent.reloc_done) {
1046                         isym->gotent.reloc_done = 1;
1047                         *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1048                 }
1049         /* make the reloc with_respect_to_.got */
1050 #if defined(__sh__)
1051                 *loc += isym->gotent.offset + rel->r_addend;
1052 #elif defined(__i386__) || defined(__arm__)
1053                 *loc += isym->gotent.offset;
1054 #endif
1055                 break;
1056
1057     /* address relative to the got */
1058 #if defined(__sh__)
1059         case R_SH_GOTOFF:
1060 #elif defined(__arm__)
1061         case R_ARM_GOTOFF:
1062 #elif defined(__i386__)
1063         case R_386_GOTOFF:
1064 #endif
1065                 assert(got != 0);
1066                 *loc += v - got;
1067                 break;
1068
1069 #endif /* BB_USE_GOT_ENTRIES */
1070
1071         default:
1072         printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info));
1073                 ret = obj_reloc_unhandled;
1074                 break;
1075         }
1076
1077         return ret;
1078 }
1079
1080 int arch_create_got(struct obj_file *f)
1081 {
1082 #if defined(BB_USE_GOT_ENTRIES) || defined(BB_USE_PLT_ENTRIES)
1083         struct arch_file *ifile = (struct arch_file *) f;
1084         int i;
1085 #if defined(BB_USE_GOT_ENTRIES)
1086         int got_offset = 0, gotneeded = 0;
1087 #endif
1088 #if defined(BB_USE_PLT_ENTRIES)
1089         int plt_offset = 0, pltneeded = 0;
1090 #endif
1091     struct obj_section *relsec, *symsec, *strsec;
1092         ElfW(RelM) *rel, *relend;
1093         ElfW(Sym) *symtab, *extsym;
1094         const char *strtab, *name;
1095         struct arch_symbol *intsym;
1096
1097         for (i = 0; i < f->header.e_shnum; ++i) {
1098                 relsec = f->sections[i];
1099                 if (relsec->header.sh_type != SHT_RELM)
1100                         continue;
1101
1102                 symsec = f->sections[relsec->header.sh_link];
1103                 strsec = f->sections[symsec->header.sh_link];
1104
1105                 rel = (ElfW(RelM) *) relsec->contents;
1106                 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1107                 symtab = (ElfW(Sym) *) symsec->contents;
1108                 strtab = (const char *) strsec->contents;
1109
1110                 for (; rel < relend; ++rel) {
1111                         extsym = &symtab[ELF32_R_SYM(rel->r_info)];
1112
1113                         switch (ELF32_R_TYPE(rel->r_info)) {
1114 #if defined(__arm__)
1115                         case R_ARM_GOT32:
1116                                 break;
1117 #elif defined(__sh__)
1118                         case R_SH_GOT32:
1119                                 break;
1120 #elif defined(__i386__)
1121                         case R_386_GOT32:
1122                                 break;
1123 #endif
1124
1125 #if defined(__powerpc__)
1126                         case R_PPC_REL24:
1127                                 pltneeded = 1;
1128                                 break;
1129 #endif
1130
1131 #if defined(__arm__)
1132                         case R_ARM_PC24:
1133                         case R_ARM_PLT32:
1134                                 pltneeded = 1;
1135                                 break;
1136
1137                         case R_ARM_GOTPC:
1138                         case R_ARM_GOTOFF:
1139                                 gotneeded = 1;
1140                                 if (got_offset == 0)
1141                                         got_offset = 4;
1142 #elif defined(__sh__)
1143                         case R_SH_GOTPC:
1144                         case R_SH_GOTOFF:
1145                                 gotneeded = 1;
1146 #elif defined(__i386__)
1147                         case R_386_GOTPC:
1148                         case R_386_GOTOFF:
1149                                 gotneeded = 1;
1150 #endif
1151
1152                         default:
1153                                 continue;
1154                         }
1155
1156                         if (extsym->st_name != 0) {
1157                                 name = strtab + extsym->st_name;
1158                         } else {
1159                                 name = f->sections[extsym->st_shndx]->name;
1160                         }
1161                         intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1162 #if defined(BB_USE_GOT_ENTRIES)
1163                         if (!intsym->gotent.offset_done) {
1164                                 intsym->gotent.offset_done = 1;
1165                                 intsym->gotent.offset = got_offset;
1166                                 got_offset += BB_GOT_ENTRY_SIZE;
1167                         }
1168 #endif
1169 #if defined(BB_USE_PLT_ENTRIES)
1170                         if (pltneeded && intsym->pltent.allocated == 0) {
1171                                 intsym->pltent.allocated = 1;
1172                                 intsym->pltent.offset = plt_offset;
1173                                 plt_offset += BB_PLT_ENTRY_SIZE;
1174                                 intsym->pltent.inited = 0;
1175                                 pltneeded = 0;
1176                         }
1177 #endif
1178                         }
1179                 }
1180
1181 #if defined(BB_USE_GOT_ENTRIES)
1182         if (got_offset) {
1183                 struct obj_section* myrelsec = obj_find_section(f, ".got");
1184
1185                 if (myrelsec) {
1186                         obj_extend_section(myrelsec, got_offset);
1187                 } else {
1188                         myrelsec = obj_create_alloced_section(f, ".got", 
1189                                                             BB_GOT_ENTRY_SIZE,
1190                                                             got_offset);
1191                         assert(myrelsec);
1192                 }
1193
1194                 ifile->got = myrelsec;
1195         }
1196 #endif
1197
1198 #if defined(BB_USE_PLT_ENTRIES)
1199         if (plt_offset)
1200                 ifile->plt = obj_create_alloced_section(f, ".plt", 
1201                                                         BB_PLT_ENTRY_SIZE, 
1202                                                         plt_offset);
1203 #endif
1204 #endif
1205         return 1;
1206 }
1207
1208 int arch_init_module(struct obj_file *f, struct new_module *mod)
1209 {
1210         return 1;
1211 }
1212
1213
1214 /*======================================================================*/
1215
1216 /* Standard ELF hash function.  */
1217 inline unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1218 {
1219         unsigned long h = 0;
1220         unsigned long g;
1221         unsigned char ch;
1222
1223         while (n > 0) {
1224                 ch = *name++;
1225                 h = (h << 4) + ch;
1226                 if ((g = (h & 0xf0000000)) != 0) {
1227                         h ^= g >> 24;
1228                         h &= ~g;
1229                 }
1230                 n--;
1231         }
1232         return h;
1233 }
1234
1235 unsigned long obj_elf_hash(const char *name)
1236 {
1237         return obj_elf_hash_n(name, strlen(name));
1238 }
1239
1240 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1241 /* Get the kernel version in the canonical integer form.  */
1242
1243 static int get_kernel_version(char str[STRVERSIONLEN])
1244 {
1245         struct utsname uts_info;
1246         char *p, *q;
1247         int a, b, c;
1248
1249         if (uname(&uts_info) < 0)
1250                 return -1;
1251         strncpy(str, uts_info.release, STRVERSIONLEN);
1252         p = uts_info.release;
1253
1254         a = strtoul(p, &p, 10);
1255         if (*p != '.')
1256                 return -1;
1257         b = strtoul(p + 1, &p, 10);
1258         if (*p != '.')
1259                 return -1;
1260         c = strtoul(p + 1, &q, 10);
1261         if (p + 1 == q)
1262                 return -1;
1263
1264         return a << 16 | b << 8 | c;
1265 }
1266
1267 /* String comparison for non-co-versioned kernel and module.  */
1268
1269 static int ncv_strcmp(const char *a, const char *b)
1270 {
1271         size_t alen = strlen(a), blen = strlen(b);
1272
1273         if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1274                 return strncmp(a, b, alen);
1275         else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1276                 return strncmp(a, b, blen);
1277         else
1278                 return strcmp(a, b);
1279 }
1280
1281 /* String hashing for non-co-versioned kernel and module.  Here
1282    we are simply forced to drop the crc from the hash.  */
1283
1284 static unsigned long ncv_symbol_hash(const char *str)
1285 {
1286         size_t len = strlen(str);
1287         if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1288                 len -= 10;
1289         return obj_elf_hash_n(str, len);
1290 }
1291
1292 void
1293 obj_set_symbol_compare(struct obj_file *f,
1294                                            int (*cmp) (const char *, const char *),
1295                                            unsigned long (*hash) (const char *))
1296 {
1297         if (cmp)
1298                 f->symbol_cmp = cmp;
1299         if (hash) {
1300                 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1301                 int i;
1302
1303                 f->symbol_hash = hash;
1304
1305                 memcpy(tmptab, f->symtab, sizeof(tmptab));
1306                 memset(f->symtab, 0, sizeof(f->symtab));
1307
1308                 for (i = 0; i < HASH_BUCKETS; ++i)
1309                         for (sym = tmptab[i]; sym; sym = next) {
1310                                 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1311                                 next = sym->next;
1312                                 sym->next = f->symtab[h];
1313                                 f->symtab[h] = sym;
1314                         }
1315         }
1316 }
1317
1318 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1319
1320
1321 struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name,
1322                                                                   unsigned long symidx, int info,
1323                                                                   int secidx, ElfW(Addr) value,
1324                                                                   unsigned long size)
1325 {
1326         struct obj_symbol *sym;
1327         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1328         int n_type = ELFW(ST_TYPE) (info);
1329         int n_binding = ELFW(ST_BIND) (info);
1330
1331         for (sym = f->symtab[hash]; sym; sym = sym->next)
1332                 if (f->symbol_cmp(sym->name, name) == 0) {
1333                         int o_secidx = sym->secidx;
1334                         int o_info = sym->info;
1335                         int o_type = ELFW(ST_TYPE) (o_info);
1336                         int o_binding = ELFW(ST_BIND) (o_info);
1337
1338                         /* A redefinition!  Is it legal?  */
1339
1340                         if (secidx == SHN_UNDEF)
1341                                 return sym;
1342                         else if (o_secidx == SHN_UNDEF)
1343                                 goto found;
1344                         else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
1345                                 /* Cope with local and global symbols of the same name
1346                                    in the same object file, as might have been created
1347                                    by ld -r.  The only reason locals are now seen at this
1348                                    level at all is so that we can do semi-sensible things
1349                                    with parameters.  */
1350
1351                                 struct obj_symbol *nsym, **p;
1352
1353                                 nsym = arch_new_symbol();
1354                                 nsym->next = sym->next;
1355                                 nsym->ksymidx = -1;
1356
1357                                 /* Excise the old (local) symbol from the hash chain.  */
1358                                 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
1359                                         continue;
1360                                 *p = sym = nsym;
1361                                 goto found;
1362                         } else if (n_binding == STB_LOCAL) {
1363                                 /* Another symbol of the same name has already been defined.
1364                                    Just add this to the local table.  */
1365                                 sym = arch_new_symbol();
1366                                 sym->next = NULL;
1367                                 sym->ksymidx = -1;
1368                                 f->local_symtab[symidx] = sym;
1369                                 goto found;
1370                         } else if (n_binding == STB_WEAK)
1371                                 return sym;
1372                         else if (o_binding == STB_WEAK)
1373                                 goto found;
1374                         /* Don't unify COMMON symbols with object types the programmer
1375                            doesn't expect.  */
1376                         else if (secidx == SHN_COMMON
1377                                          && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
1378                                 return sym;
1379                         else if (o_secidx == SHN_COMMON
1380                                          && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
1381                                 goto found;
1382                         else {
1383                                 /* Don't report an error if the symbol is coming from
1384                                    the kernel or some external module.  */
1385                                 if (secidx <= SHN_HIRESERVE)
1386                                         error_msg("%s multiply defined", name);
1387                                 return sym;
1388                         }
1389                 }
1390
1391         /* Completely new symbol.  */
1392         sym = arch_new_symbol();
1393         sym->next = f->symtab[hash];
1394         f->symtab[hash] = sym;
1395         sym->ksymidx = -1;
1396
1397         if (ELFW(ST_BIND) (info) == STB_LOCAL)
1398                 f->local_symtab[symidx] = sym;
1399
1400   found:
1401         sym->name = name;
1402         sym->value = value;
1403         sym->size = size;
1404         sym->secidx = secidx;
1405         sym->info = info;
1406
1407         return sym;
1408 }
1409
1410 struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name)
1411 {
1412         struct obj_symbol *sym;
1413         unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1414
1415         for (sym = f->symtab[hash]; sym; sym = sym->next)
1416                 if (f->symbol_cmp(sym->name, name) == 0)
1417                         return sym;
1418
1419         return NULL;
1420 }
1421
1422 ElfW(Addr)
1423         obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
1424 {
1425         if (sym) {
1426                 if (sym->secidx >= SHN_LORESERVE)
1427                         return sym->value;
1428
1429                 return sym->value + f->sections[sym->secidx]->header.sh_addr;
1430         } else {
1431                 /* As a special case, a NULL sym has value zero.  */
1432                 return 0;
1433         }
1434 }
1435
1436 struct obj_section *obj_find_section(struct obj_file *f, const char *name)
1437 {
1438         int i, n = f->header.e_shnum;
1439
1440         for (i = 0; i < n; ++i)
1441                 if (strcmp(f->sections[i]->name, name) == 0)
1442                         return f->sections[i];
1443
1444         return NULL;
1445 }
1446
1447 static int obj_load_order_prio(struct obj_section *a)
1448 {
1449         unsigned long af, ac;
1450
1451         af = a->header.sh_flags;
1452
1453         ac = 0;
1454         if (a->name[0] != '.' || strlen(a->name) != 10 ||
1455                 strcmp(a->name + 5, ".init"))
1456                 ac |= 32;
1457         if (af & SHF_ALLOC)
1458                 ac |= 16;
1459         if (!(af & SHF_WRITE))
1460                 ac |= 8;
1461         if (af & SHF_EXECINSTR)
1462                 ac |= 4;
1463         if (a->header.sh_type != SHT_NOBITS)
1464                 ac |= 2;
1465
1466         return ac;
1467 }
1468
1469 void
1470 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
1471 {
1472         struct obj_section **p;
1473         int prio = obj_load_order_prio(sec);
1474         for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
1475                 if (obj_load_order_prio(*p) < prio)
1476                         break;
1477         sec->load_next = *p;
1478         *p = sec;
1479 }
1480
1481 struct obj_section *obj_create_alloced_section(struct obj_file *f,
1482                                                                                            const char *name,
1483                                                                                            unsigned long align,
1484                                                                                            unsigned long size)
1485 {
1486         int newidx = f->header.e_shnum++;
1487         struct obj_section *sec;
1488
1489         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1490         f->sections[newidx] = sec = arch_new_section();
1491
1492         memset(sec, 0, sizeof(*sec));
1493         sec->header.sh_type = SHT_PROGBITS;
1494         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1495         sec->header.sh_size = size;
1496         sec->header.sh_addralign = align;
1497         sec->name = name;
1498         sec->idx = newidx;
1499         if (size)
1500                 sec->contents = xmalloc(size);
1501
1502         obj_insert_section_load_order(f, sec);
1503
1504         return sec;
1505 }
1506
1507 struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
1508                                                                                                          const char *name,
1509                                                                                                          unsigned long align,
1510                                                                                                          unsigned long size)
1511 {
1512         int newidx = f->header.e_shnum++;
1513         struct obj_section *sec;
1514
1515         f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));
1516         f->sections[newidx] = sec = arch_new_section();
1517
1518         memset(sec, 0, sizeof(*sec));
1519         sec->header.sh_type = SHT_PROGBITS;
1520         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
1521         sec->header.sh_size = size;
1522         sec->header.sh_addralign = align;
1523         sec->name = name;
1524         sec->idx = newidx;
1525         if (size)
1526                 sec->contents = xmalloc(size);
1527
1528         sec->load_next = f->load_order;
1529         f->load_order = sec;
1530         if (f->load_order_search_start == &f->load_order)
1531                 f->load_order_search_start = &sec->load_next;
1532
1533         return sec;
1534 }
1535
1536 void *obj_extend_section(struct obj_section *sec, unsigned long more)
1537 {
1538         unsigned long oldsize = sec->header.sh_size;
1539         sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);
1540         return sec->contents + oldsize;
1541 }
1542
1543
1544
1545 /* Conditionally add the symbols from the given symbol set to the
1546    new module.  */
1547
1548 static int
1549 add_symbols_from(
1550                                  struct obj_file *f,
1551                                  int idx, struct new_module_symbol *syms, size_t nsyms)
1552 {
1553         struct new_module_symbol *s;
1554         size_t i;
1555         int used = 0;
1556
1557         for (i = 0, s = syms; i < nsyms; ++i, ++s) {
1558
1559                 /* Only add symbols that are already marked external.  If we
1560                    override locals we may cause problems for argument initialization.
1561                    We will also create a false dependency on the module.  */
1562                 struct obj_symbol *sym;
1563
1564                 sym = obj_find_symbol(f, (char *) s->name);
1565                 if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
1566                         sym = obj_add_symbol(f, (char *) s->name, -1,
1567                                                                  ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
1568                                                                  idx, s->value, 0);
1569                         /* Did our symbol just get installed?  If so, mark the
1570                            module as "used".  */
1571                         if (sym->secidx == idx)
1572                                 used = 1;
1573                 }
1574         }
1575
1576         return used;
1577 }
1578
1579 static void add_kernel_symbols(struct obj_file *f)
1580 {
1581         struct external_module *m;
1582         int i, nused = 0;
1583
1584         /* Add module symbols first.  */
1585
1586         for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)
1587                 if (m->nsyms
1588                         && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,
1589                                                                 m->nsyms)) m->used = 1, ++nused;
1590
1591         n_ext_modules_used = nused;
1592
1593         /* And finally the symbols from the kernel proper.  */
1594
1595         if (nksyms)
1596                 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
1597 }
1598
1599 static char *get_modinfo_value(struct obj_file *f, const char *key)
1600 {
1601         struct obj_section *sec;
1602         char *p, *v, *n, *ep;
1603         size_t klen = strlen(key);
1604
1605         sec = obj_find_section(f, ".modinfo");
1606         if (sec == NULL)
1607                 return NULL;
1608         p = sec->contents;
1609         ep = p + sec->header.sh_size;
1610         while (p < ep) {
1611                 v = strchr(p, '=');
1612                 n = strchr(p, '\0');
1613                 if (v) {
1614                         if (p + klen == v && strncmp(p, key, klen) == 0)
1615                                 return v + 1;
1616                 } else {
1617                         if (p + klen == n && strcmp(p, key) == 0)
1618                                 return n;
1619                 }
1620                 p = n + 1;
1621         }
1622
1623         return NULL;
1624 }
1625
1626
1627 /*======================================================================*/
1628 /* Functions relating to module loading in pre 2.1 kernels.  */
1629
1630 static int
1631 old_process_module_arguments(struct obj_file *f, int argc, char **argv)
1632 {
1633         while (argc > 0) {
1634                 char *p, *q;
1635                 struct obj_symbol *sym;
1636                 int *loc;
1637
1638                 p = *argv;
1639                 if ((q = strchr(p, '=')) == NULL) {
1640                         argc--;
1641                         continue;
1642                 }
1643                 *q++ = '\0';
1644
1645                 sym = obj_find_symbol(f, p);
1646
1647                 /* Also check that the parameter was not resolved from the kernel.  */
1648                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
1649                         error_msg("symbol for parameter %s not found", p);
1650                         return 0;
1651                 }
1652
1653                 loc = (int *) (f->sections[sym->secidx]->contents + sym->value);
1654
1655                 /* Do C quoting if we begin with a ".  */
1656                 if (*q == '"') {
1657                         char *r, *str;
1658
1659                         str = alloca(strlen(q));
1660                         for (r = str, q++; *q != '"'; ++q, ++r) {
1661                                 if (*q == '\0') {
1662                                         error_msg("improperly terminated string argument for %s", p);
1663                                         return 0;
1664                                 } else if (*q == '\\')
1665                                         switch (*++q) {
1666                                         case 'a':
1667                                                 *r = '\a';
1668                                                 break;
1669                                         case 'b':
1670                                                 *r = '\b';
1671                                                 break;
1672                                         case 'e':
1673                                                 *r = '\033';
1674                                                 break;
1675                                         case 'f':
1676                                                 *r = '\f';
1677                                                 break;
1678                                         case 'n':
1679                                                 *r = '\n';
1680                                                 break;
1681                                         case 'r':
1682                                                 *r = '\r';
1683                                                 break;
1684                                         case 't':
1685                                                 *r = '\t';
1686                                                 break;
1687
1688                                         case '0':
1689                                         case '1':
1690                                         case '2':
1691                                         case '3':
1692                                         case '4':
1693                                         case '5':
1694                                         case '6':
1695                                         case '7':
1696                                                 {
1697                                                         int c = *q - '0';
1698                                                         if (q[1] >= '0' && q[1] <= '7') {
1699                                                                 c = (c * 8) + *++q - '0';
1700                                                                 if (q[1] >= '0' && q[1] <= '7')
1701                                                                         c = (c * 8) + *++q - '0';
1702                                                         }
1703                                                         *r = c;
1704                                                 }
1705                                                 break;
1706
1707                                         default:
1708                                                 *r = *q;
1709                                                 break;
1710                                 } else
1711                                         *r = *q;
1712                         }
1713                         *r = '\0';
1714                         obj_string_patch(f, sym->secidx, sym->value, str);
1715                 } else if (*q >= '0' && *q <= '9') {
1716                         do
1717                                 *loc++ = strtoul(q, &q, 0);
1718                         while (*q++ == ',');
1719                 } else {
1720                         char *contents = f->sections[sym->secidx]->contents;
1721                         char *myloc = contents + sym->value;
1722                         char *r;                        /* To search for commas */
1723
1724                         /* Break the string with comas */
1725                         while ((r = strchr(q, ',')) != (char *) NULL) {
1726                                 *r++ = '\0';
1727                                 obj_string_patch(f, sym->secidx, myloc - contents, q);
1728                                 myloc += sizeof(char *);
1729                                 q = r;
1730                         }
1731
1732                         /* last part */
1733                         obj_string_patch(f, sym->secidx, myloc - contents, q);
1734                 }
1735
1736                 argc--, argv++;
1737         }
1738
1739         return 1;
1740 }
1741
1742 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
1743 static int old_is_module_checksummed(struct obj_file *f)
1744 {
1745         return obj_find_symbol(f, "Using_Versions") != NULL;
1746 }
1747 /* Get the module's kernel version in the canonical integer form.  */
1748
1749 static int
1750 old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
1751 {
1752         struct obj_symbol *sym;
1753         char *p, *q;
1754         int a, b, c;
1755
1756         sym = obj_find_symbol(f, "kernel_version");
1757         if (sym == NULL)
1758                 return -1;
1759
1760         p = f->sections[sym->secidx]->contents + sym->value;
1761         strncpy(str, p, STRVERSIONLEN);
1762
1763         a = strtoul(p, &p, 10);
1764         if (*p != '.')
1765                 return -1;
1766         b = strtoul(p + 1, &p, 10);
1767         if (*p != '.')
1768                 return -1;
1769         c = strtoul(p + 1, &q, 10);
1770         if (p + 1 == q)
1771                 return -1;
1772
1773         return a << 16 | b << 8 | c;
1774 }
1775
1776 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
1777
1778 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
1779
1780 /* Fetch all the symbols and divvy them up as appropriate for the modules.  */
1781
1782 static int old_get_kernel_symbols(const char *m_name)
1783 {
1784         struct old_kernel_sym *ks, *k;
1785         struct new_module_symbol *s;
1786         struct external_module *mod;
1787         int nks, nms, nmod, i;
1788
1789         nks = get_kernel_syms(NULL);
1790         if (nks <= 0) {
1791                 if (nks)
1792                         perror_msg("get_kernel_syms: %s", m_name);
1793                 else
1794                         error_msg("No kernel symbols");
1795                 return 0;
1796         }
1797
1798         ks = k = xmalloc(nks * sizeof(*ks));
1799
1800         if (get_kernel_syms(ks) != nks) {
1801                 perror("inconsistency with get_kernel_syms -- is someone else "
1802                            "playing with modules?");
1803                 free(ks);
1804                 return 0;
1805         }
1806
1807         /* Collect the module information.  */
1808
1809         mod = NULL;
1810         nmod = -1;
1811
1812         while (k->name[0] == '#' && k->name[1]) {
1813                 struct old_kernel_sym *k2;
1814
1815                 /* Find out how many symbols this module has.  */
1816                 for (k2 = k + 1; k2->name[0] != '#'; ++k2)
1817                         continue;
1818                 nms = k2 - k - 1;
1819
1820                 mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));
1821                 mod[nmod].name = k->name + 1;
1822                 mod[nmod].addr = k->value;
1823                 mod[nmod].used = 0;
1824                 mod[nmod].nsyms = nms;
1825                 mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1826
1827                 for (i = 0, ++k; i < nms; ++i, ++s, ++k) {
1828                         s->name = (unsigned long) k->name;
1829                         s->value = k->value;
1830                 }
1831
1832                 k = k2;
1833         }
1834
1835         ext_modules = mod;
1836         n_ext_modules = nmod + 1;
1837
1838         /* Now collect the symbols for the kernel proper.  */
1839
1840         if (k->name[0] == '#')
1841                 ++k;
1842
1843         nksyms = nms = nks - (k - ks);
1844         ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);
1845
1846         for (i = 0; i < nms; ++i, ++s, ++k) {
1847                 s->name = (unsigned long) k->name;
1848                 s->value = k->value;
1849         }
1850
1851         return 1;
1852 }
1853
1854 /* Return the kernel symbol checksum version, or zero if not used.  */
1855
1856 static int old_is_kernel_checksummed(void)
1857 {
1858         /* Using_Versions is the first symbol.  */
1859         if (nksyms > 0
1860                 && strcmp((char *) ksyms[0].name,
1861                                   "Using_Versions") == 0) return ksyms[0].value;
1862         else
1863                 return 0;
1864 }
1865
1866
1867 static int old_create_mod_use_count(struct obj_file *f)
1868 {
1869         struct obj_section *sec;
1870
1871         sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),
1872                                                                                    sizeof(long));
1873
1874         obj_add_symbol(f, "mod_use_count_", -1,
1875                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
1876                                    sizeof(long));
1877
1878         return 1;
1879 }
1880
1881 static int
1882 old_init_module(const char *m_name, struct obj_file *f,
1883                                 unsigned long m_size)
1884 {
1885         char *image;
1886         struct old_mod_routines routines;
1887         struct old_symbol_table *symtab;
1888         int ret;
1889
1890         /* Create the symbol table */
1891         {
1892                 int nsyms = 0, strsize = 0, total;
1893
1894                 /* Size things first... */
1895                 if (flag_export) {
1896                         int i;
1897                         for (i = 0; i < HASH_BUCKETS; ++i) {
1898                                 struct obj_symbol *sym;
1899                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1900                                         if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
1901                                                 && sym->secidx <= SHN_HIRESERVE) 
1902                                         {
1903                                                 sym->ksymidx = nsyms++;
1904                                                 strsize += strlen(sym->name) + 1;
1905                                         }
1906                         }
1907                 }
1908
1909                 total = (sizeof(struct old_symbol_table)
1910                                  + nsyms * sizeof(struct old_module_symbol)
1911                                  + n_ext_modules_used * sizeof(struct old_module_ref)
1912                                  + strsize);
1913                 symtab = xmalloc(total);
1914                 symtab->size = total;
1915                 symtab->n_symbols = nsyms;
1916                 symtab->n_refs = n_ext_modules_used;
1917
1918                 if (flag_export && nsyms) {
1919                         struct old_module_symbol *ksym;
1920                         char *str;
1921                         int i;
1922
1923                         ksym = symtab->symbol;
1924                         str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)
1925                                    + n_ext_modules_used * sizeof(struct old_module_ref));
1926
1927                         for (i = 0; i < HASH_BUCKETS; ++i) {
1928                                 struct obj_symbol *sym;
1929                                 for (sym = f->symtab[i]; sym; sym = sym->next)
1930                                         if (sym->ksymidx >= 0) {
1931                                                 ksym->addr = obj_symbol_final_value(f, sym);
1932                                                 ksym->name =
1933                                                         (unsigned long) str - (unsigned long) symtab;
1934
1935                                                 strcpy(str, sym->name);
1936                                                 str += strlen(sym->name) + 1;
1937                                                 ksym++;
1938                                         }
1939                         }
1940                 }
1941
1942                 if (n_ext_modules_used) {
1943                         struct old_module_ref *ref;
1944                         int i;
1945
1946                         ref = (struct old_module_ref *)
1947                                 ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));
1948
1949                         for (i = 0; i < n_ext_modules; ++i)
1950                                 if (ext_modules[i].used)
1951                                         ref++->module = ext_modules[i].addr;
1952                 }
1953         }
1954
1955         /* Fill in routines.  */
1956
1957         routines.init =
1958                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
1959         routines.cleanup =
1960                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
1961
1962         /* Whew!  All of the initialization is complete.  Collect the final
1963            module image and give it to the kernel.  */
1964
1965         image = xmalloc(m_size);
1966         obj_create_image(f, image);
1967
1968         /* image holds the complete relocated module, accounting correctly for
1969            mod_use_count.  However the old module kernel support assume that
1970            it is receiving something which does not contain mod_use_count.  */
1971         ret = old_sys_init_module(m_name, image + sizeof(long),
1972                                                           m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN
1973                                                                                 : 0), &routines, symtab);
1974         if (ret)
1975                 perror_msg("init_module: %s", m_name);
1976
1977         free(image);
1978         free(symtab);
1979
1980         return ret == 0;
1981 }
1982
1983 #else
1984
1985 #define old_create_mod_use_count(x) TRUE
1986 #define old_init_module(x, y, z) TRUE
1987
1988 #endif                                                  /* BB_FEATURE_OLD_MODULE_INTERFACE */
1989
1990
1991
1992 /*======================================================================*/
1993 /* Functions relating to module loading after 2.1.18.  */
1994
1995 static int
1996 new_process_module_arguments(struct obj_file *f, int argc, char **argv)
1997 {
1998         while (argc > 0) {
1999                 char *p, *q, *key;
2000                 struct obj_symbol *sym;
2001                 char *contents, *loc;
2002                 int min, max, n;
2003
2004                 p = *argv;
2005                 if ((q = strchr(p, '=')) == NULL) {
2006                         argc--;
2007                         continue;
2008                 }
2009
2010                 key = alloca(q - p + 6);
2011                 memcpy(key, "parm_", 5);
2012                 memcpy(key + 5, p, q - p);
2013                 key[q - p + 5] = 0;
2014
2015                 p = get_modinfo_value(f, key);
2016                 key += 5;
2017                 if (p == NULL) {
2018                         error_msg("invalid parameter %s", key);
2019                         return 0;
2020                 }
2021
2022                 sym = obj_find_symbol(f, key);
2023
2024                 /* Also check that the parameter was not resolved from the kernel.  */
2025                 if (sym == NULL || sym->secidx > SHN_HIRESERVE) {
2026                         error_msg("symbol for parameter %s not found", key);
2027                         return 0;
2028                 }
2029
2030                 if (isdigit(*p)) {
2031                         min = strtoul(p, &p, 10);
2032                         if (*p == '-')
2033                                 max = strtoul(p + 1, &p, 10);
2034                         else
2035                                 max = min;
2036                 } else
2037                         min = max = 1;
2038
2039                 contents = f->sections[sym->secidx]->contents;
2040                 loc = contents + sym->value;
2041                 n = (*++q != '\0');
2042
2043                 while (1) {
2044                         if ((*p == 's') || (*p == 'c')) {
2045                                 char *str;
2046
2047                                 /* Do C quoting if we begin with a ", else slurp the lot.  */
2048                                 if (*q == '"') {
2049                                         char *r;
2050
2051                                         str = alloca(strlen(q));
2052                                         for (r = str, q++; *q != '"'; ++q, ++r) {
2053                                                 if (*q == '\0') {
2054                                                         error_msg("improperly terminated string argument for %s",
2055                                                                         key);
2056                                                         return 0;
2057                                                 } else if (*q == '\\')
2058                                                         switch (*++q) {
2059                                                         case 'a':
2060                                                                 *r = '\a';
2061                                                                 break;
2062                                                         case 'b':
2063                                                                 *r = '\b';
2064                                                                 break;
2065                                                         case 'e':
2066                                                                 *r = '\033';
2067                                                                 break;
2068                                                         case 'f':
2069                                                                 *r = '\f';
2070                                                                 break;
2071                                                         case 'n':
2072                                                                 *r = '\n';
2073                                                                 break;
2074                                                         case 'r':
2075                                                                 *r = '\r';
2076                                                                 break;
2077                                                         case 't':
2078                                                                 *r = '\t';
2079                                                                 break;
2080
2081                                                         case '0':
2082                                                         case '1':
2083                                                         case '2':
2084                                                         case '3':
2085                                                         case '4':
2086                                                         case '5':
2087                                                         case '6':
2088                                                         case '7':
2089                                                                 {
2090                                                                         int c = *q - '0';
2091                                                                         if (q[1] >= '0' && q[1] <= '7') {
2092                                                                                 c = (c * 8) + *++q - '0';
2093                                                                                 if (q[1] >= '0' && q[1] <= '7')
2094                                                                                         c = (c * 8) + *++q - '0';
2095                                                                         }
2096                                                                         *r = c;
2097                                                                 }
2098                                                                 break;
2099
2100                                                         default:
2101                                                                 *r = *q;
2102                                                                 break;
2103                                                 } else
2104                                                         *r = *q;
2105                                         }
2106                                         *r = '\0';
2107                                         ++q;
2108                                 } else {
2109                                         char *r;
2110
2111                                         /* In this case, the string is not quoted. We will break
2112                                            it using the coma (like for ints). If the user wants to
2113                                            include comas in a string, he just has to quote it */
2114
2115                                         /* Search the next coma */
2116                                         r = strchr(q, ',');
2117
2118                                         /* Found ? */
2119                                         if (r != (char *) NULL) {
2120                                                 /* Recopy the current field */
2121                                                 str = alloca(r - q + 1);
2122                                                 memcpy(str, q, r - q);
2123
2124                                                 /* I don't know if it is usefull, as the previous case
2125                                                    doesn't null terminate the string ??? */
2126                                                 str[r - q] = '\0';
2127
2128                                                 /* Keep next fields */
2129                                                 q = r;
2130                                         } else {
2131                                                 /* last string */
2132                                                 str = q;
2133                                                 q = "";
2134                                         }
2135                                 }
2136
2137                                 if (*p == 's') {
2138                                         /* Normal string */
2139                                         obj_string_patch(f, sym->secidx, loc - contents, str);
2140                                         loc += tgt_sizeof_char_p;
2141                                 } else {
2142                                         /* Array of chars (in fact, matrix !) */
2143                                         unsigned long charssize;        /* size of each member */
2144
2145                                         /* Get the size of each member */
2146                                         /* Probably we should do that outside the loop ? */
2147                                         if (!isdigit(*(p + 1))) {
2148                                                 error_msg("parameter type 'c' for %s must be followed by"
2149                                                                 " the maximum size", key);
2150                                                 return 0;
2151                                         }
2152                                         charssize = strtoul(p + 1, (char **) NULL, 10);
2153
2154                                         /* Check length */
2155                                         if (strlen(str) >= charssize) {
2156                                                 error_msg("string too long for %s (max %ld)", key,
2157                                                                 charssize - 1);
2158                                                 return 0;
2159                                         }
2160
2161                                         /* Copy to location */
2162                                         strcpy((char *) loc, str);
2163                                         loc += charssize;
2164                                 }
2165                         } else {
2166                                 long v = strtoul(q, &q, 0);
2167                                 switch (*p) {
2168                                 case 'b':
2169                                         *loc++ = v;
2170                                         break;
2171                                 case 'h':
2172                                         *(short *) loc = v;
2173                                         loc += tgt_sizeof_short;
2174                                         break;
2175                                 case 'i':
2176                                         *(int *) loc = v;
2177                                         loc += tgt_sizeof_int;
2178                                         break;
2179                                 case 'l':
2180                                         *(long *) loc = v;
2181                                         loc += tgt_sizeof_long;
2182                                         break;
2183
2184                                 default:
2185                                         error_msg("unknown parameter type '%c' for %s", *p, key);
2186                                         return 0;
2187                                 }
2188                         }
2189
2190                   retry_end_of_value:
2191                         switch (*q) {
2192                         case '\0':
2193                                 goto end_of_arg;
2194
2195                         case ' ':
2196                         case '\t':
2197                         case '\n':
2198                         case '\r':
2199                                 ++q;
2200                                 goto retry_end_of_value;
2201
2202                         case ',':
2203                                 if (++n > max) {
2204                                         error_msg("too many values for %s (max %d)", key, max);
2205                                         return 0;
2206                                 }
2207                                 ++q;
2208                                 break;
2209
2210                         default:
2211                                 error_msg("invalid argument syntax for %s", key);
2212                                 return 0;
2213                         }
2214                 }
2215
2216           end_of_arg:
2217                 if (n < min) {
2218                         error_msg("too few values for %s (min %d)", key, min);
2219                         return 0;
2220                 }
2221
2222                 argc--, argv++;
2223         }
2224
2225         return 1;
2226 }
2227
2228 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
2229 static int new_is_module_checksummed(struct obj_file *f)
2230 {
2231         const char *p = get_modinfo_value(f, "using_checksums");
2232         if (p)
2233                 return atoi(p);
2234         else
2235                 return 0;
2236 }
2237
2238 /* Get the module's kernel version in the canonical integer form.  */
2239
2240 static int
2241 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2242 {
2243         char *p, *q;
2244         int a, b, c;
2245
2246         p = get_modinfo_value(f, "kernel_version");
2247         if (p == NULL)
2248                 return -1;
2249         strncpy(str, p, STRVERSIONLEN);
2250
2251         a = strtoul(p, &p, 10);
2252         if (*p != '.')
2253                 return -1;
2254         b = strtoul(p + 1, &p, 10);
2255         if (*p != '.')
2256                 return -1;
2257         c = strtoul(p + 1, &q, 10);
2258         if (p + 1 == q)
2259                 return -1;
2260
2261         return a << 16 | b << 8 | c;
2262 }
2263
2264 #endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */
2265
2266
2267 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
2268
2269 /* Fetch the loaded modules, and all currently exported symbols.  */
2270
2271 static int new_get_kernel_symbols(void)
2272 {
2273         char *module_names, *mn;
2274         struct external_module *modules, *m;
2275         struct new_module_symbol *syms, *s;
2276         size_t ret, bufsize, nmod, nsyms, i, j;
2277
2278         /* Collect the loaded modules.  */
2279
2280         module_names = xmalloc(bufsize = 256);
2281   retry_modules_load:
2282         if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2283                 if (errno == ENOSPC && bufsize < ret) {
2284                         module_names = xrealloc(module_names, bufsize = ret);
2285                         goto retry_modules_load;
2286                 }
2287                 perror_msg("QM_MODULES");
2288                 return 0;
2289         }
2290
2291         n_ext_modules = nmod = ret;
2292
2293         /* Collect the modules' symbols.  */
2294
2295         if (nmod){
2296                 ext_modules = modules = xmalloc(nmod * sizeof(*modules));
2297                 memset(modules, 0, nmod * sizeof(*modules));
2298                 for (i = 0, mn = module_names, m = modules;
2299                          i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2300                         struct new_module_info info;
2301         
2302                         if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2303                                 if (errno == ENOENT) {
2304                                         /* The module was removed out from underneath us.  */
2305                                         continue;
2306                                 }
2307                                 perror_msg("query_module: QM_INFO: %s", mn);
2308                                 return 0;
2309                         }
2310         
2311                         syms = xmalloc(bufsize = 1024);
2312                   retry_mod_sym_load:
2313                         if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2314                                 switch (errno) {
2315                                 case ENOSPC:
2316                                         syms = xrealloc(syms, bufsize = ret);
2317                                         goto retry_mod_sym_load;
2318                                 case ENOENT:
2319                                         /* The module was removed out from underneath us.  */
2320                                         continue;
2321                                 default:
2322                                         perror_msg("query_module: QM_SYMBOLS: %s", mn);
2323                                         return 0;
2324                                 }
2325                         }
2326                         nsyms = ret;
2327         
2328                         m->name = mn;
2329                         m->addr = info.addr;
2330                         m->nsyms = nsyms;
2331                         m->syms = syms;
2332         
2333                         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2334                                 s->name += (unsigned long) syms;
2335                         }
2336                 }
2337         }
2338
2339         /* Collect the kernel's symbols.  */
2340
2341         syms = xmalloc(bufsize = 16 * 1024);
2342   retry_kern_sym_load:
2343         if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2344                 if (errno == ENOSPC && bufsize < ret) {
2345                         syms = xrealloc(syms, bufsize = ret);
2346                         goto retry_kern_sym_load;
2347                 }
2348                 perror_msg("kernel: QM_SYMBOLS");
2349                 return 0;
2350         }
2351         nksyms = nsyms = ret;
2352         ksyms = syms;
2353
2354         for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2355                 s->name += (unsigned long) syms;
2356         }
2357         return 1;
2358 }
2359
2360
2361 /* Return the kernel symbol checksum version, or zero if not used.  */
2362
2363 static int new_is_kernel_checksummed(void)
2364 {
2365         struct new_module_symbol *s;
2366         size_t i;
2367
2368         /* Using_Versions is not the first symbol, but it should be in there.  */
2369
2370         for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2371                 if (strcmp((char *) s->name, "Using_Versions") == 0)
2372                         return s->value;
2373
2374         return 0;
2375 }
2376
2377
2378 static int new_create_this_module(struct obj_file *f, const char *m_name)
2379 {
2380         struct obj_section *sec;
2381
2382         sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2383                                                                                    sizeof(struct new_module));
2384         memset(sec->contents, 0, sizeof(struct new_module));
2385
2386         obj_add_symbol(f, "__this_module", -1,
2387                                    ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
2388                                    sizeof(struct new_module));
2389
2390         obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2391                                          m_name);
2392
2393         return 1;
2394 }
2395
2396
2397 static int new_create_module_ksymtab(struct obj_file *f)
2398 {
2399         struct obj_section *sec;
2400         int i;
2401
2402         /* We must always add the module references.  */
2403
2404         if (n_ext_modules_used) {
2405                 struct new_module_ref *dep;
2406                 struct obj_symbol *tm;
2407
2408                 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2409                                                                                  (sizeof(struct new_module_ref)
2410                                                                                   * n_ext_modules_used));
2411                 if (!sec)
2412                         return 0;
2413
2414                 tm = obj_find_symbol(f, "__this_module");
2415                 dep = (struct new_module_ref *) sec->contents;
2416                 for (i = 0; i < n_ext_modules; ++i)
2417                         if (ext_modules[i].used) {
2418                                 dep->dep = ext_modules[i].addr;
2419                                 obj_symbol_patch(f, sec->idx,
2420                                                                  (char *) &dep->ref - sec->contents, tm);
2421                                 dep->next_ref = 0;
2422                                 ++dep;
2423                         }
2424         }
2425
2426         if (flag_export && !obj_find_section(f, "__ksymtab")) {
2427                 size_t nsyms;
2428                 int *loaded;
2429
2430                 sec =
2431                         obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,
2432                                                                            0);
2433
2434                 /* We don't want to export symbols residing in sections that
2435                    aren't loaded.  There are a number of these created so that
2436                    we make sure certain module options don't appear twice.  */
2437
2438                 loaded = alloca(sizeof(int) * (i = f->header.e_shnum));
2439                 while (--i >= 0)
2440                         loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2441
2442                 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2443                         struct obj_symbol *sym;
2444                         for (sym = f->symtab[i]; sym; sym = sym->next)
2445                                 if (ELFW(ST_BIND) (sym->info) != STB_LOCAL
2446                                         && sym->secidx <= SHN_HIRESERVE
2447                                         && (sym->secidx >= SHN_LORESERVE
2448                                                 || loaded[sym->secidx])) {
2449                                         ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2450
2451                                         obj_symbol_patch(f, sec->idx, ofs, sym);
2452                                         obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2453                                                                          sym->name);
2454
2455                                         nsyms++;
2456                                 }
2457                 }
2458
2459                 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2460         }
2461
2462         return 1;
2463 }
2464
2465
2466 static int
2467 new_init_module(const char *m_name, struct obj_file *f,
2468                                 unsigned long m_size)
2469 {
2470         struct new_module *module;
2471         struct obj_section *sec;
2472         void *image;
2473         int ret;
2474         tgt_long m_addr;
2475
2476         sec = obj_find_section(f, ".this");
2477         module = (struct new_module *) sec->contents;
2478         m_addr = sec->header.sh_addr;
2479
2480         module->size_of_struct = sizeof(*module);
2481         module->size = m_size;
2482         module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2483
2484         sec = obj_find_section(f, "__ksymtab");
2485         if (sec && sec->header.sh_size) {
2486                 module->syms = sec->header.sh_addr;
2487                 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2488         }
2489
2490         if (n_ext_modules_used) {
2491                 sec = obj_find_section(f, ".kmodtab");
2492                 module->deps = sec->header.sh_addr;
2493                 module->ndeps = n_ext_modules_used;
2494         }
2495
2496         module->init =
2497                 obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
2498         module->cleanup =
2499                 obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
2500
2501         sec = obj_find_section(f, "__ex_table");
2502         if (sec) {
2503                 module->ex_table_start = sec->header.sh_addr;
2504                 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2505         }
2506
2507         sec = obj_find_section(f, ".text.init");
2508         if (sec) {
2509                 module->runsize = sec->header.sh_addr - m_addr;
2510         }
2511         sec = obj_find_section(f, ".data.init");
2512         if (sec) {
2513                 if (!module->runsize ||
2514                         module->runsize > sec->header.sh_addr - m_addr)
2515                                 module->runsize = sec->header.sh_addr - m_addr;
2516         }
2517
2518         if (!arch_init_module(f, module))
2519                 return 0;
2520
2521         /* Whew!  All of the initialization is complete.  Collect the final
2522            module image and give it to the kernel.  */
2523
2524         image = xmalloc(m_size);
2525         obj_create_image(f, image);
2526
2527         ret = new_sys_init_module(m_name, (struct new_module *) image);
2528         if (ret)
2529                 perror_msg("init_module: %s", m_name);
2530
2531         free(image);
2532
2533         return ret == 0;
2534 }
2535
2536 #else
2537
2538 #define new_init_module(x, y, z) TRUE
2539 #define new_create_this_module(x, y) 0
2540 #define new_create_module_ksymtab(x)
2541 #define query_module(v, w, x, y, z) -1
2542
2543 #endif                                                  /* BB_FEATURE_NEW_MODULE_INTERFACE */
2544
2545
2546 /*======================================================================*/
2547
2548 int
2549 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2550                                  const char *string)
2551 {
2552         struct obj_string_patch *p;
2553         struct obj_section *strsec;
2554         size_t len = strlen(string) + 1;
2555         char *loc;
2556
2557         p = xmalloc(sizeof(*p));
2558         p->next = f->string_patches;
2559         p->reloc_secidx = secidx;
2560         p->reloc_offset = offset;
2561         f->string_patches = p;
2562
2563         strsec = obj_find_section(f, ".kstrtab");
2564         if (strsec == NULL) {
2565                 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2566                 p->string_offset = 0;
2567                 loc = strsec->contents;
2568         } else {
2569                 p->string_offset = strsec->header.sh_size;
2570                 loc = obj_extend_section(strsec, len);
2571         }
2572         memcpy(loc, string, len);
2573
2574         return 1;
2575 }
2576
2577 int
2578 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2579                                  struct obj_symbol *sym)
2580 {
2581         struct obj_symbol_patch *p;
2582
2583         p = xmalloc(sizeof(*p));
2584         p->next = f->symbol_patches;
2585         p->reloc_secidx = secidx;
2586         p->reloc_offset = offset;
2587         p->sym = sym;
2588         f->symbol_patches = p;
2589
2590         return 1;
2591 }
2592
2593 int obj_check_undefineds(struct obj_file *f)
2594 {
2595         unsigned long i;
2596         int ret = 1;
2597
2598         for (i = 0; i < HASH_BUCKETS; ++i) {
2599                 struct obj_symbol *sym;
2600                 for (sym = f->symtab[i]; sym; sym = sym->next)
2601                         if (sym->secidx == SHN_UNDEF) {
2602                                 if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {
2603                                         sym->secidx = SHN_ABS;
2604                                         sym->value = 0;
2605                                 } else {
2606                                         error_msg("unresolved symbol %s", sym->name);
2607                                         ret = 0;
2608                                 }
2609                         }
2610         }
2611
2612         return ret;
2613 }
2614
2615 void obj_allocate_commons(struct obj_file *f)
2616 {
2617         struct common_entry {
2618                 struct common_entry *next;
2619                 struct obj_symbol *sym;
2620         } *common_head = NULL;
2621
2622         unsigned long i;
2623
2624         for (i = 0; i < HASH_BUCKETS; ++i) {
2625                 struct obj_symbol *sym;
2626                 for (sym = f->symtab[i]; sym; sym = sym->next)
2627                         if (sym->secidx == SHN_COMMON) {
2628                                 /* Collect all COMMON symbols and sort them by size so as to
2629                                    minimize space wasted by alignment requirements.  */
2630                                 {
2631                                         struct common_entry **p, *n;
2632                                         for (p = &common_head; *p; p = &(*p)->next)
2633                                                 if (sym->size <= (*p)->sym->size)
2634                                                         break;
2635
2636                                         n = alloca(sizeof(*n));
2637                                         n->next = *p;
2638                                         n->sym = sym;
2639                                         *p = n;
2640                                 }
2641                         }
2642         }
2643
2644         for (i = 1; i < f->local_symtab_size; ++i) {
2645                 struct obj_symbol *sym = f->local_symtab[i];
2646                 if (sym && sym->secidx == SHN_COMMON) {
2647                         struct common_entry **p, *n;
2648                         for (p = &common_head; *p; p = &(*p)->next)
2649                                 if (sym == (*p)->sym)
2650                                         break;
2651                                 else if (sym->size < (*p)->sym->size) {
2652                                         n = alloca(sizeof(*n));
2653                                         n->next = *p;
2654                                         n->sym = sym;
2655                                         *p = n;
2656                                         break;
2657                                 }
2658                 }
2659         }
2660
2661         if (common_head) {
2662                 /* Find the bss section.  */
2663                 for (i = 0; i < f->header.e_shnum; ++i)
2664                         if (f->sections[i]->header.sh_type == SHT_NOBITS)
2665                                 break;
2666
2667                 /* If for some reason there hadn't been one, create one.  */
2668                 if (i == f->header.e_shnum) {
2669                         struct obj_section *sec;
2670
2671                         f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec));
2672                         f->sections[i] = sec = arch_new_section();
2673                         f->header.e_shnum = i + 1;
2674
2675                         memset(sec, 0, sizeof(*sec));
2676                         sec->header.sh_type = SHT_PROGBITS;
2677                         sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2678                         sec->name = ".bss";
2679                         sec->idx = i;
2680                 }
2681
2682                 /* Allocate the COMMONS.  */
2683                 {
2684                         ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2685                         ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2686                         struct common_entry *c;
2687
2688                         for (c = common_head; c; c = c->next) {
2689                                 ElfW(Addr) align = c->sym->value;
2690
2691                                 if (align > max_align)
2692                                         max_align = align;
2693                                 if (bss_size & (align - 1))
2694                                         bss_size = (bss_size | (align - 1)) + 1;
2695
2696                                 c->sym->secidx = i;
2697                                 c->sym->value = bss_size;
2698
2699                                 bss_size += c->sym->size;
2700                         }
2701
2702                         f->sections[i]->header.sh_size = bss_size;
2703                         f->sections[i]->header.sh_addralign = max_align;
2704                 }
2705         }
2706
2707         /* For the sake of patch relocation and parameter initialization,
2708            allocate zeroed data for NOBITS sections now.  Note that after
2709            this we cannot assume NOBITS are really empty.  */
2710         for (i = 0; i < f->header.e_shnum; ++i) {
2711                 struct obj_section *s = f->sections[i];
2712                 if (s->header.sh_type == SHT_NOBITS) {
2713                         if (s->header.sh_size != 0)
2714                         s->contents = memset(xmalloc(s->header.sh_size),
2715                                                                  0, s->header.sh_size);
2716                         else
2717                                 s->contents = NULL;
2718
2719                         s->header.sh_type = SHT_PROGBITS;
2720                 }
2721         }
2722 }
2723
2724 unsigned long obj_load_size(struct obj_file *f)
2725 {
2726         unsigned long dot = 0;
2727         struct obj_section *sec;
2728
2729         /* Finalize the positions of the sections relative to one another.  */
2730
2731         for (sec = f->load_order; sec; sec = sec->load_next) {
2732                 ElfW(Addr) align;
2733
2734                 align = sec->header.sh_addralign;
2735                 if (align && (dot & (align - 1)))
2736                         dot = (dot | (align - 1)) + 1;
2737
2738                 sec->header.sh_addr = dot;
2739                 dot += sec->header.sh_size;
2740         }
2741
2742         return dot;
2743 }
2744
2745 int obj_relocate(struct obj_file *f, ElfW(Addr) base)
2746 {
2747         int i, n = f->header.e_shnum;
2748         int ret = 1;
2749
2750         /* Finalize the addresses of the sections.  */
2751
2752         f->baseaddr = base;
2753         for (i = 0; i < n; ++i)
2754                 f->sections[i]->header.sh_addr += base;
2755
2756         /* And iterate over all of the relocations.  */
2757
2758         for (i = 0; i < n; ++i) {
2759                 struct obj_section *relsec, *symsec, *targsec, *strsec;
2760                 ElfW(RelM) * rel, *relend;
2761                 ElfW(Sym) * symtab;
2762                 const char *strtab;
2763
2764                 relsec = f->sections[i];
2765                 if (relsec->header.sh_type != SHT_RELM)
2766                         continue;
2767
2768                 symsec = f->sections[relsec->header.sh_link];
2769                 targsec = f->sections[relsec->header.sh_info];
2770                 strsec = f->sections[symsec->header.sh_link];
2771
2772                 rel = (ElfW(RelM) *) relsec->contents;
2773                 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
2774                 symtab = (ElfW(Sym) *) symsec->contents;
2775                 strtab = (const char *) strsec->contents;
2776
2777                 for (; rel < relend; ++rel) {
2778                         ElfW(Addr) value = 0;
2779                         struct obj_symbol *intsym = NULL;
2780                         unsigned long symndx;
2781                         ElfW(Sym) * extsym = 0;
2782                         const char *errmsg;
2783
2784                         /* Attempt to find a value to use for this relocation.  */
2785
2786                         symndx = ELFW(R_SYM) (rel->r_info);
2787                         if (symndx) {
2788                                 /* Note we've already checked for undefined symbols.  */
2789
2790                                 extsym = &symtab[symndx];
2791                                 if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) {
2792                                         /* Local symbols we look up in the local table to be sure
2793                                            we get the one that is really intended.  */
2794                                         intsym = f->local_symtab[symndx];
2795                                 } else {
2796                                         /* Others we look up in the hash table.  */
2797                                         const char *name;
2798                                         if (extsym->st_name)
2799                                                 name = strtab + extsym->st_name;
2800                                         else
2801                                                 name = f->sections[extsym->st_shndx]->name;
2802                                         intsym = obj_find_symbol(f, name);
2803                                 }
2804
2805                                 value = obj_symbol_final_value(f, intsym);
2806                                 intsym->referenced = 1;
2807                         }
2808 #if SHT_RELM == SHT_RELA
2809 #if defined(__alpha__) && defined(AXP_BROKEN_GAS)
2810                         /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9.  */
2811                         if (!extsym || !extsym->st_name ||
2812                                 ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL)
2813 #endif
2814                                 value += rel->r_addend;
2815 #endif
2816
2817                         /* Do it! */
2818                         switch (arch_apply_relocation
2819                                         (f, targsec, symsec, intsym, rel, value)) {
2820                         case obj_reloc_ok:
2821                                 break;
2822
2823                         case obj_reloc_overflow:
2824                                 errmsg = "Relocation overflow";
2825                                 goto bad_reloc;
2826                         case obj_reloc_dangerous:
2827                                 errmsg = "Dangerous relocation";
2828                                 goto bad_reloc;
2829                         case obj_reloc_unhandled:
2830                                 errmsg = "Unhandled relocation";
2831                           bad_reloc:
2832                                 if (extsym) {
2833                                         error_msg("%s of type %ld for %s", errmsg,
2834                                                         (long) ELFW(R_TYPE) (rel->r_info),
2835                                                         strtab + extsym->st_name);
2836                                 } else {
2837                                         error_msg("%s of type %ld", errmsg,
2838                                                         (long) ELFW(R_TYPE) (rel->r_info));
2839                                 }
2840                                 ret = 0;
2841                                 break;
2842                         }
2843                 }
2844         }
2845
2846         /* Finally, take care of the patches.  */
2847
2848         if (f->string_patches) {
2849                 struct obj_string_patch *p;
2850                 struct obj_section *strsec;
2851                 ElfW(Addr) strsec_base;
2852                 strsec = obj_find_section(f, ".kstrtab");
2853                 strsec_base = strsec->header.sh_addr;
2854
2855                 for (p = f->string_patches; p; p = p->next) {
2856                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2857                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2858                                 = strsec_base + p->string_offset;
2859                 }
2860         }
2861
2862         if (f->symbol_patches) {
2863                 struct obj_symbol_patch *p;
2864
2865                 for (p = f->symbol_patches; p; p = p->next) {
2866                         struct obj_section *targsec = f->sections[p->reloc_secidx];
2867                         *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
2868                                 = obj_symbol_final_value(f, p->sym);
2869                 }
2870         }
2871
2872         return ret;
2873 }
2874
2875 int obj_create_image(struct obj_file *f, char *image)
2876 {
2877         struct obj_section *sec;
2878         ElfW(Addr) base = f->baseaddr;
2879
2880         for (sec = f->load_order; sec; sec = sec->load_next) {
2881                 char *secimg;
2882
2883                 if (sec->contents == 0 || sec->header.sh_size == 0)
2884                         continue;
2885
2886                 secimg = image + (sec->header.sh_addr - base);
2887
2888                 /* Note that we allocated data for NOBITS sections earlier.  */
2889                 memcpy(secimg, sec->contents, sec->header.sh_size);
2890         }
2891
2892         return 1;
2893 }
2894
2895 /*======================================================================*/
2896
2897 struct obj_file *obj_load(FILE * fp)
2898 {
2899         struct obj_file *f;
2900         ElfW(Shdr) * section_headers;
2901         int shnum, i;
2902         char *shstrtab;
2903
2904         /* Read the file header.  */
2905
2906         f = arch_new_file();
2907         memset(f, 0, sizeof(*f));
2908         f->symbol_cmp = strcmp;
2909         f->symbol_hash = obj_elf_hash;
2910         f->load_order_search_start = &f->load_order;
2911
2912         fseek(fp, 0, SEEK_SET);
2913         if (fread(&f->header, sizeof(f->header), 1, fp) != 1) {
2914                 perror_msg("error reading ELF header");
2915                 return NULL;
2916         }
2917
2918         if (f->header.e_ident[EI_MAG0] != ELFMAG0
2919                 || f->header.e_ident[EI_MAG1] != ELFMAG1
2920                 || f->header.e_ident[EI_MAG2] != ELFMAG2
2921                 || f->header.e_ident[EI_MAG3] != ELFMAG3) {
2922                 error_msg("not an ELF file");
2923                 return NULL;
2924         }
2925         if (f->header.e_ident[EI_CLASS] != ELFCLASSM
2926                 || f->header.e_ident[EI_DATA] != ELFDATAM
2927                 || f->header.e_ident[EI_VERSION] != EV_CURRENT
2928                 || !MATCH_MACHINE(f->header.e_machine)) {
2929                 error_msg("ELF file not for this architecture");
2930                 return NULL;
2931         }
2932         if (f->header.e_type != ET_REL) {
2933                 error_msg("ELF file not a relocatable object");
2934                 return NULL;
2935         }
2936
2937         /* Read the section headers.  */
2938
2939         if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
2940                 error_msg("section header size mismatch: %lu != %lu",
2941                                 (unsigned long) f->header.e_shentsize,
2942                                 (unsigned long) sizeof(ElfW(Shdr)));
2943                 return NULL;
2944         }
2945
2946         shnum = f->header.e_shnum;
2947         f->sections = xmalloc(sizeof(struct obj_section *) * shnum);
2948         memset(f->sections, 0, sizeof(struct obj_section *) * shnum);
2949
2950         section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
2951         fseek(fp, f->header.e_shoff, SEEK_SET);
2952         if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) {
2953                 perror_msg("error reading ELF section headers");
2954                 return NULL;
2955         }
2956
2957         /* Read the section data.  */
2958
2959         for (i = 0; i < shnum; ++i) {
2960                 struct obj_section *sec;
2961
2962                 f->sections[i] = sec = arch_new_section();
2963                 memset(sec, 0, sizeof(*sec));
2964
2965                 sec->header = section_headers[i];
2966                 sec->idx = i;
2967
2968                 if(sec->header.sh_size) switch (sec->header.sh_type) {
2969                 case SHT_NULL:
2970                 case SHT_NOTE:
2971                 case SHT_NOBITS:
2972                         /* ignore */
2973                         break;
2974
2975                 case SHT_PROGBITS:
2976                 case SHT_SYMTAB:
2977                 case SHT_STRTAB:
2978                 case SHT_RELM:
2979                         if (sec->header.sh_size > 0) {
2980                                 sec->contents = xmalloc(sec->header.sh_size);
2981                                 fseek(fp, sec->header.sh_offset, SEEK_SET);
2982                                 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
2983                                         perror_msg("error reading ELF section data");
2984                                         return NULL;
2985                                 }
2986                         } else {
2987                                 sec->contents = NULL;
2988                         }
2989                         break;
2990
2991 #if SHT_RELM == SHT_REL
2992                 case SHT_RELA:
2993                         error_msg("RELA relocations not supported on this architecture");
2994                         return NULL;
2995 #else
2996                 case SHT_REL:
2997                         error_msg("REL relocations not supported on this architecture");
2998                         return NULL;
2999 #endif
3000
3001                 default:
3002                         if (sec->header.sh_type >= SHT_LOPROC) {
3003                                 /* Assume processor specific section types are debug
3004                                    info and can safely be ignored.  If this is ever not
3005                                    the case (Hello MIPS?), don't put ifdefs here but
3006                                    create an arch_load_proc_section().  */
3007                                 break;
3008                         }
3009
3010                         error_msg("can't handle sections of type %ld",
3011                                         (long) sec->header.sh_type);
3012                         return NULL;
3013                 }
3014         }
3015
3016         /* Do what sort of interpretation as needed by each section.  */
3017
3018         shstrtab = f->sections[f->header.e_shstrndx]->contents;
3019
3020         for (i = 0; i < shnum; ++i) {
3021                 struct obj_section *sec = f->sections[i];
3022                 sec->name = shstrtab + sec->header.sh_name;
3023         }
3024
3025         for (i = 0; i < shnum; ++i) {
3026                 struct obj_section *sec = f->sections[i];
3027
3028                 /* .modinfo should be contents only but gcc has no attribute for that.
3029                  * The kernel may have marked .modinfo as ALLOC, ignore this bit.
3030                  */
3031                 if (strcmp(sec->name, ".modinfo") == 0)
3032                         sec->header.sh_flags &= ~SHF_ALLOC;
3033
3034                 if (sec->header.sh_flags & SHF_ALLOC)
3035                         obj_insert_section_load_order(f, sec);
3036
3037                 switch (sec->header.sh_type) {
3038                 case SHT_SYMTAB:
3039                         {
3040                                 unsigned long nsym, j;
3041                                 char *strtab;
3042                                 ElfW(Sym) * sym;
3043
3044                                 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3045                                         error_msg("symbol size mismatch: %lu != %lu",
3046                                                         (unsigned long) sec->header.sh_entsize,
3047                                                         (unsigned long) sizeof(ElfW(Sym)));
3048                                         return NULL;
3049                                 }
3050
3051                                 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3052                                 strtab = f->sections[sec->header.sh_link]->contents;
3053                                 sym = (ElfW(Sym) *) sec->contents;
3054
3055                                 /* Allocate space for a table of local symbols.  */
3056                                 j = f->local_symtab_size = sec->header.sh_info;
3057                                 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *));
3058
3059                                 /* Insert all symbols into the hash table.  */
3060                                 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3061                                         const char *name;
3062                                         if (sym->st_name)
3063                                                 name = strtab + sym->st_name;
3064                                         else
3065                                                 name = f->sections[sym->st_shndx]->name;
3066
3067                                         obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3068                                                                    sym->st_value, sym->st_size);
3069                                 }
3070                         }
3071                         break;
3072
3073                 case SHT_RELM:
3074                         if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3075                                 error_msg("relocation entry size mismatch: %lu != %lu",
3076                                                 (unsigned long) sec->header.sh_entsize,
3077                                                 (unsigned long) sizeof(ElfW(RelM)));
3078                                 return NULL;
3079                         }
3080                         break;
3081                         /* XXX  Relocation code from modutils-2.3.19 is not here.
3082                          * Why?  That's about 20 lines of code from obj/obj_load.c,
3083                          * which gets done in a second pass through the sections.
3084                          * This BusyBox insmod does similar work in obj_relocate(). */
3085                 }
3086         }
3087
3088         return f;
3089 }
3090
3091 static void hide_special_symbols(struct obj_file *f)
3092 {
3093         static const char *const specials[] = {
3094                 "cleanup_module",
3095                 "init_module",
3096                 "kernel_version",
3097                 NULL
3098         };
3099
3100         struct obj_symbol *sym;
3101         const char *const *p;
3102
3103         for (p = specials; *p; ++p)
3104                 if ((sym = obj_find_symbol(f, *p)) != NULL)
3105                         sym->info =
3106                                 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3107 }
3108
3109
3110
3111 extern int insmod_main( int argc, char **argv)
3112 {
3113         int opt;
3114         int k_crcs;
3115         int k_new_syscalls;
3116         int len;
3117         char *tmp;
3118         unsigned long m_size;
3119         ElfW(Addr) m_addr;
3120         FILE *fp;
3121         struct obj_file *f;
3122         struct stat st;
3123         char m_name[BUFSIZ + 1] = "\0";
3124         int exit_status = EXIT_FAILURE;
3125         int m_has_modinfo;
3126 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3127         int k_version;
3128         char k_strversion[STRVERSIONLEN];
3129         char m_strversion[STRVERSIONLEN];
3130         int m_version;
3131         int m_crcs;
3132 #endif
3133
3134         /* Parse any options */
3135         while ((opt = getopt(argc, argv, "fkvxLo:")) > 0) {
3136                 switch (opt) {
3137                         case 'f':                       /* force loading */
3138                                 flag_force_load = 1;
3139                                 break;
3140                         case 'k':                       /* module loaded by kerneld, auto-cleanable */
3141                                 flag_autoclean = 1;
3142                                 break;
3143                         case 'v':                       /* verbose output */
3144                                 flag_verbose = 1;
3145                                 break;
3146                         case 'x':                       /* do not export externs */
3147                                 flag_export = 0;
3148                                 break;
3149                         case 'o':                       /* name the output module */
3150                                 strncpy(m_name, optarg, BUFSIZ);
3151                                 break;
3152                         case 'L':                       /* Stub warning */
3153                                 /* This is needed for compatibility with modprobe.
3154                                  * In theory, this does locking, but we don't do
3155                                  * that.  So be careful and plan your life around not
3156                                  * loading the same module 50 times concurrently. */
3157                                 break;
3158                         default:
3159                                 show_usage();
3160                 }
3161         }
3162         
3163         if (argv[optind] == NULL) {
3164                 show_usage();
3165         }
3166
3167         /* Grab the module name */
3168         if ((tmp = strrchr(argv[optind], '/')) != NULL) {
3169                 tmp++;
3170         } else {
3171                 tmp = argv[optind];
3172         }
3173         len = strlen(tmp);
3174
3175         if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o')
3176                 len -= 2;
3177         memcpy(m_fullName, tmp, len);
3178         m_fullName[len]='\0';
3179         if (*m_name == '\0') {
3180                 strcpy(m_name, m_fullName);
3181         }
3182         strcat(m_fullName, ".o");
3183
3184         /* Get a filedesc for the module */
3185         if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) ||
3186                         (fp = fopen(argv[optind], "r")) == NULL) {
3187                 /* Hmpf.  Could not open it. Search through _PATH_MODULES to find a module named m_name */
3188                 if (recursive_action(_PATH_MODULES, TRUE, FALSE, FALSE,
3189                                                         findNamedModule, 0, m_fullName) == FALSE) 
3190                 {
3191                         if (m_filename[0] == '\0'
3192                                 || ((fp = fopen(m_filename, "r")) == NULL)) 
3193                         {
3194                                 error_msg("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3195                                 return EXIT_FAILURE;
3196                         }
3197                 } else
3198                         error_msg_and_die("No module named '%s' found in '%s'", m_fullName, _PATH_MODULES);
3199         } else
3200                 safe_strncpy(m_filename, argv[optind], sizeof(m_filename));
3201
3202
3203         if ((f = obj_load(fp)) == NULL)
3204                 perror_msg_and_die("Could not load the module");
3205
3206         if (get_modinfo_value(f, "kernel_version") == NULL)
3207                 m_has_modinfo = 0;
3208         else
3209                 m_has_modinfo = 1;
3210
3211 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3212         /* Version correspondence?  */
3213
3214         k_version = get_kernel_version(k_strversion);
3215         if (m_has_modinfo) {
3216                 m_version = new_get_module_version(f, m_strversion);
3217         } else {
3218                 m_version = old_get_module_version(f, m_strversion);
3219                 if (m_version == -1) {
3220                         error_msg("couldn't find the kernel version the module was "
3221                                         "compiled for");
3222                         goto out;
3223                 }
3224         }
3225
3226         if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) {
3227                 if (flag_force_load) {
3228                         error_msg("Warning: kernel-module version mismatch\n"
3229                                         "\t%s was compiled for kernel version %s\n"
3230                                         "\twhile this kernel is version %s",
3231                                         m_filename, m_strversion, k_strversion);
3232                 } else {
3233                         error_msg("kernel-module version mismatch\n"
3234                                         "\t%s was compiled for kernel version %s\n"
3235                                         "\twhile this kernel is version %s.",
3236                                         m_filename, m_strversion, k_strversion);
3237                         goto out;
3238                 }
3239         }
3240         k_crcs = 0;
3241 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3242
3243         k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
3244
3245         if (k_new_syscalls) {
3246 #ifdef BB_FEATURE_NEW_MODULE_INTERFACE
3247                 if (!new_get_kernel_symbols())
3248                         goto out;
3249                 k_crcs = new_is_kernel_checksummed();
3250 #else
3251                 error_msg("Not configured to support new kernels");
3252                 goto out;
3253 #endif
3254         } else {
3255 #ifdef BB_FEATURE_OLD_MODULE_INTERFACE
3256                 if (!old_get_kernel_symbols(m_name))
3257                         goto out;
3258                 k_crcs = old_is_kernel_checksummed();
3259 #else
3260                 error_msg("Not configured to support old kernels");
3261                 goto out;
3262 #endif
3263         }
3264
3265 #ifdef BB_FEATURE_INSMOD_VERSION_CHECKING
3266         if (m_has_modinfo)
3267                 m_crcs = new_is_module_checksummed(f);
3268         else
3269                 m_crcs = old_is_module_checksummed(f);
3270
3271         if (m_crcs != k_crcs)
3272                 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3273 #endif                                                  /* BB_FEATURE_INSMOD_VERSION_CHECKING */
3274
3275         /* Let the module know about the kernel symbols.  */
3276         add_kernel_symbols(f);
3277
3278         /* Allocate common symbols, symbol tables, and string tables.  */
3279
3280         if (k_new_syscalls 
3281                 ? !new_create_this_module(f, m_name)
3282                 : !old_create_mod_use_count(f)) 
3283         {
3284                 goto out;
3285         }
3286
3287         if (!obj_check_undefineds(f)) {
3288                 goto out;
3289         }
3290         obj_allocate_commons(f);
3291
3292         /* done with the module name, on to the optional var=value arguments */
3293         ++optind;
3294
3295         if (optind < argc) {
3296                 if (m_has_modinfo
3297                         ? !new_process_module_arguments(f, argc - optind, argv + optind) 
3298                         : !old_process_module_arguments(f, argc - optind, argv + optind)) 
3299                 {
3300                         goto out;
3301                 }
3302         }
3303
3304         arch_create_got(f);
3305         hide_special_symbols(f);
3306
3307         if (k_new_syscalls)
3308                 new_create_module_ksymtab(f);
3309
3310         /* Find current size of the module */
3311         m_size = obj_load_size(f);
3312
3313
3314         m_addr = create_module(m_name, m_size);
3315         if (m_addr==-1) switch (errno) {
3316         case EEXIST:
3317                 error_msg("A module named %s already exists", m_name);
3318                 goto out;
3319         case ENOMEM:
3320                 error_msg("Can't allocate kernel memory for module; needed %lu bytes",
3321                                 m_size);
3322                 goto out;
3323         default:
3324                 perror_msg("create_module: %s", m_name);
3325                 goto out;
3326         }
3327
3328         if (!obj_relocate(f, m_addr)) {
3329                 delete_module(m_name);
3330                 goto out;
3331         }
3332
3333         if (k_new_syscalls 
3334                 ? !new_init_module(m_name, f, m_size)
3335                 : !old_init_module(m_name, f, m_size)) 
3336         {
3337                 delete_module(m_name);
3338                 goto out;
3339         }
3340
3341         exit_status = EXIT_SUCCESS;
3342
3343 out:
3344         fclose(fp);
3345         return(exit_status);
3346 }