1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#include "libbb.h"
62#include "modutils.h"
63#include <libgen.h>
64#include <sys/utsname.h>
65
66#if ENABLE_FEATURE_INSMOD_LOADINKMEM
67#define LOADBITS 0
68#else
69#define LOADBITS 1
70#endif
71
72
73#if defined(__alpha__)
74#define MATCH_MACHINE(x) (x == EM_ALPHA)
75#define SHT_RELM SHT_RELA
76#define Elf64_RelM Elf64_Rela
77#define ELFCLASSM ELFCLASS64
78#endif
79
80
81#if defined(__arm__)
82#define MATCH_MACHINE(x) (x == EM_ARM)
83#define SHT_RELM SHT_REL
84#define Elf32_RelM Elf32_Rel
85#define ELFCLASSM ELFCLASS32
86#define USE_PLT_ENTRIES
87#define PLT_ENTRY_SIZE 8
88#define USE_GOT_ENTRIES
89#define GOT_ENTRY_SIZE 8
90#define USE_SINGLE
91#endif
92
93
94#if defined(BFIN)
95#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
96#define SHT_RELM SHT_RELA
97#define Elf32_RelM Elf32_Rela
98#define ELFCLASSM ELFCLASS32
99#endif
100
101
102#if defined(__cris__)
103#define MATCH_MACHINE(x) (x == EM_CRIS)
104#define SHT_RELM SHT_RELA
105#define Elf32_RelM Elf32_Rela
106#define ELFCLASSM ELFCLASS32
107#ifndef EM_CRIS
108#define EM_CRIS 76
109#define R_CRIS_NONE 0
110#define R_CRIS_32 3
111#endif
112#endif
113
114
115#if defined(__H8300H__) || defined(__H8300S__)
116#define MATCH_MACHINE(x) (x == EM_H8_300)
117#define SHT_RELM SHT_RELA
118#define Elf32_RelM Elf32_Rela
119#define ELFCLASSM ELFCLASS32
120#define USE_SINGLE
121#define SYMBOL_PREFIX "_"
122#endif
123
124
125#if defined(__hppa__)
126#define MATCH_MACHINE(x) (x == EM_PARISC)
127#define SHT_RELM SHT_RELA
128#if defined(__LP64__)
129#define Elf64_RelM Elf64_Rela
130#define ELFCLASSM ELFCLASS64
131#else
132#define Elf32_RelM Elf32_Rela
133#define ELFCLASSM ELFCLASS32
134#endif
135#endif
136
137
138#if defined(__i386__)
139#ifndef EM_486
140#define MATCH_MACHINE(x) (x == EM_386)
141#else
142#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
143#endif
144#define SHT_RELM SHT_REL
145#define Elf32_RelM Elf32_Rel
146#define ELFCLASSM ELFCLASS32
147#define USE_GOT_ENTRIES
148#define GOT_ENTRY_SIZE 4
149#define USE_SINGLE
150#endif
151
152
153#if defined(__ia64__)
154#define MATCH_MACHINE(x) (x == EM_IA_64)
155#define SHT_RELM SHT_RELA
156#define Elf64_RelM Elf64_Rela
157#define ELFCLASSM ELFCLASS64
158#endif
159
160
161#if defined(__mc68000__)
162#define MATCH_MACHINE(x) (x == EM_68K)
163#define SHT_RELM SHT_RELA
164#define Elf32_RelM Elf32_Rela
165#define ELFCLASSM ELFCLASS32
166#define USE_GOT_ENTRIES
167#define GOT_ENTRY_SIZE 4
168#define USE_SINGLE
169#endif
170
171
172#if defined(__microblaze__)
173#define USE_SINGLE
174#include <linux/elf-em.h>
175#define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE)
176#define SHT_RELM SHT_RELA
177#define Elf32_RelM Elf32_Rela
178#define ELFCLASSM ELFCLASS32
179#endif
180
181
182#if defined(__mips__)
183#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
184#define SHT_RELM SHT_REL
185#define Elf32_RelM Elf32_Rel
186#define ELFCLASSM ELFCLASS32
187
188#ifndef EM_MIPS_RS3_LE
189#ifdef EM_MIPS_RS4_BE
190#define EM_MIPS_RS3_LE EM_MIPS_RS4_BE
191#else
192#define EM_MIPS_RS3_LE 10
193#endif
194#endif
195#define ARCHDATAM "__dbe_table"
196#endif
197
198
199#if defined(__nios2__)
200#define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2)
201#define SHT_RELM SHT_RELA
202#define Elf32_RelM Elf32_Rela
203#define ELFCLASSM ELFCLASS32
204#endif
205
206
207#if defined(__powerpc64__)
208#define MATCH_MACHINE(x) (x == EM_PPC64)
209#define SHT_RELM SHT_RELA
210#define Elf64_RelM Elf64_Rela
211#define ELFCLASSM ELFCLASS64
212#elif defined(__powerpc__)
213#define MATCH_MACHINE(x) (x == EM_PPC)
214#define SHT_RELM SHT_RELA
215#define Elf32_RelM Elf32_Rela
216#define ELFCLASSM ELFCLASS32
217#define USE_PLT_ENTRIES
218#define PLT_ENTRY_SIZE 16
219#define USE_PLT_LIST
220#define LIST_ARCHTYPE ElfW(Addr)
221#define USE_LIST
222#define ARCHDATAM "__ftr_fixup"
223#endif
224
225
226#if defined(__s390__)
227#define MATCH_MACHINE(x) (x == EM_S390)
228#define SHT_RELM SHT_RELA
229#define Elf32_RelM Elf32_Rela
230#define ELFCLASSM ELFCLASS32
231#define USE_PLT_ENTRIES
232#define PLT_ENTRY_SIZE 8
233#define USE_GOT_ENTRIES
234#define GOT_ENTRY_SIZE 8
235#define USE_SINGLE
236#endif
237
238
239#if defined(__sh__)
240#define MATCH_MACHINE(x) (x == EM_SH)
241#define SHT_RELM SHT_RELA
242#define Elf32_RelM Elf32_Rela
243#define ELFCLASSM ELFCLASS32
244#define USE_GOT_ENTRIES
245#define GOT_ENTRY_SIZE 4
246#define USE_SINGLE
247
248
249#if defined(__sh__) && BB_BIG_ENDIAN
250# error insmod.c may require changes for use on big endian SH
251#endif
252
253#if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__))
254#error insmod.c may require changes for SH1 or SH2 use
255#endif
256#endif
257
258
259#if defined(__sparc__)
260#define MATCH_MACHINE(x) (x == EM_SPARC)
261#define SHT_RELM SHT_RELA
262#define Elf32_RelM Elf32_Rela
263#define ELFCLASSM ELFCLASS32
264#endif
265
266
267#if defined(__v850e__)
268#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
269#define SHT_RELM SHT_RELA
270#define Elf32_RelM Elf32_Rela
271#define ELFCLASSM ELFCLASS32
272#define USE_PLT_ENTRIES
273#define PLT_ENTRY_SIZE 8
274#define USE_SINGLE
275#ifndef EM_CYGNUS_V850
276#define EM_CYGNUS_V850 0x9080
277#endif
278#define SYMBOL_PREFIX "_"
279#endif
280
281
282#if defined(__x86_64__)
283#define MATCH_MACHINE(x) (x == EM_X86_64)
284#define SHT_RELM SHT_RELA
285#define USE_GOT_ENTRIES
286#define GOT_ENTRY_SIZE 8
287#define USE_SINGLE
288#define Elf64_RelM Elf64_Rela
289#define ELFCLASSM ELFCLASS64
290#endif
291
292#ifndef SHT_RELM
293#error Sorry, but insmod.c does not yet support this architecture...
294#endif
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323#ifndef MODUTILS_MODULE_H
324
325
326
327
328
329#define tgt_sizeof_char sizeof(char)
330#define tgt_sizeof_short sizeof(short)
331#define tgt_sizeof_int sizeof(int)
332#define tgt_sizeof_long sizeof(long)
333#define tgt_sizeof_char_p sizeof(char *)
334#define tgt_sizeof_void_p sizeof(void *)
335#define tgt_long long
336
337#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64)
338#undef tgt_sizeof_long
339#undef tgt_sizeof_char_p
340#undef tgt_sizeof_void_p
341#undef tgt_long
342enum {
343 tgt_sizeof_long = 8,
344 tgt_sizeof_char_p = 8,
345 tgt_sizeof_void_p = 8
346};
347#define tgt_long long long
348#endif
349
350
351
352
353
354struct new_module_symbol {
355 unsigned long value;
356 unsigned long name;
357};
358
359struct new_module_persist;
360
361struct new_module_ref {
362 unsigned tgt_long dep;
363 unsigned tgt_long ref;
364 unsigned tgt_long next_ref;
365};
366
367struct new_module {
368 unsigned tgt_long size_of_struct;
369 unsigned tgt_long next;
370 unsigned tgt_long name;
371 unsigned tgt_long size;
372
373 tgt_long usecount;
374 unsigned tgt_long flags;
375
376 unsigned nsyms;
377 unsigned ndeps;
378
379 unsigned tgt_long syms;
380 unsigned tgt_long deps;
381 unsigned tgt_long refs;
382 unsigned tgt_long init;
383 unsigned tgt_long cleanup;
384 unsigned tgt_long ex_table_start;
385 unsigned tgt_long ex_table_end;
386#ifdef __alpha__
387 unsigned tgt_long gp;
388#endif
389
390 unsigned tgt_long persist_start;
391 unsigned tgt_long persist_end;
392 unsigned tgt_long can_unload;
393 unsigned tgt_long runsize;
394 const char *kallsyms_start;
395 const char *kallsyms_end;
396 const char *archdata_start;
397 const char *archdata_end;
398 const char *kernel_data;
399};
400
401#ifdef ARCHDATAM
402#define ARCHDATA_SEC_NAME ARCHDATAM
403#else
404#define ARCHDATA_SEC_NAME "__archdata"
405#endif
406#define KALLSYMS_SEC_NAME "__kallsyms"
407
408
409struct new_module_info {
410 unsigned long addr;
411 unsigned long size;
412 unsigned long flags;
413 long usecount;
414};
415
416
417enum {
418 NEW_MOD_RUNNING = 1,
419 NEW_MOD_DELETED = 2,
420 NEW_MOD_AUTOCLEAN = 4,
421 NEW_MOD_VISITED = 8,
422 NEW_MOD_USED_ONCE = 16
423};
424
425int init_module(const char *name, const struct new_module *);
426int query_module(const char *name, int which, void *buf,
427 size_t bufsize, size_t *ret);
428
429
430enum {
431 QM_MODULES = 1,
432 QM_DEPS = 2,
433 QM_REFS = 3,
434 QM_SYMBOLS = 4,
435 QM_INFO = 5
436};
437
438
439
440
441unsigned long create_module(const char *, size_t);
442int delete_module(const char *module, unsigned int flags);
443
444
445#endif
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479#ifndef MODUTILS_OBJ_H
480
481
482
483#include <elf.h>
484#include <endian.h>
485
486#ifndef ElfW
487# if ELFCLASSM == ELFCLASS32
488# define ElfW(x) Elf32_ ## x
489# define ELFW(x) ELF32_ ## x
490# else
491# define ElfW(x) Elf64_ ## x
492# define ELFW(x) ELF64_ ## x
493# endif
494#endif
495
496
497#ifndef ELF32_ST_INFO
498# define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
499#endif
500
501#ifndef ELF64_ST_INFO
502# define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
503#endif
504
505#define ELF_ST_BIND(info) ELFW(ST_BIND)(info)
506#define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info)
507#define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type)
508#define ELF_R_TYPE(val) ELFW(R_TYPE)(val)
509#define ELF_R_SYM(val) ELFW(R_SYM)(val)
510
511struct obj_string_patch;
512struct obj_symbol_patch;
513
514struct obj_section
515{
516 ElfW(Shdr) header;
517 const char *name;
518 char *contents;
519 struct obj_section *load_next;
520 int idx;
521};
522
523struct obj_symbol
524{
525 struct obj_symbol *next;
526 const char *name;
527 unsigned long value;
528 unsigned long size;
529 int secidx;
530 int info;
531 int ksymidx;
532 int referenced;
533};
534
535
536
537
538
539#define HASH_BUCKETS 521
540
541struct obj_file {
542 ElfW(Ehdr) header;
543 ElfW(Addr) baseaddr;
544 struct obj_section **sections;
545 struct obj_section *load_order;
546 struct obj_section **load_order_search_start;
547 struct obj_string_patch *string_patches;
548 struct obj_symbol_patch *symbol_patches;
549 int (*symbol_cmp)(const char *, const char *);
550 unsigned long (*symbol_hash)(const char *);
551 unsigned long local_symtab_size;
552 struct obj_symbol **local_symtab;
553 struct obj_symbol *symtab[HASH_BUCKETS];
554};
555
556enum obj_reloc {
557 obj_reloc_ok,
558 obj_reloc_overflow,
559 obj_reloc_dangerous,
560 obj_reloc_unhandled
561};
562
563struct obj_string_patch {
564 struct obj_string_patch *next;
565 int reloc_secidx;
566 ElfW(Addr) reloc_offset;
567 ElfW(Addr) string_offset;
568};
569
570struct obj_symbol_patch {
571 struct obj_symbol_patch *next;
572 int reloc_secidx;
573 ElfW(Addr) reloc_offset;
574 struct obj_symbol *sym;
575};
576
577
578
579
580static unsigned long obj_elf_hash(const char *);
581
582static unsigned long obj_elf_hash_n(const char *, unsigned long len);
583
584static struct obj_symbol *obj_find_symbol(struct obj_file *f,
585 const char *name);
586
587static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,
588 struct obj_symbol *sym);
589
590#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
591static void obj_set_symbol_compare(struct obj_file *f,
592 int (*cmp)(const char *, const char *),
593 unsigned long (*hash)(const char *));
594#endif
595
596static struct obj_section *obj_find_section(struct obj_file *f,
597 const char *name);
598
599static void obj_insert_section_load_order(struct obj_file *f,
600 struct obj_section *sec);
601
602static struct obj_section *obj_create_alloced_section(struct obj_file *f,
603 const char *name,
604 unsigned long align,
605 unsigned long size);
606
607static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
608 const char *name,
609 unsigned long align,
610 unsigned long size);
611
612static void *obj_extend_section(struct obj_section *sec, unsigned long more);
613
614static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
615 const char *string);
616
617static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
618 struct obj_symbol *sym);
619
620static void obj_check_undefineds(struct obj_file *f);
621
622static void obj_allocate_commons(struct obj_file *f);
623
624static unsigned long obj_load_size(struct obj_file *f);
625
626static int obj_relocate(struct obj_file *f, ElfW(Addr) base);
627
628#if !LOADBITS
629#define obj_load(image, image_size, loadprogbits) \
630 obj_load(image, image_size)
631#endif
632static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits);
633
634static int obj_create_image(struct obj_file *f, char *image);
635
636
637
638static struct obj_file *arch_new_file(void);
639
640static struct obj_section *arch_new_section(void);
641
642static struct obj_symbol *arch_new_symbol(void);
643
644static enum obj_reloc arch_apply_relocation(struct obj_file *f,
645 struct obj_section *targsec,
646
647 struct obj_symbol *sym,
648 ElfW(RelM) *rel, ElfW(Addr) value);
649
650static void arch_create_got(struct obj_file *f);
651#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
652static int obj_gpl_license(struct obj_file *f, const char **license);
653#endif
654#endif
655
656
657
658
659
660
661#ifdef SYMBOL_PREFIX
662#define SPFX SYMBOL_PREFIX
663#else
664#define SPFX ""
665#endif
666
667enum { STRVERSIONLEN = 64 };
668
669
670
671#define flag_force_load (option_mask32 & INSMOD_OPT_FORCE)
672#define flag_autoclean (option_mask32 & INSMOD_OPT_KERNELD)
673#define flag_verbose (option_mask32 & INSMOD_OPT_VERBOSE)
674#define flag_quiet (option_mask32 & INSMOD_OPT_SILENT)
675#define flag_noexport (option_mask32 & INSMOD_OPT_NO_EXPORT)
676#define flag_print_load_map (option_mask32 & INSMOD_OPT_PRINT_MAP)
677
678
679
680#if defined(USE_LIST)
681
682struct arch_list_entry
683{
684 struct arch_list_entry *next;
685 LIST_ARCHTYPE addend;
686 int offset;
687 int inited : 1;
688};
689
690#endif
691
692#if defined(USE_SINGLE)
693
694struct arch_single_entry
695{
696 int offset;
697 int inited : 1;
698 int allocated : 1;
699};
700
701#endif
702
703#if defined(__mips__)
704struct mips_hi16
705{
706 struct mips_hi16 *next;
707 ElfW(Addr) *addr;
708 ElfW(Addr) value;
709};
710#endif
711
712struct arch_file {
713 struct obj_file root;
714#if defined(USE_PLT_ENTRIES)
715 struct obj_section *plt;
716#endif
717#if defined(USE_GOT_ENTRIES)
718 struct obj_section *got;
719#endif
720#if defined(__mips__)
721 struct mips_hi16 *mips_hi16_list;
722#endif
723};
724
725struct arch_symbol {
726 struct obj_symbol root;
727#if defined(USE_PLT_ENTRIES)
728#if defined(USE_PLT_LIST)
729 struct arch_list_entry *pltent;
730#else
731 struct arch_single_entry pltent;
732#endif
733#endif
734#if defined(USE_GOT_ENTRIES)
735 struct arch_single_entry gotent;
736#endif
737};
738
739
740struct external_module {
741 const char *name;
742 ElfW(Addr) addr;
743 int used;
744 size_t nsyms;
745 struct new_module_symbol *syms;
746};
747
748static struct new_module_symbol *ksyms;
749static size_t nksyms;
750
751static struct external_module *ext_modules;
752static int n_ext_modules;
753static int n_ext_modules_used;
754
755
756
757
758static struct obj_file *arch_new_file(void)
759{
760 struct arch_file *f;
761 f = xzalloc(sizeof(*f));
762 return &f->root;
763}
764
765static struct obj_section *arch_new_section(void)
766{
767 return xzalloc(sizeof(struct obj_section));
768}
769
770static struct obj_symbol *arch_new_symbol(void)
771{
772 struct arch_symbol *sym;
773 sym = xzalloc(sizeof(*sym));
774 return &sym->root;
775}
776
777static enum obj_reloc
778arch_apply_relocation(struct obj_file *f,
779 struct obj_section *targsec,
780
781 struct obj_symbol *sym,
782 ElfW(RelM) *rel, ElfW(Addr) v)
783{
784#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
785 || defined(__sh__) || defined(__s390__) || defined(__x86_64__) \
786 || defined(__powerpc__) || defined(__mips__)
787 struct arch_file *ifile = (struct arch_file *) f;
788#endif
789 enum obj_reloc ret = obj_reloc_ok;
790 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
791#if defined(__arm__) || defined(__H8300H__) || defined(__H8300S__) \
792 || defined(__i386__) || defined(__mc68000__) || defined(__microblaze__) \
793 || defined(__mips__) || defined(__nios2__) || defined(__powerpc__) \
794 || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
795 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
796#endif
797#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
798 struct arch_symbol *isym = (struct arch_symbol *) sym;
799#endif
800#if defined(__arm__) || defined(__i386__) || defined(__mc68000__) \
801 || defined(__sh__) || defined(__s390__)
802#if defined(USE_GOT_ENTRIES)
803 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
804#endif
805#endif
806#if defined(USE_PLT_ENTRIES)
807 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
808 unsigned long *ip;
809# if defined(USE_PLT_LIST)
810 struct arch_list_entry *pe;
811# else
812 struct arch_single_entry *pe;
813# endif
814#endif
815
816 switch (ELF_R_TYPE(rel->r_info)) {
817
818#if defined(__arm__)
819
820 case R_ARM_NONE:
821 break;
822
823 case R_ARM_ABS32:
824 *loc += v;
825 break;
826
827 case R_ARM_GOT32:
828 goto bb_use_got;
829
830 case R_ARM_GOTPC:
831
832
833
834
835 *loc += got - dot;
836 break;
837
838 case R_ARM_PC24:
839 case R_ARM_PLT32:
840 goto bb_use_plt;
841
842 case R_ARM_GOTOFF:
843 *loc += v - got;
844 break;
845
846#elif defined(__cris__)
847
848 case R_CRIS_NONE:
849 break;
850
851 case R_CRIS_32:
852
853
854
855 *loc = v;
856 break;
857
858#elif defined(__H8300H__) || defined(__H8300S__)
859
860 case R_H8_DIR24R8:
861 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1);
862 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
863 break;
864 case R_H8_DIR24A8:
865 *loc += v;
866 break;
867 case R_H8_DIR32:
868 case R_H8_DIR32A16:
869 *loc += v;
870 break;
871 case R_H8_PCREL16:
872 v -= dot + 2;
873 if ((ElfW(Sword))v > 0x7fff ||
874 (ElfW(Sword))v < -(ElfW(Sword))0x8000)
875 ret = obj_reloc_overflow;
876 else
877 *(unsigned short *)loc = v;
878 break;
879 case R_H8_PCREL8:
880 v -= dot + 1;
881 if ((ElfW(Sword))v > 0x7f ||
882 (ElfW(Sword))v < -(ElfW(Sword))0x80)
883 ret = obj_reloc_overflow;
884 else
885 *(unsigned char *)loc = v;
886 break;
887
888#elif defined(__i386__)
889
890 case R_386_NONE:
891 break;
892
893 case R_386_32:
894 *loc += v;
895 break;
896
897 case R_386_PLT32:
898 case R_386_PC32:
899 case R_386_GOTOFF:
900 *loc += v - dot;
901 break;
902
903 case R_386_GLOB_DAT:
904 case R_386_JMP_SLOT:
905 *loc = v;
906 break;
907
908 case R_386_RELATIVE:
909 *loc += f->baseaddr;
910 break;
911
912 case R_386_GOTPC:
913 *loc += got - dot;
914 break;
915
916 case R_386_GOT32:
917 goto bb_use_got;
918 break;
919
920#elif defined(__microblaze__)
921 case R_MICROBLAZE_NONE:
922 case R_MICROBLAZE_64_NONE:
923 case R_MICROBLAZE_32_SYM_OP_SYM:
924 case R_MICROBLAZE_32_PCREL:
925 break;
926
927 case R_MICROBLAZE_64_PCREL: {
928
929
930
931
932
933
934
935
936
937 unsigned int temp = (loc[0] & 0xFFFF) << 16 |
938 (loc[1] & 0xFFFF);
939
940
941
942
943
944 temp += v - dot - 4;
945
946
947 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16;
948 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF);
949
950 break;
951 }
952
953 case R_MICROBLAZE_32:
954 *loc += v;
955 break;
956
957 case R_MICROBLAZE_64: {
958
959 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 |
960 (loc[1] & 0xFFFF);
961
962
963 temp1+=v;
964
965
966 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16;
967 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF);
968
969 break;
970 }
971
972 case R_MICROBLAZE_32_PCREL_LO:
973 case R_MICROBLAZE_32_LO:
974 case R_MICROBLAZE_SRO32:
975 case R_MICROBLAZE_SRW32:
976 ret = obj_reloc_unhandled;
977 break;
978
979#elif defined(__mc68000__)
980
981 case R_68K_NONE:
982 break;
983
984 case R_68K_32:
985 *loc += v;
986 break;
987
988 case R_68K_8:
989 if (v > 0xff) {
990 ret = obj_reloc_overflow;
991 }
992 *(char *)loc = v;
993 break;
994
995 case R_68K_16:
996 if (v > 0xffff) {
997 ret = obj_reloc_overflow;
998 }
999 *(short *)loc = v;
1000 break;
1001
1002 case R_68K_PC8:
1003 v -= dot;
1004 if ((ElfW(Sword))v > 0x7f
1005 || (ElfW(Sword))v < -(ElfW(Sword))0x80
1006 ) {
1007 ret = obj_reloc_overflow;
1008 }
1009 *(char *)loc = v;
1010 break;
1011
1012 case R_68K_PC16:
1013 v -= dot;
1014 if ((ElfW(Sword))v > 0x7fff
1015 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
1016 ) {
1017 ret = obj_reloc_overflow;
1018 }
1019 *(short *)loc = v;
1020 break;
1021
1022 case R_68K_PC32:
1023 *(int *)loc = v - dot;
1024 break;
1025
1026 case R_68K_GLOB_DAT:
1027 case R_68K_JMP_SLOT:
1028 *loc = v;
1029 break;
1030
1031 case R_68K_RELATIVE:
1032 *(int *)loc += f->baseaddr;
1033 break;
1034
1035 case R_68K_GOT32:
1036 goto bb_use_got;
1037
1038# ifdef R_68K_GOTOFF
1039 case R_68K_GOTOFF:
1040 *loc += v - got;
1041 break;
1042# endif
1043
1044#elif defined(__mips__)
1045
1046 case R_MIPS_NONE:
1047 break;
1048
1049 case R_MIPS_32:
1050 *loc += v;
1051 break;
1052
1053 case R_MIPS_26:
1054 if (v % 4)
1055 ret = obj_reloc_dangerous;
1056 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
1057 ret = obj_reloc_overflow;
1058 *loc =
1059 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
1060 0x03ffffff);
1061 break;
1062
1063 case R_MIPS_HI16:
1064 {
1065 struct mips_hi16 *n;
1066
1067
1068
1069
1070 n = xmalloc(sizeof *n);
1071 n->addr = loc;
1072 n->value = v;
1073 n->next = ifile->mips_hi16_list;
1074 ifile->mips_hi16_list = n;
1075 break;
1076 }
1077
1078 case R_MIPS_LO16:
1079 {
1080 unsigned long insnlo = *loc;
1081 ElfW(Addr) val, vallo;
1082
1083
1084 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
1085
1086 if (ifile->mips_hi16_list != NULL) {
1087 struct mips_hi16 *l;
1088
1089 l = ifile->mips_hi16_list;
1090 while (l != NULL) {
1091 struct mips_hi16 *next;
1092 unsigned long insn;
1093
1094
1095
1096
1097 insn = *l->addr;
1098 val =
1099 ((insn & 0xffff) << 16) +
1100 vallo;
1101 val += v;
1102
1103
1104
1105 val =
1106 ((val >> 16) +
1107 ((val & 0x8000) !=
1108 0)) & 0xffff;
1109
1110 insn = (insn & ~0xffff) | val;
1111 *l->addr = insn;
1112
1113 next = l->next;
1114 free(l);
1115 l = next;
1116 }
1117
1118 ifile->mips_hi16_list = NULL;
1119 }
1120
1121
1122 val = v + vallo;
1123 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
1124 *loc = insnlo;
1125 break;
1126 }
1127
1128#elif defined(__nios2__)
1129
1130 case R_NIOS2_NONE:
1131 break;
1132
1133 case R_NIOS2_BFD_RELOC_32:
1134 *loc += v;
1135 break;
1136
1137 case R_NIOS2_BFD_RELOC_16:
1138 if (v > 0xffff) {
1139 ret = obj_reloc_overflow;
1140 }
1141 *(short *)loc = v;
1142 break;
1143
1144 case R_NIOS2_BFD_RELOC_8:
1145 if (v > 0xff) {
1146 ret = obj_reloc_overflow;
1147 }
1148 *(char *)loc = v;
1149 break;
1150
1151 case R_NIOS2_S16:
1152 {
1153 Elf32_Addr word;
1154
1155 if ((Elf32_Sword)v > 0x7fff
1156 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1157 ) {
1158 ret = obj_reloc_overflow;
1159 }
1160
1161 word = *loc;
1162 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1163 (word & 0x3f);
1164 }
1165 break;
1166
1167 case R_NIOS2_U16:
1168 {
1169 Elf32_Addr word;
1170
1171 if (v > 0xffff) {
1172 ret = obj_reloc_overflow;
1173 }
1174
1175 word = *loc;
1176 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1177 (word & 0x3f);
1178 }
1179 break;
1180
1181 case R_NIOS2_PCREL16:
1182 {
1183 Elf32_Addr word;
1184
1185 v -= dot + 4;
1186 if ((Elf32_Sword)v > 0x7fff
1187 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1188 ) {
1189 ret = obj_reloc_overflow;
1190 }
1191
1192 word = *loc;
1193 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1194 }
1195 break;
1196
1197 case R_NIOS2_GPREL:
1198 {
1199 Elf32_Addr word, gp;
1200
1201 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
1202 v -= gp;
1203 if ((Elf32_Sword)v > 0x7fff
1204 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1205 ) {
1206 ret = obj_reloc_overflow;
1207 }
1208
1209 word = *loc;
1210 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f);
1211 }
1212 break;
1213
1214 case R_NIOS2_CALL26:
1215 if (v & 3)
1216 ret = obj_reloc_dangerous;
1217 if ((v >> 28) != (dot >> 28))
1218 ret = obj_reloc_overflow;
1219 *loc = (*loc & 0x3f) | ((v >> 2) << 6);
1220 break;
1221
1222 case R_NIOS2_IMM5:
1223 {
1224 Elf32_Addr word;
1225
1226 if (v > 0x1f) {
1227 ret = obj_reloc_overflow;
1228 }
1229
1230 word = *loc & ~0x7c0;
1231 *loc = word | ((v & 0x1f) << 6);
1232 }
1233 break;
1234
1235 case R_NIOS2_IMM6:
1236 {
1237 Elf32_Addr word;
1238
1239 if (v > 0x3f) {
1240 ret = obj_reloc_overflow;
1241 }
1242
1243 word = *loc & ~0xfc0;
1244 *loc = word | ((v & 0x3f) << 6);
1245 }
1246 break;
1247
1248 case R_NIOS2_IMM8:
1249 {
1250 Elf32_Addr word;
1251
1252 if (v > 0xff) {
1253 ret = obj_reloc_overflow;
1254 }
1255
1256 word = *loc & ~0x3fc0;
1257 *loc = word | ((v & 0xff) << 6);
1258 }
1259 break;
1260
1261 case R_NIOS2_HI16:
1262 {
1263 Elf32_Addr word;
1264
1265 word = *loc;
1266 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) |
1267 (word & 0x3f);
1268 }
1269 break;
1270
1271 case R_NIOS2_LO16:
1272 {
1273 Elf32_Addr word;
1274
1275 word = *loc;
1276 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) |
1277 (word & 0x3f);
1278 }
1279 break;
1280
1281 case R_NIOS2_HIADJ16:
1282 {
1283 Elf32_Addr word1, word2;
1284
1285 word1 = *loc;
1286 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff;
1287 *loc = ((((word1 >> 22) << 16) | word2) << 6) |
1288 (word1 & 0x3f);
1289 }
1290 break;
1291
1292#elif defined(__powerpc64__)
1293
1294
1295#elif defined(__powerpc__)
1296
1297 case R_PPC_ADDR16_HA:
1298 *(unsigned short *)loc = (v + 0x8000) >> 16;
1299 break;
1300
1301 case R_PPC_ADDR16_HI:
1302 *(unsigned short *)loc = v >> 16;
1303 break;
1304
1305 case R_PPC_ADDR16_LO:
1306 *(unsigned short *)loc = v;
1307 break;
1308
1309 case R_PPC_REL24:
1310 goto bb_use_plt;
1311
1312 case R_PPC_REL32:
1313 *loc = v - dot;
1314 break;
1315
1316 case R_PPC_ADDR32:
1317 *loc = v;
1318 break;
1319
1320#elif defined(__s390__)
1321
1322 case R_390_32:
1323 *(unsigned int *) loc += v;
1324 break;
1325 case R_390_16:
1326 *(unsigned short *) loc += v;
1327 break;
1328 case R_390_8:
1329 *(unsigned char *) loc += v;
1330 break;
1331
1332 case R_390_PC32:
1333 *(unsigned int *) loc += v - dot;
1334 break;
1335 case R_390_PC16DBL:
1336 *(unsigned short *) loc += (v - dot) >> 1;
1337 break;
1338 case R_390_PC16:
1339 *(unsigned short *) loc += v - dot;
1340 break;
1341
1342 case R_390_PLT32:
1343 case R_390_PLT16DBL:
1344
1345 pe = (struct arch_single_entry *) &isym->pltent;
1346 if (pe->inited == 0) {
1347 ip = (unsigned long *)(ifile->plt->contents + pe->offset);
1348 ip[0] = 0x0d105810;
1349 ip[1] = 0x100607f1;
1350 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1351 ip[2] = v - 2;
1352 else
1353 ip[2] = v;
1354 pe->inited = 1;
1355 }
1356
1357
1358 v = plt + pe->offset - dot;
1359 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32)
1360 *(unsigned int *) loc = (unsigned int) v;
1361 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL)
1362 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
1363 break;
1364
1365 case R_390_GLOB_DAT:
1366 case R_390_JMP_SLOT:
1367 *loc = v;
1368 break;
1369
1370 case R_390_RELATIVE:
1371 *loc += f->baseaddr;
1372 break;
1373
1374 case R_390_GOTPC:
1375 *(unsigned long *) loc += got - dot;
1376 break;
1377
1378 case R_390_GOT12:
1379 case R_390_GOT16:
1380 case R_390_GOT32:
1381 if (!isym->gotent.inited)
1382 {
1383 isym->gotent.inited = 1;
1384 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v;
1385 }
1386 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12)
1387 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
1388 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16)
1389 *(unsigned short *) loc += isym->gotent.offset;
1390 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32)
1391 *(unsigned int *) loc += isym->gotent.offset;
1392 break;
1393
1394# ifndef R_390_GOTOFF32
1395# define R_390_GOTOFF32 R_390_GOTOFF
1396# endif
1397 case R_390_GOTOFF32:
1398 *loc += v - got;
1399 break;
1400
1401#elif defined(__sh__)
1402
1403 case R_SH_NONE:
1404 break;
1405
1406 case R_SH_DIR32:
1407 *loc += v;
1408 break;
1409
1410 case R_SH_REL32:
1411 *loc += v - dot;
1412 break;
1413
1414 case R_SH_PLT32:
1415 *loc = v - dot;
1416 break;
1417
1418 case R_SH_GLOB_DAT:
1419 case R_SH_JMP_SLOT:
1420 *loc = v;
1421 break;
1422
1423 case R_SH_RELATIVE:
1424 *loc = f->baseaddr + rel->r_addend;
1425 break;
1426
1427 case R_SH_GOTPC:
1428 *loc = got - dot + rel->r_addend;
1429 break;
1430
1431 case R_SH_GOT32:
1432 goto bb_use_got;
1433
1434 case R_SH_GOTOFF:
1435 *loc = v - got;
1436 break;
1437
1438# if defined(__SH5__)
1439 case R_SH_IMM_MEDLOW16:
1440 case R_SH_IMM_LOW16:
1441 {
1442 ElfW(Addr) word;
1443
1444 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16)
1445 v >>= 16;
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455 word = *loc & ~0x3fffc00;
1456 word |= (v & 0xffff) << 10;
1457
1458 *loc = word;
1459
1460 break;
1461 }
1462
1463 case R_SH_IMM_MEDLOW16_PCREL:
1464 case R_SH_IMM_LOW16_PCREL:
1465 {
1466 ElfW(Addr) word;
1467
1468 word = *loc & ~0x3fffc00;
1469
1470 v -= dot;
1471
1472 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL)
1473 v >>= 16;
1474
1475 word |= (v & 0xffff) << 10;
1476
1477 *loc = word;
1478
1479 break;
1480 }
1481# endif
1482
1483#elif defined(__v850e__)
1484
1485 case R_V850_NONE:
1486 break;
1487
1488 case R_V850_32:
1489
1490
1491
1492 v += ((unsigned short *)loc)[0];
1493 v += ((unsigned short *)loc)[1] << 16;
1494 ((unsigned short *)loc)[0] = v & 0xffff;
1495 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
1496 break;
1497
1498 case R_V850_22_PCREL:
1499 goto bb_use_plt;
1500
1501#elif defined(__x86_64__)
1502
1503 case R_X86_64_NONE:
1504 break;
1505
1506 case R_X86_64_64:
1507 *loc += v;
1508 break;
1509
1510 case R_X86_64_32:
1511 *(unsigned int *) loc += v;
1512 if (v > 0xffffffff)
1513 {
1514 ret = obj_reloc_overflow;
1515
1516 }
1517 break;
1518
1519 case R_X86_64_32S:
1520 *(signed int *) loc += v;
1521 break;
1522
1523 case R_X86_64_16:
1524 *(unsigned short *) loc += v;
1525 break;
1526
1527 case R_X86_64_8:
1528 *(unsigned char *) loc += v;
1529 break;
1530
1531 case R_X86_64_PC32:
1532 *(unsigned int *) loc += v - dot;
1533 break;
1534
1535 case R_X86_64_PC16:
1536 *(unsigned short *) loc += v - dot;
1537 break;
1538
1539 case R_X86_64_PC8:
1540 *(unsigned char *) loc += v - dot;
1541 break;
1542
1543 case R_X86_64_GLOB_DAT:
1544 case R_X86_64_JUMP_SLOT:
1545 *loc = v;
1546 break;
1547
1548 case R_X86_64_RELATIVE:
1549 *loc += f->baseaddr;
1550 break;
1551
1552 case R_X86_64_GOT32:
1553 case R_X86_64_GOTPCREL:
1554 goto bb_use_got;
1555# if 0
1556 if (!isym->gotent.reloc_done)
1557 {
1558 isym->gotent.reloc_done = 1;
1559 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
1560 }
1561
1562 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL)
1563 *(unsigned int *) loc += v + isym->gotent.offset;
1564 else
1565 *loc += isym->gotent.offset;
1566 break;
1567# endif
1568
1569#else
1570# warning "no idea how to handle relocations on your arch"
1571#endif
1572
1573 default:
1574 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info));
1575 ret = obj_reloc_unhandled;
1576 break;
1577
1578#if defined(USE_PLT_ENTRIES)
1579
1580bb_use_plt:
1581
1582
1583
1584#if defined(USE_PLT_LIST)
1585 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;)
1586 pe = pe->next;
1587#else
1588 pe = &isym->pltent;
1589#endif
1590
1591 if (! pe->inited) {
1592 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
1593
1594
1595
1596#if defined(__arm__)
1597 ip[0] = 0xe51ff004;
1598 ip[1] = v;
1599#endif
1600#if defined(__powerpc__)
1601 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16);
1602 ip[1] = 0x396b0000 + (v & 0xffff);
1603 ip[2] = 0x7d6903a6;
1604 ip[3] = 0x4e800420;
1605#endif
1606#if defined(__v850e__)
1607
1608
1609
1610 ip[0] = 0x0621 + ((v & 0xffff) << 16);
1611 ip[1] = ((v >> 16) & 0xffff) + 0x610000;
1612#endif
1613 pe->inited = 1;
1614 }
1615
1616
1617 v -= dot;
1618
1619#if defined(__arm__) || defined(__powerpc__)
1620 if ((int)v < -0x02000000 || (int)v >= 0x02000000)
1621#elif defined(__v850e__)
1622 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000)
1623#endif
1624
1625 v = plt + pe->offset - dot;
1626
1627#if defined(__v850e__)
1628 if (v & 1)
1629#else
1630 if (v & 3)
1631#endif
1632 ret = obj_reloc_dangerous;
1633
1634
1635#if defined(__arm__)
1636
1637 v >>= 2;
1638
1639 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
1640#endif
1641#if defined(__powerpc__)
1642 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
1643#endif
1644#if defined(__v850e__)
1645
1646
1647
1648 ((unsigned short *)loc)[0] =
1649 (*(unsigned short *)loc & 0xffc0)
1650 | ((v >> 16) & 0x3f);
1651 ((unsigned short *)loc)[1] =
1652 (v & 0xffff);
1653#endif
1654 break;
1655#endif
1656
1657#if defined(USE_GOT_ENTRIES)
1658bb_use_got:
1659
1660
1661 if (!isym->gotent.inited) {
1662 isym->gotent.inited = 1;
1663 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
1664 }
1665
1666#if defined(__sh__)
1667 *loc += isym->gotent.offset + rel->r_addend;
1668#elif defined(__i386__) || defined(__arm__) || defined(__mc68000__)
1669 *loc += isym->gotent.offset;
1670#endif
1671 break;
1672
1673#endif
1674 }
1675
1676 return ret;
1677}
1678
1679
1680#if defined(USE_LIST)
1681
1682static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list,
1683 int offset, int size)
1684{
1685 struct arch_list_entry *pe;
1686
1687 for (pe = *list; pe != NULL; pe = pe->next) {
1688 if (pe->addend == rel->r_addend) {
1689 break;
1690 }
1691 }
1692
1693 if (pe == NULL) {
1694 pe = xzalloc(sizeof(struct arch_list_entry));
1695 pe->next = *list;
1696 pe->addend = rel->r_addend;
1697 pe->offset = offset;
1698
1699 *list = pe;
1700 return size;
1701 }
1702 return 0;
1703}
1704
1705#endif
1706
1707#if defined(USE_SINGLE)
1708
1709static int arch_single_init( struct arch_single_entry *single,
1710 int offset, int size)
1711{
1712 if (single->allocated == 0) {
1713 single->allocated = 1;
1714 single->offset = offset;
1715 single->inited = 0;
1716 return size;
1717 }
1718 return 0;
1719}
1720
1721#endif
1722
1723#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1724
1725static struct obj_section *arch_xsect_init(struct obj_file *f, const char *name,
1726 int offset, int size)
1727{
1728 struct obj_section *myrelsec = obj_find_section(f, name);
1729
1730 if (offset == 0) {
1731 offset += size;
1732 }
1733
1734 if (myrelsec) {
1735 obj_extend_section(myrelsec, offset);
1736 } else {
1737 myrelsec = obj_create_alloced_section(f, name,
1738 size, offset);
1739 }
1740
1741 return myrelsec;
1742}
1743
1744#endif
1745
1746static void arch_create_got(struct obj_file *f)
1747{
1748#if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES)
1749 struct arch_file *ifile = (struct arch_file *) f;
1750 int i;
1751#if defined(USE_GOT_ENTRIES)
1752 int got_offset = 0, got_needed = 0, got_allocate;
1753#endif
1754#if defined(USE_PLT_ENTRIES)
1755 int plt_offset = 0, plt_needed = 0, plt_allocate;
1756#endif
1757 struct obj_section *relsec, *symsec, *strsec;
1758 ElfW(RelM) *rel, *relend;
1759 ElfW(Sym) *symtab, *extsym;
1760 const char *strtab, *name;
1761 struct arch_symbol *intsym;
1762
1763 for (i = 0; i < f->header.e_shnum; ++i) {
1764 relsec = f->sections[i];
1765 if (relsec->header.sh_type != SHT_RELM)
1766 continue;
1767
1768 symsec = f->sections[relsec->header.sh_link];
1769 strsec = f->sections[symsec->header.sh_link];
1770
1771 rel = (ElfW(RelM) *) relsec->contents;
1772 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
1773 symtab = (ElfW(Sym) *) symsec->contents;
1774 strtab = (const char *) strsec->contents;
1775
1776 for (; rel < relend; ++rel) {
1777 extsym = &symtab[ELF_R_SYM(rel->r_info)];
1778
1779#if defined(USE_GOT_ENTRIES)
1780 got_allocate = 0;
1781#endif
1782#if defined(USE_PLT_ENTRIES)
1783 plt_allocate = 0;
1784#endif
1785
1786 switch (ELF_R_TYPE(rel->r_info)) {
1787#if defined(__arm__)
1788 case R_ARM_PC24:
1789 case R_ARM_PLT32:
1790 plt_allocate = 1;
1791 break;
1792
1793 case R_ARM_GOTOFF:
1794 case R_ARM_GOTPC:
1795 got_needed = 1;
1796 continue;
1797
1798 case R_ARM_GOT32:
1799 got_allocate = 1;
1800 break;
1801
1802#elif defined(__i386__)
1803 case R_386_GOTPC:
1804 case R_386_GOTOFF:
1805 got_needed = 1;
1806 continue;
1807
1808 case R_386_GOT32:
1809 got_allocate = 1;
1810 break;
1811
1812#elif defined(__powerpc__)
1813 case R_PPC_REL24:
1814 plt_allocate = 1;
1815 break;
1816
1817#elif defined(__mc68000__)
1818 case R_68K_GOT32:
1819 got_allocate = 1;
1820 break;
1821
1822#ifdef R_68K_GOTOFF
1823 case R_68K_GOTOFF:
1824 got_needed = 1;
1825 continue;
1826#endif
1827
1828#elif defined(__sh__)
1829 case R_SH_GOT32:
1830 got_allocate = 1;
1831 break;
1832
1833 case R_SH_GOTPC:
1834 case R_SH_GOTOFF:
1835 got_needed = 1;
1836 continue;
1837
1838#elif defined(__v850e__)
1839 case R_V850_22_PCREL:
1840 plt_needed = 1;
1841 break;
1842
1843#endif
1844 default:
1845 continue;
1846 }
1847
1848 if (extsym->st_name != 0) {
1849 name = strtab + extsym->st_name;
1850 } else {
1851 name = f->sections[extsym->st_shndx]->name;
1852 }
1853 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
1854#if defined(USE_GOT_ENTRIES)
1855 if (got_allocate) {
1856 got_offset += arch_single_init(
1857 &intsym->gotent,
1858 got_offset, GOT_ENTRY_SIZE);
1859
1860 got_needed = 1;
1861 }
1862#endif
1863#if defined(USE_PLT_ENTRIES)
1864 if (plt_allocate) {
1865#if defined(USE_PLT_LIST)
1866 plt_offset += arch_list_add(
1867 rel, &intsym->pltent,
1868 plt_offset, PLT_ENTRY_SIZE);
1869#else
1870 plt_offset += arch_single_init(
1871 &intsym->pltent,
1872 plt_offset, PLT_ENTRY_SIZE);
1873#endif
1874 plt_needed = 1;
1875 }
1876#endif
1877 }
1878 }
1879
1880#if defined(USE_GOT_ENTRIES)
1881 if (got_needed) {
1882 ifile->got = arch_xsect_init(f, ".got", got_offset,
1883 GOT_ENTRY_SIZE);
1884 }
1885#endif
1886
1887#if defined(USE_PLT_ENTRIES)
1888 if (plt_needed) {
1889 ifile->plt = arch_xsect_init(f, ".plt", plt_offset,
1890 PLT_ENTRY_SIZE);
1891 }
1892#endif
1893
1894#endif
1895}
1896
1897
1898
1899
1900static unsigned long obj_elf_hash_n(const char *name, unsigned long n)
1901{
1902 unsigned long h = 0;
1903 unsigned long g;
1904 unsigned char ch;
1905
1906 while (n > 0) {
1907 ch = *name++;
1908 h = (h << 4) + ch;
1909 g = (h & 0xf0000000);
1910 if (g != 0) {
1911 h ^= g >> 24;
1912 h &= ~g;
1913 }
1914 n--;
1915 }
1916 return h;
1917}
1918
1919static unsigned long obj_elf_hash(const char *name)
1920{
1921 return obj_elf_hash_n(name, strlen(name));
1922}
1923
1924#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
1925
1926
1927static int ncv_strcmp(const char *a, const char *b)
1928{
1929 size_t alen = strlen(a), blen = strlen(b);
1930
1931 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R')
1932 return strncmp(a, b, alen);
1933 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R')
1934 return strncmp(a, b, blen);
1935 else
1936 return strcmp(a, b);
1937}
1938
1939
1940
1941
1942static unsigned long ncv_symbol_hash(const char *str)
1943{
1944 size_t len = strlen(str);
1945 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R')
1946 len -= 10;
1947 return obj_elf_hash_n(str, len);
1948}
1949
1950static void
1951obj_set_symbol_compare(struct obj_file *f,
1952 int (*cmp) (const char *, const char *),
1953 unsigned long (*hash) (const char *))
1954{
1955 if (cmp)
1956 f->symbol_cmp = cmp;
1957 if (hash) {
1958 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next;
1959 int i;
1960
1961 f->symbol_hash = hash;
1962
1963 memcpy(tmptab, f->symtab, sizeof(tmptab));
1964 memset(f->symtab, 0, sizeof(f->symtab));
1965
1966 for (i = 0; i < HASH_BUCKETS; ++i)
1967 for (sym = tmptab[i]; sym; sym = next) {
1968 unsigned long h = hash(sym->name) % HASH_BUCKETS;
1969 next = sym->next;
1970 sym->next = f->symtab[h];
1971 f->symtab[h] = sym;
1972 }
1973 }
1974}
1975
1976#endif
1977
1978static struct obj_symbol *
1979obj_add_symbol(struct obj_file *f, const char *name,
1980 unsigned long symidx, int info,
1981 int secidx, ElfW(Addr) value,
1982 unsigned long size)
1983{
1984 struct obj_symbol *sym;
1985 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
1986 int n_type = ELF_ST_TYPE(info);
1987 int n_binding = ELF_ST_BIND(info);
1988
1989 for (sym = f->symtab[hash]; sym; sym = sym->next) {
1990 if (f->symbol_cmp(sym->name, name) == 0) {
1991 int o_secidx = sym->secidx;
1992 int o_info = sym->info;
1993 int o_type = ELF_ST_TYPE(o_info);
1994 int o_binding = ELF_ST_BIND(o_info);
1995
1996
1997
1998 if (secidx == SHN_UNDEF)
1999 return sym;
2000 else if (o_secidx == SHN_UNDEF)
2001 goto found;
2002 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) {
2003
2004
2005
2006
2007
2008
2009 struct obj_symbol *nsym, **p;
2010
2011 nsym = arch_new_symbol();
2012 nsym->next = sym->next;
2013 nsym->ksymidx = -1;
2014
2015
2016 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next)
2017 continue;
2018 *p = sym = nsym;
2019 goto found;
2020 } else if (n_binding == STB_LOCAL) {
2021
2022
2023 sym = arch_new_symbol();
2024 sym->next = NULL;
2025 sym->ksymidx = -1;
2026 f->local_symtab[symidx] = sym;
2027 goto found;
2028 } else if (n_binding == STB_WEAK)
2029 return sym;
2030 else if (o_binding == STB_WEAK)
2031 goto found;
2032
2033
2034 else if (secidx == SHN_COMMON
2035 && (o_type == STT_NOTYPE || o_type == STT_OBJECT))
2036 return sym;
2037 else if (o_secidx == SHN_COMMON
2038 && (n_type == STT_NOTYPE || n_type == STT_OBJECT))
2039 goto found;
2040 else {
2041
2042
2043 if (secidx <= SHN_HIRESERVE)
2044 bb_error_msg("%s multiply defined", name);
2045 return sym;
2046 }
2047 }
2048 }
2049
2050
2051 sym = arch_new_symbol();
2052 sym->next = f->symtab[hash];
2053 f->symtab[hash] = sym;
2054 sym->ksymidx = -1;
2055 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != (unsigned long)(-1)) {
2056 if (symidx >= f->local_symtab_size)
2057 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld",
2058 name, (long) symidx, (long) f->local_symtab_size);
2059 else
2060 f->local_symtab[symidx] = sym;
2061 }
2062
2063found:
2064 sym->name = name;
2065 sym->value = value;
2066 sym->size = size;
2067 sym->secidx = secidx;
2068 sym->info = info;
2069
2070 return sym;
2071}
2072
2073static struct obj_symbol *
2074obj_find_symbol(struct obj_file *f, const char *name)
2075{
2076 struct obj_symbol *sym;
2077 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS;
2078
2079 for (sym = f->symtab[hash]; sym; sym = sym->next)
2080 if (f->symbol_cmp(sym->name, name) == 0)
2081 return sym;
2082 return NULL;
2083}
2084
2085static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym)
2086{
2087 if (sym) {
2088 if (sym->secidx >= SHN_LORESERVE)
2089 return sym->value;
2090 return sym->value + f->sections[sym->secidx]->header.sh_addr;
2091 }
2092
2093 return 0;
2094}
2095
2096static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
2097{
2098 int i, n = f->header.e_shnum;
2099
2100 for (i = 0; i < n; ++i)
2101 if (strcmp(f->sections[i]->name, name) == 0)
2102 return f->sections[i];
2103 return NULL;
2104}
2105
2106static int obj_load_order_prio(struct obj_section *a)
2107{
2108 unsigned long af, ac;
2109
2110 af = a->header.sh_flags;
2111
2112 ac = 0;
2113 if (a->name[0] != '.' || strlen(a->name) != 10
2114 || strcmp(a->name + 5, ".init") != 0
2115 ) {
2116 ac |= 32;
2117 }
2118 if (af & SHF_ALLOC)
2119 ac |= 16;
2120 if (!(af & SHF_WRITE))
2121 ac |= 8;
2122 if (af & SHF_EXECINSTR)
2123 ac |= 4;
2124 if (a->header.sh_type != SHT_NOBITS)
2125 ac |= 2;
2126
2127 return ac;
2128}
2129
2130static void
2131obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec)
2132{
2133 struct obj_section **p;
2134 int prio = obj_load_order_prio(sec);
2135 for (p = f->load_order_search_start; *p; p = &(*p)->load_next)
2136 if (obj_load_order_prio(*p) < prio)
2137 break;
2138 sec->load_next = *p;
2139 *p = sec;
2140}
2141
2142static struct obj_section *helper_create_alloced_section(struct obj_file *f,
2143 const char *name,
2144 unsigned long align,
2145 unsigned long size)
2146{
2147 int newidx = f->header.e_shnum++;
2148 struct obj_section *sec;
2149
2150 f->sections = xrealloc_vector(f->sections, 2, newidx);
2151 f->sections[newidx] = sec = arch_new_section();
2152
2153 sec->header.sh_type = SHT_PROGBITS;
2154 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2155 sec->header.sh_size = size;
2156 sec->header.sh_addralign = align;
2157 sec->name = name;
2158 sec->idx = newidx;
2159 if (size)
2160 sec->contents = xzalloc(size);
2161
2162 return sec;
2163}
2164
2165static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2166 const char *name,
2167 unsigned long align,
2168 unsigned long size)
2169{
2170 struct obj_section *sec;
2171
2172 sec = helper_create_alloced_section(f, name, align, size);
2173 obj_insert_section_load_order(f, sec);
2174 return sec;
2175}
2176
2177static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2178 const char *name,
2179 unsigned long align,
2180 unsigned long size)
2181{
2182 struct obj_section *sec;
2183
2184 sec = helper_create_alloced_section(f, name, align, size);
2185 sec->load_next = f->load_order;
2186 f->load_order = sec;
2187 if (f->load_order_search_start == &f->load_order)
2188 f->load_order_search_start = &sec->load_next;
2189
2190 return sec;
2191}
2192
2193static void *obj_extend_section(struct obj_section *sec, unsigned long more)
2194{
2195 unsigned long oldsize = sec->header.sh_size;
2196 if (more) {
2197 sec->header.sh_size += more;
2198 sec->contents = xrealloc(sec->contents, sec->header.sh_size);
2199 }
2200 return sec->contents + oldsize;
2201}
2202
2203
2204
2205
2206
2207static int add_symbols_from(struct obj_file *f,
2208 int idx,
2209 struct new_module_symbol *syms,
2210 size_t nsyms)
2211{
2212 struct new_module_symbol *s;
2213 size_t i;
2214 int used = 0;
2215#ifdef SYMBOL_PREFIX
2216 char *name_buf = NULL;
2217 size_t name_alloced_size = 0;
2218#endif
2219#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2220 int gpl;
2221
2222 gpl = obj_gpl_license(f, NULL) == 0;
2223#endif
2224 for (i = 0, s = syms; i < nsyms; ++i, ++s) {
2225
2226
2227
2228
2229 struct obj_symbol *sym;
2230 char *name;
2231
2232
2233
2234
2235
2236
2237
2238 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) {
2239#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
2240 if (gpl)
2241 s->name += 8;
2242 else
2243#endif
2244 continue;
2245 }
2246 name = (char *)s->name;
2247
2248#ifdef SYMBOL_PREFIX
2249
2250
2251
2252 size_t extra = sizeof SYMBOL_PREFIX;
2253 size_t name_size = strlen(name) + extra;
2254 if (name_size > name_alloced_size) {
2255 name_alloced_size = name_size * 2;
2256 name_buf = alloca(name_alloced_size);
2257 }
2258 strcpy(name_buf, SYMBOL_PREFIX);
2259 strcpy(name_buf + extra - 1, name);
2260 name = name_buf;
2261#endif
2262
2263 sym = obj_find_symbol(f, name);
2264 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) {
2265#ifdef SYMBOL_PREFIX
2266
2267 name = xmalloc(name_size);
2268 strcpy(name, name_buf);
2269#endif
2270 sym = obj_add_symbol(f, name, -1,
2271 ELF_ST_INFO(STB_GLOBAL,
2272 STT_NOTYPE),
2273 idx, s->value, 0);
2274
2275
2276 if (sym->secidx == idx)
2277 used = 1;
2278 }
2279 }
2280
2281 return used;
2282}
2283
2284static void add_kernel_symbols(struct obj_file *f)
2285{
2286 struct external_module *m;
2287 int i, nused = 0;
2288
2289
2290
2291 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) {
2292 if (m->nsyms
2293 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms)
2294 ) {
2295 m->used = 1;
2296 ++nused;
2297 }
2298 }
2299
2300 n_ext_modules_used = nused;
2301
2302
2303
2304 if (nksyms)
2305 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);
2306}
2307
2308static char *get_modinfo_value(struct obj_file *f, const char *key)
2309{
2310 struct obj_section *sec;
2311 char *p, *v, *n, *ep;
2312 size_t klen = strlen(key);
2313
2314 sec = obj_find_section(f, ".modinfo");
2315 if (sec == NULL)
2316 return NULL;
2317 p = sec->contents;
2318 ep = p + sec->header.sh_size;
2319 while (p < ep) {
2320 v = strchr(p, '=');
2321 n = strchr(p, '\0');
2322 if (v) {
2323 if (p + klen == v && strncmp(p, key, klen) == 0)
2324 return v + 1;
2325 } else {
2326 if (p + klen == n && strcmp(p, key) == 0)
2327 return n;
2328 }
2329 p = n + 1;
2330 }
2331
2332 return NULL;
2333}
2334
2335
2336
2337
2338
2339
2340
2341
2342static char *next_arg(char *args, char **param, char **val)
2343{
2344 unsigned int i, equals = 0;
2345 int in_quote = 0, quoted = 0;
2346 char *next;
2347
2348 if (*args == '"') {
2349 args++;
2350 in_quote = 1;
2351 quoted = 1;
2352 }
2353
2354 for (i = 0; args[i]; i++) {
2355 if (args[i] == ' ' && !in_quote)
2356 break;
2357 if (equals == 0) {
2358 if (args[i] == '=')
2359 equals = i;
2360 }
2361 if (args[i] == '"')
2362 in_quote = !in_quote;
2363 }
2364
2365 *param = args;
2366 if (!equals)
2367 *val = NULL;
2368 else {
2369 args[equals] = '\0';
2370 *val = args + equals + 1;
2371
2372
2373 if (**val == '"') {
2374 (*val)++;
2375 if (args[i-1] == '"')
2376 args[i-1] = '\0';
2377 }
2378 if (quoted && args[i-1] == '"')
2379 args[i-1] = '\0';
2380 }
2381
2382 if (args[i]) {
2383 args[i] = '\0';
2384 next = args + i + 1;
2385 } else
2386 next = args + i;
2387
2388
2389 return skip_whitespace(next);
2390}
2391
2392static void
2393new_process_module_arguments(struct obj_file *f, const char *options)
2394{
2395 char *xoptions, *pos;
2396 char *param, *val;
2397
2398 xoptions = pos = xstrdup(skip_whitespace(options));
2399 while (*pos) {
2400 unsigned long charssize = 0;
2401 char *tmp, *contents, *loc, *pinfo, *p;
2402 struct obj_symbol *sym;
2403 int min, max, n, len;
2404
2405 pos = next_arg(pos, ¶m, &val);
2406
2407 tmp = xasprintf("parm_%s", param);
2408 pinfo = get_modinfo_value(f, tmp);
2409 free(tmp);
2410 if (pinfo == NULL)
2411 bb_error_msg_and_die("invalid parameter %s", param);
2412
2413#ifdef SYMBOL_PREFIX
2414 tmp = xasprintf(SYMBOL_PREFIX "%s", param);
2415 sym = obj_find_symbol(f, tmp);
2416 free(tmp);
2417#else
2418 sym = obj_find_symbol(f, param);
2419#endif
2420
2421
2422 if (sym == NULL || sym->secidx > SHN_HIRESERVE)
2423 bb_error_msg_and_die("symbol for parameter %s not found", param);
2424
2425
2426 if (isdigit(*pinfo)) {
2427 min = strtoul(pinfo, &pinfo, 10);
2428 if (*pinfo == '-')
2429 max = strtoul(pinfo + 1, &pinfo, 10);
2430 else
2431 max = min;
2432 } else
2433 min = max = 1;
2434
2435 contents = f->sections[sym->secidx]->contents;
2436 loc = contents + sym->value;
2437
2438 if (*pinfo == 'c') {
2439 if (!isdigit(*(pinfo + 1))) {
2440 bb_error_msg_and_die("parameter type 'c' for %s must be followed by"
2441 " the maximum size", param);
2442 }
2443 charssize = strtoul(pinfo + 1, (char **) NULL, 10);
2444 }
2445
2446 if (val == NULL) {
2447 if (*pinfo != 'b')
2448 bb_error_msg_and_die("argument expected for parameter %s", param);
2449 val = (char *) "1";
2450 }
2451
2452
2453 n = 0;
2454 p = val;
2455 while (*p != 0) {
2456 if (++n > max)
2457 bb_error_msg_and_die("too many values for %s (max %d)", param, max);
2458
2459 switch (*pinfo) {
2460 case 's':
2461 len = strcspn(p, ",");
2462 p[len] = 0;
2463 obj_string_patch(f, sym->secidx,
2464 loc - contents, p);
2465 loc += tgt_sizeof_char_p;
2466 p += len;
2467 break;
2468 case 'c':
2469 len = strcspn(p, ",");
2470 p[len] = 0;
2471 if (len >= charssize)
2472 bb_error_msg_and_die("string too long for %s (max %ld)", param,
2473 charssize - 1);
2474 strcpy((char *) loc, p);
2475 loc += charssize;
2476 p += len;
2477 break;
2478 case 'b':
2479 *loc++ = strtoul(p, &p, 0);
2480 break;
2481 case 'h':
2482 *(short *) loc = strtoul(p, &p, 0);
2483 loc += tgt_sizeof_short;
2484 break;
2485 case 'i':
2486 *(int *) loc = strtoul(p, &p, 0);
2487 loc += tgt_sizeof_int;
2488 break;
2489 case 'l':
2490 *(long *) loc = strtoul(p, &p, 0);
2491 loc += tgt_sizeof_long;
2492 break;
2493 default:
2494 bb_error_msg_and_die("unknown parameter type '%c' for %s",
2495 *pinfo, param);
2496 }
2497
2498 p = skip_whitespace(p);
2499 if (*p != ',')
2500 break;
2501 p = skip_whitespace(p + 1);
2502 }
2503
2504 if (n < min)
2505 bb_error_msg_and_die("parameter %s requires at least %d arguments", param, min);
2506 if (*p != '\0')
2507 bb_error_msg_and_die("invalid argument syntax for %s", param);
2508 }
2509
2510 free(xoptions);
2511}
2512
2513#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
2514static int new_is_module_checksummed(struct obj_file *f)
2515{
2516 const char *p = get_modinfo_value(f, "using_checksums");
2517 if (p)
2518 return xatoi(p);
2519 return 0;
2520}
2521
2522
2523
2524static int
2525new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
2526{
2527 char *p, *q;
2528 int a, b, c;
2529
2530 p = get_modinfo_value(f, "kernel_version");
2531 if (p == NULL)
2532 return -1;
2533 safe_strncpy(str, p, STRVERSIONLEN);
2534
2535 a = strtoul(p, &p, 10);
2536 if (*p != '.')
2537 return -1;
2538 b = strtoul(p + 1, &p, 10);
2539 if (*p != '.')
2540 return -1;
2541 c = strtoul(p + 1, &q, 10);
2542 if (p + 1 == q)
2543 return -1;
2544
2545 return a << 16 | b << 8 | c;
2546}
2547
2548#endif
2549
2550
2551
2552
2553static void new_get_kernel_symbols(void)
2554{
2555 char *module_names, *mn;
2556 struct external_module *modules, *m;
2557 struct new_module_symbol *syms, *s;
2558 size_t ret, bufsize, nmod, nsyms, i, j;
2559
2560
2561
2562 bufsize = 256;
2563 module_names = xmalloc(bufsize);
2564
2565 retry_modules_load:
2566 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
2567 if (errno == ENOSPC && bufsize < ret) {
2568 bufsize = ret;
2569 module_names = xrealloc(module_names, bufsize);
2570 goto retry_modules_load;
2571 }
2572 bb_perror_msg_and_die("QM_MODULES");
2573 }
2574
2575 n_ext_modules = nmod = ret;
2576
2577
2578
2579 if (nmod) {
2580 ext_modules = modules = xzalloc(nmod * sizeof(*modules));
2581 for (i = 0, mn = module_names, m = modules;
2582 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2583 struct new_module_info info;
2584
2585 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
2586 if (errno == ENOENT) {
2587
2588 continue;
2589 }
2590 bb_perror_msg_and_die("query_module: QM_INFO: %s", mn);
2591 }
2592
2593 bufsize = 1024;
2594 syms = xmalloc(bufsize);
2595 retry_mod_sym_load:
2596 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {
2597 switch (errno) {
2598 case ENOSPC:
2599 bufsize = ret;
2600 syms = xrealloc(syms, bufsize);
2601 goto retry_mod_sym_load;
2602 case ENOENT:
2603
2604 continue;
2605 default:
2606 bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn);
2607 }
2608 }
2609 nsyms = ret;
2610
2611 m->name = mn;
2612 m->addr = info.addr;
2613 m->nsyms = nsyms;
2614 m->syms = syms;
2615
2616 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2617 s->name += (unsigned long) syms;
2618 }
2619 }
2620 }
2621
2622
2623
2624 bufsize = 16 * 1024;
2625 syms = xmalloc(bufsize);
2626 retry_kern_sym_load:
2627 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {
2628 if (errno == ENOSPC && bufsize < ret) {
2629 bufsize = ret;
2630 syms = xrealloc(syms, bufsize);
2631 goto retry_kern_sym_load;
2632 }
2633 bb_perror_msg_and_die("kernel: QM_SYMBOLS");
2634 }
2635 nksyms = nsyms = ret;
2636 ksyms = syms;
2637
2638 for (j = 0, s = syms; j < nsyms; ++j, ++s) {
2639 s->name += (unsigned long) syms;
2640 }
2641}
2642
2643
2644
2645
2646static int new_is_kernel_checksummed(void)
2647{
2648 struct new_module_symbol *s;
2649 size_t i;
2650
2651
2652
2653 for (i = 0, s = ksyms; i < nksyms; ++i, ++s)
2654 if (strcmp((char *) s->name, "Using_Versions") == 0)
2655 return s->value;
2656
2657 return 0;
2658}
2659
2660
2661static void new_create_this_module(struct obj_file *f, const char *m_name)
2662{
2663 struct obj_section *sec;
2664
2665 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2666 sizeof(struct new_module));
2667
2668
2669
2670 obj_add_symbol(f, SPFX "__this_module", -1,
2671 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
2672 sizeof(struct new_module));
2673
2674 obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
2675 m_name);
2676}
2677
2678#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
2679
2680static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym)
2681{
2682 struct obj_section *sec;
2683 ElfW(Addr) ofs;
2684
2685
2686
2687
2688
2689
2690 sec = obj_find_section(f, "__ksymtab");
2691 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) {
2692 *((char *)(sec->name)) = 'x';
2693 sec = NULL;
2694 }
2695 if (!sec)
2696 sec = obj_create_alloced_section(f, "__ksymtab",
2697 tgt_sizeof_void_p, 0);
2698 if (!sec)
2699 return;
2700 sec->header.sh_flags |= SHF_ALLOC;
2701
2702 sec->header.sh_addralign = tgt_sizeof_void_p;
2703 ofs = sec->header.sh_size;
2704 obj_symbol_patch(f, sec->idx, ofs, sym);
2705 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name);
2706 obj_extend_section(sec, 2 * tgt_sizeof_char_p);
2707}
2708#endif
2709
2710static int new_create_module_ksymtab(struct obj_file *f)
2711{
2712 struct obj_section *sec;
2713 int i;
2714
2715
2716
2717 if (n_ext_modules_used) {
2718 struct new_module_ref *dep;
2719 struct obj_symbol *tm;
2720
2721 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,
2722 (sizeof(struct new_module_ref)
2723 * n_ext_modules_used));
2724 if (!sec)
2725 return 0;
2726
2727 tm = obj_find_symbol(f, SPFX "__this_module");
2728 dep = (struct new_module_ref *) sec->contents;
2729 for (i = 0; i < n_ext_modules; ++i)
2730 if (ext_modules[i].used) {
2731 dep->dep = ext_modules[i].addr;
2732 obj_symbol_patch(f, sec->idx,
2733 (char *) &dep->ref - sec->contents, tm);
2734 dep->next_ref = 0;
2735 ++dep;
2736 }
2737 }
2738
2739 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) {
2740 size_t nsyms;
2741 int *loaded;
2742
2743 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0);
2744
2745
2746
2747
2748 i = f->header.e_shnum;
2749 loaded = alloca(sizeof(int) * i);
2750 while (--i >= 0)
2751 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2752
2753 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2754 struct obj_symbol *sym;
2755 for (sym = f->symtab[i]; sym; sym = sym->next) {
2756 if (ELF_ST_BIND(sym->info) != STB_LOCAL
2757 && sym->secidx <= SHN_HIRESERVE
2758 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
2759 ) {
2760 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2761
2762 obj_symbol_patch(f, sec->idx, ofs, sym);
2763 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,
2764 sym->name);
2765 nsyms++;
2766 }
2767 }
2768 }
2769
2770 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
2771 }
2772
2773 return 1;
2774}
2775
2776
2777static int
2778new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2779{
2780 struct new_module *module;
2781 struct obj_section *sec;
2782 void *image;
2783 int ret;
2784 tgt_long m_addr;
2785
2786 sec = obj_find_section(f, ".this");
2787 if (!sec || !sec->contents) {
2788 bb_perror_msg_and_die("corrupt module %s?", m_name);
2789 }
2790 module = (struct new_module *) sec->contents;
2791 m_addr = sec->header.sh_addr;
2792
2793 module->size_of_struct = sizeof(*module);
2794 module->size = m_size;
2795 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;
2796
2797 sec = obj_find_section(f, "__ksymtab");
2798 if (sec && sec->header.sh_size) {
2799 module->syms = sec->header.sh_addr;
2800 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);
2801 }
2802
2803 if (n_ext_modules_used) {
2804 sec = obj_find_section(f, ".kmodtab");
2805 module->deps = sec->header.sh_addr;
2806 module->ndeps = n_ext_modules_used;
2807 }
2808
2809 module->init = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
2810 module->cleanup = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
2811
2812 sec = obj_find_section(f, "__ex_table");
2813 if (sec) {
2814 module->ex_table_start = sec->header.sh_addr;
2815 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;
2816 }
2817
2818 sec = obj_find_section(f, ".text.init");
2819 if (sec) {
2820 module->runsize = sec->header.sh_addr - m_addr;
2821 }
2822 sec = obj_find_section(f, ".data.init");
2823 if (sec) {
2824 if (!module->runsize
2825 || module->runsize > sec->header.sh_addr - m_addr
2826 ) {
2827 module->runsize = sec->header.sh_addr - m_addr;
2828 }
2829 }
2830 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2831 if (sec && sec->header.sh_size) {
2832 module->archdata_start = (void*)sec->header.sh_addr;
2833 module->archdata_end = module->archdata_start + sec->header.sh_size;
2834 }
2835 sec = obj_find_section(f, KALLSYMS_SEC_NAME);
2836 if (sec && sec->header.sh_size) {
2837 module->kallsyms_start = (void*)sec->header.sh_addr;
2838 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;
2839 }
2840
2841
2842
2843
2844 image = xmalloc(m_size);
2845 obj_create_image(f, image);
2846
2847 ret = init_module(m_name, (struct new_module *) image);
2848 if (ret)
2849 bb_perror_msg("init_module: %s", m_name);
2850
2851 free(image);
2852
2853 return ret == 0;
2854}
2855
2856
2857
2858
2859static void
2860obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2861 const char *string)
2862{
2863 struct obj_string_patch *p;
2864 struct obj_section *strsec;
2865 size_t len = strlen(string) + 1;
2866 char *loc;
2867
2868 p = xzalloc(sizeof(*p));
2869 p->next = f->string_patches;
2870 p->reloc_secidx = secidx;
2871 p->reloc_offset = offset;
2872 f->string_patches = p;
2873
2874 strsec = obj_find_section(f, ".kstrtab");
2875 if (strsec == NULL) {
2876 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
2877
2878 loc = strsec->contents;
2879 } else {
2880 p->string_offset = strsec->header.sh_size;
2881 loc = obj_extend_section(strsec, len);
2882 }
2883 memcpy(loc, string, len);
2884}
2885
2886static void
2887obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
2888 struct obj_symbol *sym)
2889{
2890 struct obj_symbol_patch *p;
2891
2892 p = xmalloc(sizeof(*p));
2893 p->next = f->symbol_patches;
2894 p->reloc_secidx = secidx;
2895 p->reloc_offset = offset;
2896 p->sym = sym;
2897 f->symbol_patches = p;
2898}
2899
2900static void obj_check_undefineds(struct obj_file *f)
2901{
2902 unsigned i;
2903
2904 for (i = 0; i < HASH_BUCKETS; ++i) {
2905 struct obj_symbol *sym;
2906 for (sym = f->symtab[i]; sym; sym = sym->next) {
2907 if (sym->secidx == SHN_UNDEF) {
2908 if (ELF_ST_BIND(sym->info) == STB_WEAK) {
2909 sym->secidx = SHN_ABS;
2910 sym->value = 0;
2911 } else {
2912 if (!flag_quiet)
2913 bb_error_msg_and_die("unresolved symbol %s", sym->name);
2914 }
2915 }
2916 }
2917 }
2918}
2919
2920static void obj_allocate_commons(struct obj_file *f)
2921{
2922 struct common_entry {
2923 struct common_entry *next;
2924 struct obj_symbol *sym;
2925 } *common_head = NULL;
2926
2927 unsigned long i;
2928
2929 for (i = 0; i < HASH_BUCKETS; ++i) {
2930 struct obj_symbol *sym;
2931 for (sym = f->symtab[i]; sym; sym = sym->next) {
2932 if (sym->secidx == SHN_COMMON) {
2933
2934
2935 struct common_entry **p, *n;
2936 for (p = &common_head; *p; p = &(*p)->next)
2937 if (sym->size <= (*p)->sym->size)
2938 break;
2939 n = alloca(sizeof(*n));
2940 n->next = *p;
2941 n->sym = sym;
2942 *p = n;
2943 }
2944 }
2945 }
2946
2947 for (i = 1; i < f->local_symtab_size; ++i) {
2948 struct obj_symbol *sym = f->local_symtab[i];
2949 if (sym && sym->secidx == SHN_COMMON) {
2950 struct common_entry **p, *n;
2951 for (p = &common_head; *p; p = &(*p)->next) {
2952 if (sym == (*p)->sym)
2953 break;
2954 if (sym->size < (*p)->sym->size) {
2955 n = alloca(sizeof(*n));
2956 n->next = *p;
2957 n->sym = sym;
2958 *p = n;
2959 break;
2960 }
2961 }
2962 }
2963 }
2964
2965 if (common_head) {
2966
2967 for (i = 0; i < f->header.e_shnum; ++i)
2968 if (f->sections[i]->header.sh_type == SHT_NOBITS)
2969 break;
2970
2971
2972 if (i == f->header.e_shnum) {
2973 struct obj_section *sec;
2974
2975 f->header.e_shnum++;
2976 f->sections = xrealloc_vector(f->sections, 2, i);
2977 f->sections[i] = sec = arch_new_section();
2978
2979 sec->header.sh_type = SHT_PROGBITS;
2980 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
2981 sec->name = ".bss";
2982 sec->idx = i;
2983 }
2984
2985
2986 {
2987 ElfW(Addr) bss_size = f->sections[i]->header.sh_size;
2988 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign;
2989 struct common_entry *c;
2990
2991 for (c = common_head; c; c = c->next) {
2992 ElfW(Addr) align = c->sym->value;
2993
2994 if (align > max_align)
2995 max_align = align;
2996 if (bss_size & (align - 1))
2997 bss_size = (bss_size | (align - 1)) + 1;
2998
2999 c->sym->secidx = i;
3000 c->sym->value = bss_size;
3001
3002 bss_size += c->sym->size;
3003 }
3004
3005 f->sections[i]->header.sh_size = bss_size;
3006 f->sections[i]->header.sh_addralign = max_align;
3007 }
3008 }
3009
3010
3011
3012
3013 for (i = 0; i < f->header.e_shnum; ++i) {
3014 struct obj_section *s = f->sections[i];
3015 if (s->header.sh_type == SHT_NOBITS) {
3016 s->contents = NULL;
3017 if (s->header.sh_size != 0)
3018 s->contents = xzalloc(s->header.sh_size);
3019 s->header.sh_type = SHT_PROGBITS;
3020 }
3021 }
3022}
3023
3024static unsigned long obj_load_size(struct obj_file *f)
3025{
3026 unsigned long dot = 0;
3027 struct obj_section *sec;
3028
3029
3030
3031 for (sec = f->load_order; sec; sec = sec->load_next) {
3032 ElfW(Addr) align;
3033
3034 align = sec->header.sh_addralign;
3035 if (align && (dot & (align - 1)))
3036 dot = (dot | (align - 1)) + 1;
3037
3038 sec->header.sh_addr = dot;
3039 dot += sec->header.sh_size;
3040 }
3041
3042 return dot;
3043}
3044
3045static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3046{
3047 int i, n = f->header.e_shnum;
3048 int ret = 1;
3049
3050
3051
3052 f->baseaddr = base;
3053 for (i = 0; i < n; ++i)
3054 f->sections[i]->header.sh_addr += base;
3055
3056
3057
3058 for (i = 0; i < n; ++i) {
3059 struct obj_section *relsec, *symsec, *targsec, *strsec;
3060 ElfW(RelM) * rel, *relend;
3061 ElfW(Sym) * symtab;
3062 const char *strtab;
3063
3064 relsec = f->sections[i];
3065 if (relsec->header.sh_type != SHT_RELM)
3066 continue;
3067
3068 symsec = f->sections[relsec->header.sh_link];
3069 targsec = f->sections[relsec->header.sh_info];
3070 strsec = f->sections[symsec->header.sh_link];
3071
3072 rel = (ElfW(RelM) *) relsec->contents;
3073 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
3074 symtab = (ElfW(Sym) *) symsec->contents;
3075 strtab = (const char *) strsec->contents;
3076
3077 for (; rel < relend; ++rel) {
3078 ElfW(Addr) value = 0;
3079 struct obj_symbol *intsym = NULL;
3080 unsigned long symndx;
3081 ElfW(Sym) *extsym = NULL;
3082 const char *errmsg;
3083
3084
3085
3086 symndx = ELF_R_SYM(rel->r_info);
3087 if (symndx) {
3088
3089
3090 extsym = &symtab[symndx];
3091 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) {
3092
3093
3094 intsym = f->local_symtab[symndx];
3095 } else {
3096
3097 const char *name;
3098 if (extsym->st_name)
3099 name = strtab + extsym->st_name;
3100 else
3101 name = f->sections[extsym->st_shndx]->name;
3102 intsym = obj_find_symbol(f, name);
3103 }
3104
3105 value = obj_symbol_final_value(f, intsym);
3106 intsym->referenced = 1;
3107 }
3108#if SHT_RELM == SHT_RELA
3109#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3110
3111 if (!extsym || !extsym->st_name
3112 || ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
3113#endif
3114 value += rel->r_addend;
3115#endif
3116
3117
3118 switch (arch_apply_relocation
3119 (f, targsec, intsym, rel, value)
3120 ) {
3121 case obj_reloc_ok:
3122 break;
3123
3124 case obj_reloc_overflow:
3125 errmsg = "Relocation overflow";
3126 goto bad_reloc;
3127 case obj_reloc_dangerous:
3128 errmsg = "Dangerous relocation";
3129 goto bad_reloc;
3130 case obj_reloc_unhandled:
3131 errmsg = "Unhandled relocation";
3132bad_reloc:
3133 if (extsym) {
3134 bb_error_msg("%s of type %ld for %s", errmsg,
3135 (long) ELF_R_TYPE(rel->r_info),
3136 strtab + extsym->st_name);
3137 } else {
3138 bb_error_msg("%s of type %ld", errmsg,
3139 (long) ELF_R_TYPE(rel->r_info));
3140 }
3141 ret = 0;
3142 break;
3143 }
3144 }
3145 }
3146
3147
3148
3149 if (f->string_patches) {
3150 struct obj_string_patch *p;
3151 struct obj_section *strsec;
3152 ElfW(Addr) strsec_base;
3153 strsec = obj_find_section(f, ".kstrtab");
3154 strsec_base = strsec->header.sh_addr;
3155
3156 for (p = f->string_patches; p; p = p->next) {
3157 struct obj_section *targsec = f->sections[p->reloc_secidx];
3158 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3159 = strsec_base + p->string_offset;
3160 }
3161 }
3162
3163 if (f->symbol_patches) {
3164 struct obj_symbol_patch *p;
3165
3166 for (p = f->symbol_patches; p; p = p->next) {
3167 struct obj_section *targsec = f->sections[p->reloc_secidx];
3168 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset)
3169 = obj_symbol_final_value(f, p->sym);
3170 }
3171 }
3172
3173 return ret;
3174}
3175
3176static int obj_create_image(struct obj_file *f, char *image)
3177{
3178 struct obj_section *sec;
3179 ElfW(Addr) base = f->baseaddr;
3180
3181 for (sec = f->load_order; sec; sec = sec->load_next) {
3182 char *secimg;
3183
3184 if (sec->contents == 0 || sec->header.sh_size == 0)
3185 continue;
3186
3187 secimg = image + (sec->header.sh_addr - base);
3188
3189
3190 memcpy(secimg, sec->contents, sec->header.sh_size);
3191 }
3192
3193 return 1;
3194}
3195
3196
3197
3198static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbits)
3199{
3200#if BB_LITTLE_ENDIAN
3201# define ELFMAG_U32 ((uint32_t)(ELFMAG0 + 0x100 * (ELFMAG1 + (0x100 * (ELFMAG2 + 0x100 * ELFMAG3)))))
3202#else
3203# define ELFMAG_U32 ((uint32_t)((((ELFMAG0 * 0x100) + ELFMAG1) * 0x100 + ELFMAG2) * 0x100 + ELFMAG3))
3204#endif
3205 struct obj_file *f;
3206 ElfW(Shdr) * section_headers;
3207 size_t shnum, i;
3208 char *shstrtab;
3209
3210
3211
3212 f = arch_new_file();
3213 f->symbol_cmp = strcmp;
3214 f->symbol_hash = obj_elf_hash;
3215 f->load_order_search_start = &f->load_order;
3216
3217 if (image_size < sizeof(f->header))
3218 bb_error_msg_and_die("error while loading ELF header");
3219 memcpy(&f->header, image, sizeof(f->header));
3220
3221 if (*(uint32_t*)(&f->header.e_ident) != ELFMAG_U32) {
3222 bb_error_msg_and_die("not an ELF file");
3223 }
3224 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3225 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3226 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3227 || !MATCH_MACHINE(f->header.e_machine)
3228 ) {
3229 bb_error_msg_and_die("ELF file not for this architecture");
3230 }
3231 if (f->header.e_type != ET_REL) {
3232 bb_error_msg_and_die("ELF file not a relocatable object");
3233 }
3234
3235
3236
3237 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) {
3238 bb_error_msg_and_die("section header size mismatch: %lu != %lu",
3239 (unsigned long) f->header.e_shentsize,
3240 (unsigned long) sizeof(ElfW(Shdr)));
3241 }
3242
3243 shnum = f->header.e_shnum;
3244
3245
3246
3247 f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
3248
3249 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3250 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum)
3251 bb_error_msg_and_die("error while loading section headers");
3252 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum);
3253
3254
3255
3256 for (i = 0; i < shnum; ++i) {
3257 struct obj_section *sec;
3258
3259 f->sections[i] = sec = arch_new_section();
3260
3261 sec->header = section_headers[i];
3262 sec->idx = i;
3263
3264 if (sec->header.sh_size) {
3265 switch (sec->header.sh_type) {
3266 case SHT_NULL:
3267 case SHT_NOTE:
3268 case SHT_NOBITS:
3269
3270 break;
3271 case SHT_PROGBITS:
3272#if LOADBITS
3273 if (!loadprogbits) {
3274 sec->contents = NULL;
3275 break;
3276 }
3277#endif
3278 case SHT_SYMTAB:
3279 case SHT_STRTAB:
3280 case SHT_RELM:
3281 sec->contents = NULL;
3282 if (sec->header.sh_size > 0) {
3283 sec->contents = xmalloc(sec->header.sh_size);
3284 if (image_size < (sec->header.sh_offset + sec->header.sh_size))
3285 bb_error_msg_and_die("error while loading section data");
3286 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
3287 }
3288 break;
3289#if SHT_RELM == SHT_REL
3290 case SHT_RELA:
3291 bb_error_msg_and_die("RELA relocations not supported on this architecture");
3292#else
3293 case SHT_REL:
3294 bb_error_msg_and_die("REL relocations not supported on this architecture");
3295#endif
3296 default:
3297 if (sec->header.sh_type >= SHT_LOPROC) {
3298
3299
3300
3301
3302 break;
3303 }
3304
3305 bb_error_msg_and_die("can't handle sections of type %ld",
3306 (long) sec->header.sh_type);
3307 }
3308 }
3309 }
3310
3311
3312
3313 shstrtab = f->sections[f->header.e_shstrndx]->contents;
3314
3315 for (i = 0; i < shnum; ++i) {
3316 struct obj_section *sec = f->sections[i];
3317 sec->name = shstrtab + sec->header.sh_name;
3318 }
3319
3320 for (i = 0; i < shnum; ++i) {
3321 struct obj_section *sec = f->sections[i];
3322
3323
3324
3325
3326 if (strcmp(sec->name, ".modinfo") == 0)
3327 sec->header.sh_flags &= ~SHF_ALLOC;
3328
3329 if (sec->header.sh_flags & SHF_ALLOC)
3330 obj_insert_section_load_order(f, sec);
3331
3332 switch (sec->header.sh_type) {
3333 case SHT_SYMTAB:
3334 {
3335 unsigned long nsym, j;
3336 char *strtab;
3337 ElfW(Sym) * sym;
3338
3339 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) {
3340 bb_error_msg_and_die("symbol size mismatch: %lu != %lu",
3341 (unsigned long) sec->header.sh_entsize,
3342 (unsigned long) sizeof(ElfW(Sym)));
3343 }
3344
3345 nsym = sec->header.sh_size / sizeof(ElfW(Sym));
3346 strtab = f->sections[sec->header.sh_link]->contents;
3347 sym = (ElfW(Sym) *) sec->contents;
3348
3349
3350 j = f->local_symtab_size = sec->header.sh_info;
3351 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *));
3352
3353
3354 for (j = 1, ++sym; j < nsym; ++j, ++sym) {
3355 ElfW(Addr) val = sym->st_value;
3356 const char *name;
3357 if (sym->st_name)
3358 name = strtab + sym->st_name;
3359 else if (sym->st_shndx < shnum)
3360 name = f->sections[sym->st_shndx]->name;
3361 else
3362 continue;
3363#if defined(__SH5__)
3364
3365
3366
3367
3368
3369
3370
3371 val |= sym->st_other & 4;
3372#endif
3373 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx,
3374 val, sym->st_size);
3375 }
3376 }
3377 break;
3378
3379 case SHT_RELM:
3380 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) {
3381 bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu",
3382 (unsigned long) sec->header.sh_entsize,
3383 (unsigned long) sizeof(ElfW(RelM)));
3384 }
3385 break;
3386
3387
3388
3389
3390 }
3391 }
3392
3393 return f;
3394}
3395
3396#if ENABLE_FEATURE_INSMOD_LOADINKMEM
3397
3398
3399
3400
3401
3402static int obj_load_progbits(char *image, size_t image_size, struct obj_file *f, char *imagebase)
3403{
3404 ElfW(Addr) base = f->baseaddr;
3405 struct obj_section* sec;
3406
3407 for (sec = f->load_order; sec; sec = sec->load_next) {
3408
3409 if (sec->contents != NULL)
3410 continue;
3411 if (sec->header.sh_size == 0)
3412 continue;
3413 sec->contents = imagebase + (sec->header.sh_addr - base);
3414 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) {
3415 bb_error_msg("error reading ELF section data");
3416 return 0;
3417 }
3418 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
3419 }
3420 return 1;
3421}
3422#endif
3423
3424static void hide_special_symbols(struct obj_file *f)
3425{
3426 static const char *const specials[] = {
3427 SPFX "cleanup_module",
3428 SPFX "init_module",
3429 SPFX "kernel_version",
3430 NULL
3431 };
3432
3433 struct obj_symbol *sym;
3434 const char *const *p;
3435
3436 for (p = specials; *p; ++p) {
3437 sym = obj_find_symbol(f, *p);
3438 if (sym != NULL)
3439 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info));
3440 }
3441}
3442
3443
3444#if ENABLE_FEATURE_CHECK_TAINTED_MODULE
3445static int obj_gpl_license(struct obj_file *f, const char **license)
3446{
3447 struct obj_section *sec;
3448
3449
3450
3451
3452 static const char *const gpl_licenses[] = {
3453 "GPL",
3454 "GPL v2",
3455 "GPL and additional rights",
3456 "Dual BSD/GPL",
3457 "Dual MPL/GPL"
3458 };
3459
3460 sec = obj_find_section(f, ".modinfo");
3461 if (sec) {
3462 const char *value, *ptr, *endptr;
3463 ptr = sec->contents;
3464 endptr = ptr + sec->header.sh_size;
3465 while (ptr < endptr) {
3466 value = strchr(ptr, '=');
3467 if (value && strncmp(ptr, "license", value-ptr) == 0) {
3468 unsigned i;
3469 if (license)
3470 *license = value+1;
3471 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) {
3472 if (strcmp(value+1, gpl_licenses[i]) == 0)
3473 return 0;
3474 }
3475 return 2;
3476 }
3477 ptr = strchr(ptr, '\0');
3478 if (ptr)
3479 ptr++;
3480 else
3481 ptr = endptr;
3482 }
3483 }
3484 return 1;
3485}
3486
3487#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3488#define TAINT_PROPRIETORY_MODULE (1 << 0)
3489#define TAINT_FORCED_MODULE (1 << 1)
3490#define TAINT_UNSAFE_SMP (1 << 2)
3491#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3492
3493static void set_tainted(int fd, const char *m_name,
3494 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3495{
3496 static smallint printed_info;
3497
3498 char buf[80];
3499 int oldval;
3500
3501 if (fd < 0 && !kernel_has_tainted)
3502 return;
3503 printf("Warning: loading %s will taint the kernel: %s%s\n",
3504 m_name, text1, text2);
3505 if (!printed_info) {
3506 printf(" See %s for information about tainted modules\n", TAINT_URL);
3507 printed_info = 1;
3508 }
3509 if (fd >= 0) {
3510 read(fd, buf, sizeof(buf)-1);
3511 buf[sizeof(buf)-1] = '\0';
3512 oldval = strtoul(buf, NULL, 10);
3513 sprintf(buf, "%d\n", oldval | taint);
3514 xwrite_str(fd, buf);
3515 }
3516}
3517
3518
3519static void check_tainted_module(struct obj_file *f, const char *m_name)
3520{
3521 static const char tainted_file[] ALIGN1 = TAINT_FILENAME;
3522
3523 int fd, kernel_has_tainted;
3524 const char *ptr;
3525
3526 kernel_has_tainted = 1;
3527 fd = open(tainted_file, O_RDWR);
3528 if (fd < 0) {
3529 if (errno == ENOENT)
3530 kernel_has_tainted = 0;
3531 else if (errno == EACCES)
3532 kernel_has_tainted = 1;
3533 else {
3534 perror(tainted_file);
3535 kernel_has_tainted = 0;
3536 }
3537 }
3538
3539 switch (obj_gpl_license(f, &ptr)) {
3540 case 0:
3541 break;
3542 case 1:
3543 set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3544 break;
3545 default:
3546
3547
3548
3549
3550 set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3551 break;
3552 }
3553
3554 if (flag_force_load)
3555 set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3556
3557 if (fd >= 0)
3558 close(fd);
3559}
3560#else
3561#define check_tainted_module(x, y) do { } while (0);
3562#endif
3563
3564#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3565
3566
3567
3568
3569#if !ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3570#define get_module_version(f, str) get_module_version(str)
3571#endif
3572static int
3573get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
3574{
3575#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3576 return new_get_module_version(f, str);
3577#else
3578 strncpy(str, "???", sizeof(str));
3579 return -1;
3580#endif
3581}
3582
3583
3584
3585
3586
3587static void
3588add_ksymoops_symbols(struct obj_file *f, const char *filename,
3589 const char *m_name)
3590{
3591 static const char symprefix[] ALIGN1 = "__insmod_";
3592 static const char section_names[][8] = {
3593 ".text",
3594 ".rodata",
3595 ".data",
3596 ".bss",
3597 ".sbss"
3598 };
3599
3600 struct obj_section *sec;
3601 struct obj_symbol *sym;
3602 char *name, *absolute_filename;
3603 char str[STRVERSIONLEN];
3604 unsigned i;
3605 int lm_name, lfilename, use_ksymtab, version;
3606 struct stat statbuf;
3607
3608
3609
3610 absolute_filename = xmalloc_readlink(filename);
3611 if (!absolute_filename)
3612 absolute_filename = xstrdup(filename);
3613
3614 lm_name = strlen(m_name);
3615 lfilename = strlen(absolute_filename);
3616
3617
3618
3619
3620
3621 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport;
3622
3623 sec = obj_find_section(f, ".this");
3624 if (sec) {
3625
3626
3627
3628
3629
3630 if (stat(absolute_filename, &statbuf) != 0)
3631 statbuf.st_mtime = 0;
3632 version = get_module_version(f, str);
3633 name = xasprintf("%s%s_O%s_M%0*lX_V%d",
3634 symprefix, m_name, absolute_filename,
3635 (int)(2 * sizeof(statbuf.st_mtime)),
3636 (long)statbuf.st_mtime,
3637 version);
3638 sym = obj_add_symbol(f, name, -1,
3639 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3640 sec->idx, sec->header.sh_addr, 0);
3641 if (use_ksymtab)
3642 new_add_ksymtab(f, sym);
3643 }
3644 free(absolute_filename);
3645#ifdef _NOT_SUPPORTED_
3646
3647 if (f->persist) {
3648 name = xasprintf("%s%s_P%s",
3649 symprefix, m_name, f->persist);
3650 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3651 sec->idx, sec->header.sh_addr, 0);
3652 if (use_ksymtab)
3653 new_add_ksymtab(f, sym);
3654 }
3655#endif
3656
3657 for (i = 0; i < ARRAY_SIZE(section_names); ++i) {
3658 sec = obj_find_section(f, section_names[i]);
3659 if (sec && sec->header.sh_size) {
3660 name = xasprintf("%s%s_S%s_L%ld",
3661 symprefix, m_name, sec->name,
3662 (long)sec->header.sh_size);
3663 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE),
3664 sec->idx, sec->header.sh_addr, 0);
3665 if (use_ksymtab)
3666 new_add_ksymtab(f, sym);
3667 }
3668 }
3669}
3670#endif
3671
3672#if ENABLE_FEATURE_INSMOD_LOAD_MAP
3673static void print_load_map(struct obj_file *f)
3674{
3675 struct obj_section *sec;
3676#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3677 struct obj_symbol **all, **p;
3678 int i, nsyms;
3679 char *loaded;
3680 struct obj_symbol *sym;
3681#endif
3682
3683 printf("Sections: Size %-*s Align\n",
3684 (int) (2 * sizeof(void *)), "Address");
3685
3686 for (sec = f->load_order; sec; sec = sec->load_next) {
3687 int a;
3688 unsigned long tmp;
3689
3690 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a)
3691 tmp >>= 1;
3692 if (a == -1)
3693 a = 0;
3694
3695 printf("%-15s %08lx %0*lx 2**%d\n",
3696 sec->name,
3697 (long)sec->header.sh_size,
3698 (int) (2 * sizeof(void *)),
3699 (long)sec->header.sh_addr,
3700 a);
3701 }
3702#if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL
3703
3704 i = f->header.e_shnum;
3705 loaded = alloca(i * sizeof(loaded[0]));
3706 while (--i >= 0)
3707 loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0);
3708
3709
3710 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3711 for (sym = f->symtab[i]; sym; sym = sym->next)
3712 if (sym->secidx <= SHN_HIRESERVE
3713 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3714 ) {
3715 ++nsyms;
3716 }
3717
3718 all = alloca(nsyms * sizeof(all[0]));
3719
3720 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3721 for (sym = f->symtab[i]; sym; sym = sym->next)
3722 if (sym->secidx <= SHN_HIRESERVE
3723 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3724 ) {
3725 *p++ = sym;
3726 }
3727
3728
3729 printf("\nSymbols:\n");
3730 for (p = all; p < all + nsyms; ++p) {
3731 char type = '?';
3732 unsigned long value;
3733
3734 sym = *p;
3735 if (sym->secidx == SHN_ABS) {
3736 type = 'A';
3737 value = sym->value;
3738 } else if (sym->secidx == SHN_UNDEF) {
3739 type = 'U';
3740 value = 0;
3741 } else {
3742 sec = f->sections[sym->secidx];
3743
3744 if (sec->header.sh_type == SHT_NOBITS)
3745 type = 'B';
3746 else if (sec->header.sh_flags & SHF_ALLOC) {
3747 if (sec->header.sh_flags & SHF_EXECINSTR)
3748 type = 'T';
3749 else if (sec->header.sh_flags & SHF_WRITE)
3750 type = 'D';
3751 else
3752 type = 'R';
3753 }
3754 value = sym->value + sec->header.sh_addr;
3755 }
3756
3757 if (ELF_ST_BIND(sym->info) == STB_LOCAL)
3758 type |= 0x20;
3759
3760 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value,
3761 type, sym->name);
3762 }
3763#endif
3764}
3765#else
3766static void print_load_map(struct obj_file *f UNUSED_PARAM)
3767{
3768}
3769#endif
3770
3771int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
3772{
3773 int k_crcs;
3774 unsigned long m_size;
3775 ElfW(Addr) m_addr;
3776 struct obj_file *f;
3777 int exit_status = EXIT_FAILURE;
3778 char *m_name;
3779#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3780 int m_has_modinfo;
3781#endif
3782 char *image;
3783 size_t image_size = 64 * 1024 * 1024;
3784
3785
3786 image = xmalloc_open_zipped_read_close(m_filename, &image_size);
3787 if (!image)
3788 return EXIT_FAILURE;
3789
3790 m_name = xstrdup(bb_basename(m_filename));
3791
3792 *strchrnul(m_name, '.') = '\0';
3793
3794 f = obj_load(image, image_size, LOADBITS);
3795
3796#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3797
3798 m_has_modinfo = (get_modinfo_value(f, "kernel_version") != NULL);
3799 if (!flag_quiet) {
3800 char m_strversion[STRVERSIONLEN];
3801 struct utsname uts;
3802
3803 if (m_has_modinfo) {
3804 int m_version = new_get_module_version(f, m_strversion);
3805 if (m_version == -1) {
3806 bb_error_msg_and_die("can't find the kernel version "
3807 "the module was compiled for");
3808 }
3809 }
3810
3811 uname(&uts);
3812 if (strncmp(uts.release, m_strversion, STRVERSIONLEN) != 0) {
3813 bb_error_msg("%skernel-module version mismatch\n"
3814 "\t%s was compiled for kernel version %s\n"
3815 "\twhile this kernel is version %s",
3816 flag_force_load ? "warning: " : "",
3817 m_name, m_strversion, uts.release);
3818 if (!flag_force_load)
3819 goto out;
3820 }
3821 }
3822#endif
3823
3824 if (query_module(NULL, 0, NULL, 0, NULL))
3825 bb_error_msg_and_die("old (unsupported) kernel");
3826 new_get_kernel_symbols();
3827 k_crcs = new_is_kernel_checksummed();
3828
3829#if ENABLE_FEATURE_INSMOD_VERSION_CHECKING
3830 {
3831 int m_crcs = 0;
3832 if (m_has_modinfo)
3833 m_crcs = new_is_module_checksummed(f);
3834 if (m_crcs != k_crcs)
3835 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash);
3836 }
3837#endif
3838
3839
3840 add_kernel_symbols(f);
3841
3842
3843 new_create_this_module(f, m_name);
3844 obj_check_undefineds(f);
3845 obj_allocate_commons(f);
3846 check_tainted_module(f, m_name);
3847
3848
3849 new_process_module_arguments(f, options);
3850
3851 arch_create_got(f);
3852 hide_special_symbols(f);
3853
3854#if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
3855 add_ksymoops_symbols(f, m_filename, m_name);
3856#endif
3857
3858 new_create_module_ksymtab(f);
3859
3860
3861 m_size = obj_load_size(f);
3862
3863 m_addr = create_module(m_name, m_size);
3864 if (m_addr == (ElfW(Addr))(-1)) switch (errno) {
3865 case EEXIST:
3866 bb_error_msg_and_die("a module named %s already exists", m_name);
3867 case ENOMEM:
3868 bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes",
3869 m_size);
3870 default:
3871 bb_perror_msg_and_die("create_module: %s", m_name);
3872 }
3873
3874#if !LOADBITS
3875
3876
3877
3878
3879 if (!obj_load_progbits(image, image_size, f, (char*)m_addr)) {
3880 delete_module(m_name, 0);
3881 goto out;
3882 }
3883#endif
3884
3885 if (!obj_relocate(f, m_addr)) {
3886 delete_module(m_name, 0);
3887 goto out;
3888 }
3889
3890 if (!new_init_module(m_name, f, m_size)) {
3891 delete_module(m_name, 0);
3892 goto out;
3893 }
3894
3895 if (flag_print_load_map)
3896 print_load_map(f);
3897
3898 exit_status = EXIT_SUCCESS;
3899
3900 out:
3901 free(image);
3902 free(m_name);
3903
3904 return exit_status;
3905}
3906