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