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