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