diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-12-24 20:30:45 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-12-24 20:30:45 +0000 |
commit | 3b1a74467a0909a62f26f6f27ac63ea922939c4d (patch) | |
tree | 982459b4484a823360ec90628a18d72e26902fbf | |
parent | d242e49c894cd0a8b6b016e8f1865651c1c5fef7 (diff) | |
download | busybox-w32-3b1a74467a0909a62f26f6f27ac63ea922939c4d.tar.gz busybox-w32-3b1a74467a0909a62f26f6f27ac63ea922939c4d.tar.bz2 busybox-w32-3b1a74467a0909a62f26f6f27ac63ea922939c4d.zip |
re-indent
-rw-r--r-- | modutils/insmod.c | 1967 | ||||
-rw-r--r-- | modutils/modprobe.c | 230 | ||||
-rw-r--r-- | modutils/rmmod.c | 2 |
3 files changed, 1100 insertions, 1099 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index 554c97693..e69a1bb04 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -282,7 +282,7 @@ extern int insmod_ng_main( int argc, char **argv); | |||
282 | #ifndef MODUTILS_MODULE_H | 282 | #ifndef MODUTILS_MODULE_H |
283 | static const int MODUTILS_MODULE_H = 1; | 283 | static const int MODUTILS_MODULE_H = 1; |
284 | 284 | ||
285 | #ident "$Id: insmod.c,v 1.108 2003/12/19 21:04:19 andersen Exp $" | 285 | #ident "$Id: insmod.c,v 1.109 2003/12/24 20:30:45 andersen Exp $" |
286 | 286 | ||
287 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | 287 | /* This file contains the structures used by the 2.0 and 2.1 kernels. |
288 | We do not use the kernel headers directly because we do not wish | 288 | We do not use the kernel headers directly because we do not wish |
@@ -295,47 +295,47 @@ static const int MODUTILS_MODULE_H = 1; | |||
295 | /* The symbol format used by get_kernel_syms(2). */ | 295 | /* The symbol format used by get_kernel_syms(2). */ |
296 | struct old_kernel_sym | 296 | struct old_kernel_sym |
297 | { | 297 | { |
298 | unsigned long value; | 298 | unsigned long value; |
299 | char name[60]; | 299 | char name[60]; |
300 | }; | 300 | }; |
301 | 301 | ||
302 | struct old_module_ref | 302 | struct old_module_ref |
303 | { | 303 | { |
304 | unsigned long module; /* kernel addresses */ | 304 | unsigned long module; /* kernel addresses */ |
305 | unsigned long next; | 305 | unsigned long next; |
306 | }; | 306 | }; |
307 | 307 | ||
308 | struct old_module_symbol | 308 | struct old_module_symbol |
309 | { | 309 | { |
310 | unsigned long addr; | 310 | unsigned long addr; |
311 | unsigned long name; | 311 | unsigned long name; |
312 | }; | 312 | }; |
313 | 313 | ||
314 | struct old_symbol_table | 314 | struct old_symbol_table |
315 | { | 315 | { |
316 | int size; /* total, including string table!!! */ | 316 | int size; /* total, including string table!!! */ |
317 | int n_symbols; | 317 | int n_symbols; |
318 | int n_refs; | 318 | int n_refs; |
319 | struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */ | 319 | struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */ |
320 | struct old_module_ref ref[0]; /* actual size defined by n_refs */ | 320 | struct old_module_ref ref[0]; /* actual size defined by n_refs */ |
321 | }; | 321 | }; |
322 | 322 | ||
323 | struct old_mod_routines | 323 | struct old_mod_routines |
324 | { | 324 | { |
325 | unsigned long init; | 325 | unsigned long init; |
326 | unsigned long cleanup; | 326 | unsigned long cleanup; |
327 | }; | 327 | }; |
328 | 328 | ||
329 | struct old_module | 329 | struct old_module |
330 | { | 330 | { |
331 | unsigned long next; | 331 | unsigned long next; |
332 | unsigned long ref; /* the list of modules that refer to me */ | 332 | unsigned long ref; /* the list of modules that refer to me */ |
333 | unsigned long symtab; | 333 | unsigned long symtab; |
334 | unsigned long name; | 334 | unsigned long name; |
335 | int size; /* size of module in pages */ | 335 | int size; /* size of module in pages */ |
336 | unsigned long addr; /* address of module */ | 336 | unsigned long addr; /* address of module */ |
337 | int state; | 337 | int state; |
338 | unsigned long cleanup; /* cleanup routine */ | 338 | unsigned long cleanup; /* cleanup routine */ |
339 | }; | 339 | }; |
340 | 340 | ||
341 | /* Sent to init_module(2) or'ed into the code size parameter. */ | 341 | /* Sent to init_module(2) or'ed into the code size parameter. */ |
@@ -374,53 +374,53 @@ static const int tgt_sizeof_void_p = 8; | |||
374 | /* Note: new_module_symbol does not use tgt_long intentionally */ | 374 | /* Note: new_module_symbol does not use tgt_long intentionally */ |
375 | struct new_module_symbol | 375 | struct new_module_symbol |
376 | { | 376 | { |
377 | unsigned long value; | 377 | unsigned long value; |
378 | unsigned long name; | 378 | unsigned long name; |
379 | }; | 379 | }; |
380 | 380 | ||
381 | struct new_module_persist; | 381 | struct new_module_persist; |
382 | 382 | ||
383 | struct new_module_ref | 383 | struct new_module_ref |
384 | { | 384 | { |
385 | unsigned tgt_long dep; /* kernel addresses */ | 385 | unsigned tgt_long dep; /* kernel addresses */ |
386 | unsigned tgt_long ref; | 386 | unsigned tgt_long ref; |
387 | unsigned tgt_long next_ref; | 387 | unsigned tgt_long next_ref; |
388 | }; | 388 | }; |
389 | 389 | ||
390 | struct new_module | 390 | struct new_module |
391 | { | 391 | { |
392 | unsigned tgt_long size_of_struct; /* == sizeof(module) */ | 392 | unsigned tgt_long size_of_struct; /* == sizeof(module) */ |
393 | unsigned tgt_long next; | 393 | unsigned tgt_long next; |
394 | unsigned tgt_long name; | 394 | unsigned tgt_long name; |
395 | unsigned tgt_long size; | 395 | unsigned tgt_long size; |
396 | 396 | ||
397 | tgt_long usecount; | 397 | tgt_long usecount; |
398 | unsigned tgt_long flags; /* AUTOCLEAN et al */ | 398 | unsigned tgt_long flags; /* AUTOCLEAN et al */ |
399 | 399 | ||
400 | unsigned nsyms; | 400 | unsigned nsyms; |
401 | unsigned ndeps; | 401 | unsigned ndeps; |
402 | 402 | ||
403 | unsigned tgt_long syms; | 403 | unsigned tgt_long syms; |
404 | unsigned tgt_long deps; | 404 | unsigned tgt_long deps; |
405 | unsigned tgt_long refs; | 405 | unsigned tgt_long refs; |
406 | unsigned tgt_long init; | 406 | unsigned tgt_long init; |
407 | unsigned tgt_long cleanup; | 407 | unsigned tgt_long cleanup; |
408 | unsigned tgt_long ex_table_start; | 408 | unsigned tgt_long ex_table_start; |
409 | unsigned tgt_long ex_table_end; | 409 | unsigned tgt_long ex_table_end; |
410 | #ifdef __alpha__ | 410 | #ifdef __alpha__ |
411 | unsigned tgt_long gp; | 411 | unsigned tgt_long gp; |
412 | #endif | 412 | #endif |
413 | /* Everything after here is extension. */ | 413 | /* Everything after here is extension. */ |
414 | unsigned tgt_long persist_start; | 414 | unsigned tgt_long persist_start; |
415 | unsigned tgt_long persist_end; | 415 | unsigned tgt_long persist_end; |
416 | unsigned tgt_long can_unload; | 416 | unsigned tgt_long can_unload; |
417 | unsigned tgt_long runsize; | 417 | unsigned tgt_long runsize; |
418 | #ifdef CONFIG_FEATURE_2_4_MODULES | 418 | #ifdef CONFIG_FEATURE_2_4_MODULES |
419 | const char *kallsyms_start; /* All symbols for kernel debugging */ | 419 | const char *kallsyms_start; /* All symbols for kernel debugging */ |
420 | const char *kallsyms_end; | 420 | const char *kallsyms_end; |
421 | const char *archdata_start; /* arch specific data for module */ | 421 | const char *archdata_start; /* arch specific data for module */ |
422 | const char *archdata_end; | 422 | const char *archdata_end; |
423 | const char *kernel_data; /* Reserved for kernel internal use */ | 423 | const char *kernel_data; /* Reserved for kernel internal use */ |
424 | #endif | 424 | #endif |
425 | }; | 425 | }; |
426 | 426 | ||
@@ -434,10 +434,10 @@ struct new_module | |||
434 | 434 | ||
435 | struct new_module_info | 435 | struct new_module_info |
436 | { | 436 | { |
437 | unsigned long addr; | 437 | unsigned long addr; |
438 | unsigned long size; | 438 | unsigned long size; |
439 | unsigned long flags; | 439 | unsigned long flags; |
440 | long usecount; | 440 | long usecount; |
441 | }; | 441 | }; |
442 | 442 | ||
443 | /* Bits of module.flags. */ | 443 | /* Bits of module.flags. */ |
@@ -503,7 +503,7 @@ int delete_module(const char *); | |||
503 | #ifndef MODUTILS_OBJ_H | 503 | #ifndef MODUTILS_OBJ_H |
504 | static const int MODUTILS_OBJ_H = 1; | 504 | static const int MODUTILS_OBJ_H = 1; |
505 | 505 | ||
506 | #ident "$Id: insmod.c,v 1.108 2003/12/19 21:04:19 andersen Exp $" | 506 | #ident "$Id: insmod.c,v 1.109 2003/12/24 20:30:45 andersen Exp $" |
507 | 507 | ||
508 | /* The relocatable object is manipulated using elfin types. */ | 508 | /* The relocatable object is manipulated using elfin types. */ |
509 | 509 | ||
@@ -541,23 +541,23 @@ struct obj_symbol_patch; | |||
541 | 541 | ||
542 | struct obj_section | 542 | struct obj_section |
543 | { | 543 | { |
544 | ElfW(Shdr) header; | 544 | ElfW(Shdr) header; |
545 | const char *name; | 545 | const char *name; |
546 | char *contents; | 546 | char *contents; |
547 | struct obj_section *load_next; | 547 | struct obj_section *load_next; |
548 | int idx; | 548 | int idx; |
549 | }; | 549 | }; |
550 | 550 | ||
551 | struct obj_symbol | 551 | struct obj_symbol |
552 | { | 552 | { |
553 | struct obj_symbol *next; /* hash table link */ | 553 | struct obj_symbol *next; /* hash table link */ |
554 | const char *name; | 554 | const char *name; |
555 | unsigned long value; | 555 | unsigned long value; |
556 | unsigned long size; | 556 | unsigned long size; |
557 | int secidx; /* the defining section index/module */ | 557 | int secidx; /* the defining section index/module */ |
558 | int info; | 558 | int info; |
559 | int ksymidx; /* for export to the kernel symtab */ | 559 | int ksymidx; /* for export to the kernel symtab */ |
560 | int referenced; /* actually used in the link */ | 560 | int referenced; /* actually used in the link */ |
561 | }; | 561 | }; |
562 | 562 | ||
563 | /* Hardcode the hash table size. We shouldn't be needing so many | 563 | /* Hardcode the hash table size. We shouldn't be needing so many |
@@ -568,42 +568,42 @@ struct obj_symbol | |||
568 | 568 | ||
569 | struct obj_file | 569 | struct obj_file |
570 | { | 570 | { |
571 | ElfW(Ehdr) header; | 571 | ElfW(Ehdr) header; |
572 | ElfW(Addr) baseaddr; | 572 | ElfW(Addr) baseaddr; |
573 | struct obj_section **sections; | 573 | struct obj_section **sections; |
574 | struct obj_section *load_order; | 574 | struct obj_section *load_order; |
575 | struct obj_section **load_order_search_start; | 575 | struct obj_section **load_order_search_start; |
576 | struct obj_string_patch *string_patches; | 576 | struct obj_string_patch *string_patches; |
577 | struct obj_symbol_patch *symbol_patches; | 577 | struct obj_symbol_patch *symbol_patches; |
578 | int (*symbol_cmp)(const char *, const char *); | 578 | int (*symbol_cmp)(const char *, const char *); |
579 | unsigned long (*symbol_hash)(const char *); | 579 | unsigned long (*symbol_hash)(const char *); |
580 | unsigned long local_symtab_size; | 580 | unsigned long local_symtab_size; |
581 | struct obj_symbol **local_symtab; | 581 | struct obj_symbol **local_symtab; |
582 | struct obj_symbol *symtab[HASH_BUCKETS]; | 582 | struct obj_symbol *symtab[HASH_BUCKETS]; |
583 | }; | 583 | }; |
584 | 584 | ||
585 | enum obj_reloc | 585 | enum obj_reloc |
586 | { | 586 | { |
587 | obj_reloc_ok, | 587 | obj_reloc_ok, |
588 | obj_reloc_overflow, | 588 | obj_reloc_overflow, |
589 | obj_reloc_dangerous, | 589 | obj_reloc_dangerous, |
590 | obj_reloc_unhandled | 590 | obj_reloc_unhandled |
591 | }; | 591 | }; |
592 | 592 | ||
593 | struct obj_string_patch | 593 | struct obj_string_patch |
594 | { | 594 | { |
595 | struct obj_string_patch *next; | 595 | struct obj_string_patch *next; |
596 | int reloc_secidx; | 596 | int reloc_secidx; |
597 | ElfW(Addr) reloc_offset; | 597 | ElfW(Addr) reloc_offset; |
598 | ElfW(Addr) string_offset; | 598 | ElfW(Addr) string_offset; |
599 | }; | 599 | }; |
600 | 600 | ||
601 | struct obj_symbol_patch | 601 | struct obj_symbol_patch |
602 | { | 602 | { |
603 | struct obj_symbol_patch *next; | 603 | struct obj_symbol_patch *next; |
604 | int reloc_secidx; | 604 | int reloc_secidx; |
605 | ElfW(Addr) reloc_offset; | 605 | ElfW(Addr) reloc_offset; |
606 | struct obj_symbol *sym; | 606 | struct obj_symbol *sym; |
607 | }; | 607 | }; |
608 | 608 | ||
609 | 609 | ||
@@ -739,9 +739,9 @@ struct arch_single_entry | |||
739 | #if defined(__mips__) | 739 | #if defined(__mips__) |
740 | struct mips_hi16 | 740 | struct mips_hi16 |
741 | { | 741 | { |
742 | struct mips_hi16 *next; | 742 | struct mips_hi16 *next; |
743 | Elf32_Addr *addr; | 743 | Elf32_Addr *addr; |
744 | Elf32_Addr value; | 744 | Elf32_Addr value; |
745 | }; | 745 | }; |
746 | #endif | 746 | #endif |
747 | 747 | ||
@@ -877,547 +877,547 @@ arch_apply_relocation(struct obj_file *f, | |||
877 | 877 | ||
878 | 878 | ||
879 | #if defined(__arm__) | 879 | #if defined(__arm__) |
880 | case R_ARM_NONE: | 880 | case R_ARM_NONE: |
881 | break; | 881 | break; |
882 | 882 | ||
883 | case R_ARM_ABS32: | 883 | case R_ARM_ABS32: |
884 | *loc += v; | 884 | *loc += v; |
885 | break; | 885 | break; |
886 | 886 | ||
887 | case R_ARM_GOT32: | 887 | case R_ARM_GOT32: |
888 | goto bb_use_got; | 888 | goto bb_use_got; |
889 | 889 | ||
890 | case R_ARM_GOTPC: | 890 | case R_ARM_GOTPC: |
891 | /* relative reloc, always to _GLOBAL_OFFSET_TABLE_ | 891 | /* relative reloc, always to _GLOBAL_OFFSET_TABLE_ |
892 | * (which is .got) similar to branch, | 892 | * (which is .got) similar to branch, |
893 | * but is full 32 bits relative */ | 893 | * but is full 32 bits relative */ |
894 | 894 | ||
895 | assert(got); | 895 | assert(got); |
896 | *loc += got - dot; | 896 | *loc += got - dot; |
897 | break; | 897 | break; |
898 | 898 | ||
899 | case R_ARM_PC24: | 899 | case R_ARM_PC24: |
900 | case R_ARM_PLT32: | 900 | case R_ARM_PLT32: |
901 | goto bb_use_plt; | 901 | goto bb_use_plt; |
902 | 902 | ||
903 | case R_ARM_GOTOFF: /* address relative to the got */ | 903 | case R_ARM_GOTOFF: /* address relative to the got */ |
904 | assert(got); | 904 | assert(got); |
905 | *loc += v - got; | 905 | *loc += v - got; |
906 | break; | 906 | break; |
907 | 907 | ||
908 | #elif defined(__s390__) | 908 | #elif defined(__s390__) |
909 | case R_390_32: | 909 | case R_390_32: |
910 | *(unsigned int *) loc += v; | 910 | *(unsigned int *) loc += v; |
911 | break; | 911 | break; |
912 | case R_390_16: | 912 | case R_390_16: |
913 | *(unsigned short *) loc += v; | 913 | *(unsigned short *) loc += v; |
914 | break; | 914 | break; |
915 | case R_390_8: | 915 | case R_390_8: |
916 | *(unsigned char *) loc += v; | 916 | *(unsigned char *) loc += v; |
917 | break; | 917 | break; |
918 | 918 | ||
919 | case R_390_PC32: | 919 | case R_390_PC32: |
920 | *(unsigned int *) loc += v - dot; | 920 | *(unsigned int *) loc += v - dot; |
921 | break; | 921 | break; |
922 | case R_390_PC16DBL: | 922 | case R_390_PC16DBL: |
923 | *(unsigned short *) loc += (v - dot) >> 1; | 923 | *(unsigned short *) loc += (v - dot) >> 1; |
924 | break; | 924 | break; |
925 | case R_390_PC16: | 925 | case R_390_PC16: |
926 | *(unsigned short *) loc += v - dot; | 926 | *(unsigned short *) loc += v - dot; |
927 | break; | 927 | break; |
928 | 928 | ||
929 | case R_390_PLT32: | 929 | case R_390_PLT32: |
930 | case R_390_PLT16DBL: | 930 | case R_390_PLT16DBL: |
931 | /* find the plt entry and initialize it. */ | 931 | /* find the plt entry and initialize it. */ |
932 | assert(isym != NULL); | 932 | assert(isym != NULL); |
933 | pe = (struct arch_single_entry *) &isym->pltent; | 933 | pe = (struct arch_single_entry *) &isym->pltent; |
934 | assert(pe->allocated); | 934 | assert(pe->allocated); |
935 | if (pe->inited == 0) { | 935 | if (pe->inited == 0) { |
936 | ip = (unsigned long *)(ifile->plt->contents + pe->offset); | 936 | ip = (unsigned long *)(ifile->plt->contents + pe->offset); |
937 | ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */ | 937 | ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */ |
938 | ip[1] = 0x100607f1; | 938 | ip[1] = 0x100607f1; |
939 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) | 939 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) |
940 | ip[2] = v - 2; | 940 | ip[2] = v - 2; |
941 | else | 941 | else |
942 | ip[2] = v; | 942 | ip[2] = v; |
943 | pe->inited = 1; | 943 | pe->inited = 1; |
944 | } | 944 | } |
945 | 945 | ||
946 | /* Insert relative distance to target. */ | 946 | /* Insert relative distance to target. */ |
947 | v = plt + pe->offset - dot; | 947 | v = plt + pe->offset - dot; |
948 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32) | 948 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32) |
949 | *(unsigned int *) loc = (unsigned int) v; | 949 | *(unsigned int *) loc = (unsigned int) v; |
950 | else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) | 950 | else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) |
951 | *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1); | 951 | *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1); |
952 | break; | 952 | break; |
953 | 953 | ||
954 | case R_390_GLOB_DAT: | 954 | case R_390_GLOB_DAT: |
955 | case R_390_JMP_SLOT: | 955 | case R_390_JMP_SLOT: |
956 | *loc = v; | 956 | *loc = v; |
957 | break; | 957 | break; |
958 | 958 | ||
959 | case R_390_RELATIVE: | 959 | case R_390_RELATIVE: |
960 | *loc += f->baseaddr; | 960 | *loc += f->baseaddr; |
961 | break; | 961 | break; |
962 | 962 | ||
963 | case R_390_GOTPC: | 963 | case R_390_GOTPC: |
964 | assert(got != 0); | 964 | assert(got != 0); |
965 | *(unsigned long *) loc += got - dot; | 965 | *(unsigned long *) loc += got - dot; |
966 | break; | 966 | break; |
967 | 967 | ||
968 | case R_390_GOT12: | 968 | case R_390_GOT12: |
969 | case R_390_GOT16: | 969 | case R_390_GOT16: |
970 | case R_390_GOT32: | 970 | case R_390_GOT32: |
971 | assert(isym != NULL); | 971 | assert(isym != NULL); |
972 | assert(got != 0); | 972 | assert(got != 0); |
973 | if (!isym->gotent.inited) | 973 | if (!isym->gotent.inited) |
974 | { | 974 | { |
975 | isym->gotent.inited = 1; | 975 | isym->gotent.inited = 1; |
976 | *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; | 976 | *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; |
977 | } | 977 | } |
978 | if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12) | 978 | if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12) |
979 | *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff; | 979 | *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff; |
980 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16) | 980 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16) |
981 | *(unsigned short *) loc += isym->gotent.offset; | 981 | *(unsigned short *) loc += isym->gotent.offset; |
982 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32) | 982 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32) |
983 | *(unsigned int *) loc += isym->gotent.offset; | 983 | *(unsigned int *) loc += isym->gotent.offset; |
984 | break; | 984 | break; |
985 | 985 | ||
986 | #ifndef R_390_GOTOFF32 | 986 | #ifndef R_390_GOTOFF32 |
987 | #define R_390_GOTOFF32 R_390_GOTOFF | 987 | #define R_390_GOTOFF32 R_390_GOTOFF |
988 | #endif | 988 | #endif |
989 | case R_390_GOTOFF32: | 989 | case R_390_GOTOFF32: |
990 | assert(got != 0); | 990 | assert(got != 0); |
991 | *loc += v - got; | 991 | *loc += v - got; |
992 | break; | 992 | break; |
993 | 993 | ||
994 | #elif defined(__i386__) | 994 | #elif defined(__i386__) |
995 | 995 | ||
996 | case R_386_NONE: | 996 | case R_386_NONE: |
997 | break; | 997 | break; |
998 | 998 | ||
999 | case R_386_32: | 999 | case R_386_32: |
1000 | *loc += v; | 1000 | *loc += v; |
1001 | break; | 1001 | break; |
1002 | 1002 | ||
1003 | case R_386_PLT32: | 1003 | case R_386_PLT32: |
1004 | case R_386_PC32: | 1004 | case R_386_PC32: |
1005 | *loc += v - dot; | 1005 | *loc += v - dot; |
1006 | break; | 1006 | break; |
1007 | 1007 | ||
1008 | case R_386_GLOB_DAT: | 1008 | case R_386_GLOB_DAT: |
1009 | case R_386_JMP_SLOT: | 1009 | case R_386_JMP_SLOT: |
1010 | *loc = v; | 1010 | *loc = v; |
1011 | break; | 1011 | break; |
1012 | 1012 | ||
1013 | case R_386_RELATIVE: | 1013 | case R_386_RELATIVE: |
1014 | *loc += f->baseaddr; | 1014 | *loc += f->baseaddr; |
1015 | break; | 1015 | break; |
1016 | 1016 | ||
1017 | case R_386_GOTPC: | 1017 | case R_386_GOTPC: |
1018 | assert(got != 0); | 1018 | assert(got != 0); |
1019 | *loc += got - dot; | 1019 | *loc += got - dot; |
1020 | break; | 1020 | break; |
1021 | 1021 | ||
1022 | case R_386_GOT32: | 1022 | case R_386_GOT32: |
1023 | goto bb_use_got; | 1023 | goto bb_use_got; |
1024 | 1024 | ||
1025 | case R_386_GOTOFF: | 1025 | case R_386_GOTOFF: |
1026 | assert(got != 0); | 1026 | assert(got != 0); |
1027 | *loc += v - got; | 1027 | *loc += v - got; |
1028 | break; | 1028 | break; |
1029 | 1029 | ||
1030 | #elif defined(__mc68000__) | 1030 | #elif defined(__mc68000__) |
1031 | 1031 | ||
1032 | case R_68K_NONE: | 1032 | case R_68K_NONE: |
1033 | break; | 1033 | break; |
1034 | 1034 | ||
1035 | case R_68K_32: | 1035 | case R_68K_32: |
1036 | *loc += v; | 1036 | *loc += v; |
1037 | break; | 1037 | break; |
1038 | 1038 | ||
1039 | case R_68K_8: | 1039 | case R_68K_8: |
1040 | if (v > 0xff) { | 1040 | if (v > 0xff) { |
1041 | ret = obj_reloc_overflow; | 1041 | ret = obj_reloc_overflow; |
1042 | } | 1042 | } |
1043 | *(char *)loc = v; | 1043 | *(char *)loc = v; |
1044 | break; | 1044 | break; |
1045 | 1045 | ||
1046 | case R_68K_16: | 1046 | case R_68K_16: |
1047 | if (v > 0xffff) { | 1047 | if (v > 0xffff) { |
1048 | ret = obj_reloc_overflow; | 1048 | ret = obj_reloc_overflow; |
1049 | } | 1049 | } |
1050 | *(short *)loc = v; | 1050 | *(short *)loc = v; |
1051 | break; | 1051 | break; |
1052 | 1052 | ||
1053 | case R_68K_PC8: | 1053 | case R_68K_PC8: |
1054 | v -= dot; | 1054 | v -= dot; |
1055 | if ((Elf32_Sword)v > 0x7f || | 1055 | if ((Elf32_Sword)v > 0x7f || |
1056 | (Elf32_Sword)v < -(Elf32_Sword)0x80) { | 1056 | (Elf32_Sword)v < -(Elf32_Sword)0x80) { |
1057 | ret = obj_reloc_overflow; | 1057 | ret = obj_reloc_overflow; |
1058 | } | 1058 | } |
1059 | *(char *)loc = v; | 1059 | *(char *)loc = v; |
1060 | break; | 1060 | break; |
1061 | 1061 | ||
1062 | case R_68K_PC16: | 1062 | case R_68K_PC16: |
1063 | v -= dot; | 1063 | v -= dot; |
1064 | if ((Elf32_Sword)v > 0x7fff || | 1064 | if ((Elf32_Sword)v > 0x7fff || |
1065 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1065 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { |
1066 | ret = obj_reloc_overflow; | 1066 | ret = obj_reloc_overflow; |
1067 | } | 1067 | } |
1068 | *(short *)loc = v; | 1068 | *(short *)loc = v; |
1069 | break; | 1069 | break; |
1070 | 1070 | ||
1071 | case R_68K_PC32: | 1071 | case R_68K_PC32: |
1072 | *(int *)loc = v - dot; | 1072 | *(int *)loc = v - dot; |
1073 | break; | 1073 | break; |
1074 | 1074 | ||
1075 | case R_68K_GLOB_DAT: | 1075 | case R_68K_GLOB_DAT: |
1076 | case R_68K_JMP_SLOT: | 1076 | case R_68K_JMP_SLOT: |
1077 | *loc = v; | 1077 | *loc = v; |
1078 | break; | 1078 | break; |
1079 | 1079 | ||
1080 | case R_68K_RELATIVE: | 1080 | case R_68K_RELATIVE: |
1081 | *(int *)loc += f->baseaddr; | 1081 | *(int *)loc += f->baseaddr; |
1082 | break; | 1082 | break; |
1083 | 1083 | ||
1084 | case R_68K_GOT32: | 1084 | case R_68K_GOT32: |
1085 | goto bb_use_got; | 1085 | goto bb_use_got; |
1086 | 1086 | ||
1087 | case R_68K_GOTOFF: | 1087 | case R_68K_GOTOFF: |
1088 | assert(got != 0); | 1088 | assert(got != 0); |
1089 | *loc += v - got; | 1089 | *loc += v - got; |
1090 | break; | 1090 | break; |
1091 | 1091 | ||
1092 | #elif defined(__mips__) | 1092 | #elif defined(__mips__) |
1093 | 1093 | ||
1094 | case R_MIPS_NONE: | 1094 | case R_MIPS_NONE: |
1095 | break; | 1095 | break; |
1096 | 1096 | ||
1097 | case R_MIPS_32: | 1097 | case R_MIPS_32: |
1098 | *loc += v; | 1098 | *loc += v; |
1099 | break; | 1099 | break; |
1100 | 1100 | ||
1101 | case R_MIPS_26: | 1101 | case R_MIPS_26: |
1102 | if (v % 4) | 1102 | if (v % 4) |
1103 | ret = obj_reloc_dangerous; | 1103 | ret = obj_reloc_dangerous; |
1104 | if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000)) | 1104 | if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000)) |
1105 | ret = obj_reloc_overflow; | 1105 | ret = obj_reloc_overflow; |
1106 | *loc = | 1106 | *loc = |
1107 | (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & | 1107 | (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & |
1108 | 0x03ffffff); | 1108 | 0x03ffffff); |
1109 | break; | 1109 | break; |
1110 | 1110 | ||
1111 | case R_MIPS_HI16: | 1111 | case R_MIPS_HI16: |
1112 | { | 1112 | { |
1113 | struct mips_hi16 *n; | 1113 | struct mips_hi16 *n; |
1114 | 1114 | ||
1115 | /* We cannot relocate this one now because we don't know the value | 1115 | /* We cannot relocate this one now because we don't know the value |
1116 | of the carry we need to add. Save the information, and let LO16 | 1116 | of the carry we need to add. Save the information, and let LO16 |
1117 | do the actual relocation. */ | 1117 | do the actual relocation. */ |
1118 | n = (struct mips_hi16 *) xmalloc(sizeof *n); | 1118 | n = (struct mips_hi16 *) xmalloc(sizeof *n); |
1119 | n->addr = loc; | 1119 | n->addr = loc; |
1120 | n->value = v; | 1120 | n->value = v; |
1121 | n->next = ifile->mips_hi16_list; | 1121 | n->next = ifile->mips_hi16_list; |
1122 | ifile->mips_hi16_list = n; | 1122 | ifile->mips_hi16_list = n; |
1123 | break; | 1123 | break; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | case R_MIPS_LO16: | 1126 | case R_MIPS_LO16: |
1127 | { | 1127 | { |
1128 | unsigned long insnlo = *loc; | 1128 | unsigned long insnlo = *loc; |
1129 | Elf32_Addr val, vallo; | 1129 | Elf32_Addr val, vallo; |
1130 | 1130 | ||
1131 | /* Sign extend the addend we extract from the lo insn. */ | 1131 | /* Sign extend the addend we extract from the lo insn. */ |
1132 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; | 1132 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; |
1133 | 1133 | ||
1134 | if (ifile->mips_hi16_list != NULL) { | 1134 | if (ifile->mips_hi16_list != NULL) { |
1135 | struct mips_hi16 *l; | 1135 | struct mips_hi16 *l; |
1136 | 1136 | ||
1137 | l = ifile->mips_hi16_list; | 1137 | l = ifile->mips_hi16_list; |
1138 | while (l != NULL) { | 1138 | while (l != NULL) { |
1139 | struct mips_hi16 *next; | 1139 | struct mips_hi16 *next; |
1140 | unsigned long insn; | 1140 | unsigned long insn; |
1141 | 1141 | ||
1142 | /* The value for the HI16 had best be the same. */ | 1142 | /* The value for the HI16 had best be the same. */ |
1143 | assert(v == l->value); | 1143 | assert(v == l->value); |
1144 | 1144 | ||
1145 | /* Do the HI16 relocation. Note that we actually don't | 1145 | /* Do the HI16 relocation. Note that we actually don't |
1146 | need to know anything about the LO16 itself, except where | 1146 | need to know anything about the LO16 itself, except where |
1147 | to find the low 16 bits of the addend needed by the LO16. */ | 1147 | to find the low 16 bits of the addend needed by the LO16. */ |
1148 | insn = *l->addr; | 1148 | insn = *l->addr; |
1149 | val = | 1149 | val = |
1150 | ((insn & 0xffff) << 16) + | 1150 | ((insn & 0xffff) << 16) + |
1151 | vallo; | 1151 | vallo; |
1152 | val += v; | 1152 | val += v; |
1153 | 1153 | ||
1154 | /* Account for the sign extension that will happen in the | 1154 | /* Account for the sign extension that will happen in the |
1155 | low bits. */ | 1155 | low bits. */ |
1156 | val = | 1156 | val = |
1157 | ((val >> 16) + | 1157 | ((val >> 16) + |
1158 | ((val & 0x8000) != | 1158 | ((val & 0x8000) != |
1159 | 0)) & 0xffff; | 1159 | 0)) & 0xffff; |
1160 | 1160 | ||
1161 | insn = (insn & ~0xffff) | val; | 1161 | insn = (insn & ~0xffff) | val; |
1162 | *l->addr = insn; | 1162 | *l->addr = insn; |
1163 | 1163 | ||
1164 | next = l->next; | 1164 | next = l->next; |
1165 | free(l); | 1165 | free(l); |
1166 | l = next; | 1166 | l = next; |
1167 | } | ||
1168 | |||
1169 | ifile->mips_hi16_list = NULL; | ||
1167 | } | 1170 | } |
1168 | 1171 | ||
1169 | ifile->mips_hi16_list = NULL; | 1172 | /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */ |
1173 | val = v + vallo; | ||
1174 | insnlo = (insnlo & ~0xffff) | (val & 0xffff); | ||
1175 | *loc = insnlo; | ||
1176 | break; | ||
1170 | } | 1177 | } |
1171 | 1178 | ||
1172 | /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */ | ||
1173 | val = v + vallo; | ||
1174 | insnlo = (insnlo & ~0xffff) | (val & 0xffff); | ||
1175 | *loc = insnlo; | ||
1176 | break; | ||
1177 | } | ||
1178 | |||
1179 | #elif defined(__powerpc__) | 1179 | #elif defined(__powerpc__) |
1180 | 1180 | ||
1181 | case R_PPC_ADDR16_HA: | 1181 | case R_PPC_ADDR16_HA: |
1182 | *(unsigned short *)loc = (v + 0x8000) >> 16; | 1182 | *(unsigned short *)loc = (v + 0x8000) >> 16; |
1183 | break; | 1183 | break; |
1184 | 1184 | ||
1185 | case R_PPC_ADDR16_HI: | 1185 | case R_PPC_ADDR16_HI: |
1186 | *(unsigned short *)loc = v >> 16; | 1186 | *(unsigned short *)loc = v >> 16; |
1187 | break; | 1187 | break; |
1188 | 1188 | ||
1189 | case R_PPC_ADDR16_LO: | 1189 | case R_PPC_ADDR16_LO: |
1190 | *(unsigned short *)loc = v; | 1190 | *(unsigned short *)loc = v; |
1191 | break; | 1191 | break; |
1192 | 1192 | ||
1193 | case R_PPC_REL24: | 1193 | case R_PPC_REL24: |
1194 | goto bb_use_plt; | 1194 | goto bb_use_plt; |
1195 | 1195 | ||
1196 | case R_PPC_REL32: | 1196 | case R_PPC_REL32: |
1197 | *loc = v - dot; | 1197 | *loc = v - dot; |
1198 | break; | 1198 | break; |
1199 | 1199 | ||
1200 | case R_PPC_ADDR32: | 1200 | case R_PPC_ADDR32: |
1201 | *loc = v; | 1201 | *loc = v; |
1202 | break; | 1202 | break; |
1203 | 1203 | ||
1204 | #elif defined(__sh__) | 1204 | #elif defined(__sh__) |
1205 | 1205 | ||
1206 | case R_SH_NONE: | 1206 | case R_SH_NONE: |
1207 | break; | 1207 | break; |
1208 | 1208 | ||
1209 | case R_SH_DIR32: | 1209 | case R_SH_DIR32: |
1210 | *loc += v; | 1210 | *loc += v; |
1211 | break; | 1211 | break; |
1212 | 1212 | ||
1213 | case R_SH_REL32: | 1213 | case R_SH_REL32: |
1214 | *loc += v - dot; | 1214 | *loc += v - dot; |
1215 | break; | 1215 | break; |
1216 | |||
1217 | case R_SH_PLT32: | ||
1218 | *loc = v - dot; | ||
1219 | break; | ||
1220 | 1216 | ||
1221 | case R_SH_GLOB_DAT: | 1217 | case R_SH_PLT32: |
1222 | case R_SH_JMP_SLOT: | 1218 | *loc = v - dot; |
1223 | *loc = v; | 1219 | break; |
1224 | break; | ||
1225 | 1220 | ||
1226 | case R_SH_RELATIVE: | 1221 | case R_SH_GLOB_DAT: |
1227 | *loc = f->baseaddr + rel->r_addend; | 1222 | case R_SH_JMP_SLOT: |
1228 | break; | 1223 | *loc = v; |
1224 | break; | ||
1229 | 1225 | ||
1230 | case R_SH_GOTPC: | 1226 | case R_SH_RELATIVE: |
1231 | assert(got != 0); | 1227 | *loc = f->baseaddr + rel->r_addend; |
1232 | *loc = got - dot + rel->r_addend; | 1228 | break; |
1233 | break; | ||
1234 | 1229 | ||
1235 | case R_SH_GOT32: | 1230 | case R_SH_GOTPC: |
1236 | goto bb_use_got; | 1231 | assert(got != 0); |
1232 | *loc = got - dot + rel->r_addend; | ||
1233 | break; | ||
1237 | 1234 | ||
1238 | case R_SH_GOTOFF: | 1235 | case R_SH_GOT32: |
1239 | assert(got != 0); | 1236 | goto bb_use_got; |
1240 | *loc = v - got; | 1237 | |
1241 | break; | 1238 | case R_SH_GOTOFF: |
1239 | assert(got != 0); | ||
1240 | *loc = v - got; | ||
1241 | break; | ||
1242 | 1242 | ||
1243 | #if defined(__SH5__) | 1243 | #if defined(__SH5__) |
1244 | case R_SH_IMM_MEDLOW16: | 1244 | case R_SH_IMM_MEDLOW16: |
1245 | case R_SH_IMM_LOW16: | 1245 | case R_SH_IMM_LOW16: |
1246 | { | 1246 | { |
1247 | Elf32_Addr word; | 1247 | Elf32_Addr word; |
1248 | |||
1249 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16) | ||
1250 | v >>= 16; | ||
1251 | |||
1252 | /* | ||
1253 | * movi and shori have the format: | ||
1254 | * | ||
1255 | * | op | imm | reg | reserved | | ||
1256 | * 31..26 25..10 9.. 4 3 .. 0 | ||
1257 | * | ||
1258 | * so we simply mask and or in imm. | ||
1259 | */ | ||
1260 | word = *loc & ~0x3fffc00; | ||
1261 | word |= (v & 0xffff) << 10; | ||
1262 | 1248 | ||
1263 | *loc = word; | 1249 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16) |
1250 | v >>= 16; | ||
1264 | 1251 | ||
1265 | break; | 1252 | /* |
1266 | } | 1253 | * movi and shori have the format: |
1254 | * | ||
1255 | * | op | imm | reg | reserved | | ||
1256 | * 31..26 25..10 9.. 4 3 .. 0 | ||
1257 | * | ||
1258 | * so we simply mask and or in imm. | ||
1259 | */ | ||
1260 | word = *loc & ~0x3fffc00; | ||
1261 | word |= (v & 0xffff) << 10; | ||
1267 | 1262 | ||
1268 | case R_SH_IMM_MEDLOW16_PCREL: | 1263 | *loc = word; |
1269 | case R_SH_IMM_LOW16_PCREL: | ||
1270 | { | ||
1271 | Elf32_Addr word; | ||
1272 | 1264 | ||
1273 | word = *loc & ~0x3fffc00; | 1265 | break; |
1266 | } | ||
1274 | 1267 | ||
1275 | v -= dot; | 1268 | case R_SH_IMM_MEDLOW16_PCREL: |
1269 | case R_SH_IMM_LOW16_PCREL: | ||
1270 | { | ||
1271 | Elf32_Addr word; | ||
1276 | 1272 | ||
1277 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL) | 1273 | word = *loc & ~0x3fffc00; |
1278 | v >>= 16; | ||
1279 | 1274 | ||
1280 | word |= (v & 0xffff) << 10; | 1275 | v -= dot; |
1281 | 1276 | ||
1282 | *loc = word; | 1277 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL) |
1278 | v >>= 16; | ||
1283 | 1279 | ||
1284 | break; | 1280 | word |= (v & 0xffff) << 10; |
1285 | } | 1281 | |
1282 | *loc = word; | ||
1283 | |||
1284 | break; | ||
1285 | } | ||
1286 | #endif /* __SH5__ */ | 1286 | #endif /* __SH5__ */ |
1287 | #endif /* __sh__ */ | 1287 | #endif /* __sh__ */ |
1288 | 1288 | ||
1289 | default: | 1289 | default: |
1290 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); | 1290 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); |
1291 | ret = obj_reloc_unhandled; | 1291 | ret = obj_reloc_unhandled; |
1292 | break; | 1292 | break; |
1293 | 1293 | ||
1294 | #if defined (__v850e__) | 1294 | #if defined (__v850e__) |
1295 | case R_V850_NONE: | 1295 | case R_V850_NONE: |
1296 | break; | 1296 | break; |
1297 | 1297 | ||
1298 | case R_V850_32: | 1298 | case R_V850_32: |
1299 | /* We write two shorts instead of a long because even | 1299 | /* We write two shorts instead of a long because even |
1300 | 32-bit insns only need half-word alignment, but | 1300 | 32-bit insns only need half-word alignment, but |
1301 | 32-bit data needs to be long-word aligned. */ | 1301 | 32-bit data needs to be long-word aligned. */ |
1302 | v += ((unsigned short *)loc)[0]; | 1302 | v += ((unsigned short *)loc)[0]; |
1303 | v += ((unsigned short *)loc)[1] << 16; | 1303 | v += ((unsigned short *)loc)[1] << 16; |
1304 | ((unsigned short *)loc)[0] = v & 0xffff; | 1304 | ((unsigned short *)loc)[0] = v & 0xffff; |
1305 | ((unsigned short *)loc)[1] = (v >> 16) & 0xffff; | 1305 | ((unsigned short *)loc)[1] = (v >> 16) & 0xffff; |
1306 | break; | 1306 | break; |
1307 | 1307 | ||
1308 | case R_V850_22_PCREL: | 1308 | case R_V850_22_PCREL: |
1309 | goto bb_use_plt; | 1309 | goto bb_use_plt; |
1310 | #endif | 1310 | #endif |
1311 | 1311 | ||
1312 | #if defined (__cris__) | 1312 | #if defined (__cris__) |
1313 | case R_CRIS_NONE: | 1313 | case R_CRIS_NONE: |
1314 | break; | 1314 | break; |
1315 | 1315 | ||
1316 | case R_CRIS_32: | 1316 | case R_CRIS_32: |
1317 | /* CRIS keeps the relocation value in the r_addend field and | 1317 | /* CRIS keeps the relocation value in the r_addend field and |
1318 | * should not use whats in *loc at all | 1318 | * should not use whats in *loc at all |
1319 | */ | 1319 | */ |
1320 | *loc = v; | 1320 | *loc = v; |
1321 | break; | 1321 | break; |
1322 | #endif | 1322 | #endif |
1323 | 1323 | ||
1324 | #if defined(CONFIG_USE_PLT_ENTRIES) | 1324 | #if defined(CONFIG_USE_PLT_ENTRIES) |
1325 | 1325 | ||
1326 | bb_use_plt: | 1326 | bb_use_plt: |
1327 | 1327 | ||
1328 | /* find the plt entry and initialize it if necessary */ | 1328 | /* find the plt entry and initialize it if necessary */ |
1329 | assert(isym != NULL); | 1329 | assert(isym != NULL); |
1330 | 1330 | ||
1331 | #if defined(CONFIG_USE_PLT_LIST) | 1331 | #if defined(CONFIG_USE_PLT_LIST) |
1332 | for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;) | 1332 | for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;) |
1333 | pe = pe->next; | 1333 | pe = pe->next; |
1334 | assert(pe != NULL); | 1334 | assert(pe != NULL); |
1335 | #else | 1335 | #else |
1336 | pe = &isym->pltent; | 1336 | pe = &isym->pltent; |
1337 | #endif | 1337 | #endif |
1338 | 1338 | ||
1339 | if (! pe->inited) { | 1339 | if (! pe->inited) { |
1340 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); | 1340 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); |
1341 | 1341 | ||
1342 | /* generate some machine code */ | 1342 | /* generate some machine code */ |
1343 | 1343 | ||
1344 | #if defined(__arm__) | 1344 | #if defined(__arm__) |
1345 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ | 1345 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ |
1346 | ip[1] = v; /* sym@ */ | 1346 | ip[1] = v; /* sym@ */ |
1347 | #endif | 1347 | #endif |
1348 | #if defined(__powerpc__) | 1348 | #if defined(__powerpc__) |
1349 | ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ | 1349 | ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ |
1350 | ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ | 1350 | ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ |
1351 | ip[2] = 0x7d6903a6; /* mtctr r11 */ | 1351 | ip[2] = 0x7d6903a6; /* mtctr r11 */ |
1352 | ip[3] = 0x4e800420; /* bctr */ | 1352 | ip[3] = 0x4e800420; /* bctr */ |
1353 | #endif | 1353 | #endif |
1354 | #if defined (__v850e__) | 1354 | #if defined (__v850e__) |
1355 | /* We have to trash a register, so we assume that any control | 1355 | /* We have to trash a register, so we assume that any control |
1356 | transfer more than 21-bits away must be a function call | 1356 | transfer more than 21-bits away must be a function call |
1357 | (so we can use a call-clobbered register). */ | 1357 | (so we can use a call-clobbered register). */ |
1358 | ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */ | 1358 | ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */ |
1359 | ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */ | 1359 | ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */ |
1360 | #endif | 1360 | #endif |
1361 | pe->inited = 1; | 1361 | pe->inited = 1; |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | /* relative distance to target */ | 1364 | /* relative distance to target */ |
1365 | v -= dot; | 1365 | v -= dot; |
1366 | /* if the target is too far away.... */ | 1366 | /* if the target is too far away.... */ |
1367 | #if defined (__arm__) || defined (__powerpc__) | 1367 | #if defined (__arm__) || defined (__powerpc__) |
1368 | if ((int)v < -0x02000000 || (int)v >= 0x02000000) | 1368 | if ((int)v < -0x02000000 || (int)v >= 0x02000000) |
1369 | #elif defined (__v850e__) | 1369 | #elif defined (__v850e__) |
1370 | if ((Elf32_Sword)v > 0x1fffff || (Elf32_Sword)v < (Elf32_Sword)-0x200000) | 1370 | if ((Elf32_Sword)v > 0x1fffff || (Elf32_Sword)v < (Elf32_Sword)-0x200000) |
1371 | #endif | 1371 | #endif |
1372 | /* go via the plt */ | 1372 | /* go via the plt */ |
1373 | v = plt + pe->offset - dot; | 1373 | v = plt + pe->offset - dot; |
1374 | 1374 | ||
1375 | #if defined (__v850e__) | 1375 | #if defined (__v850e__) |
1376 | if (v & 1) | 1376 | if (v & 1) |
1377 | #else | 1377 | #else |
1378 | if (v & 3) | 1378 | if (v & 3) |
1379 | #endif | 1379 | #endif |
1380 | ret = obj_reloc_dangerous; | 1380 | ret = obj_reloc_dangerous; |
1381 | 1381 | ||
1382 | /* merge the offset into the instruction. */ | 1382 | /* merge the offset into the instruction. */ |
1383 | #if defined(__arm__) | 1383 | #if defined(__arm__) |
1384 | /* Convert to words. */ | 1384 | /* Convert to words. */ |
1385 | v >>= 2; | 1385 | v >>= 2; |
1386 | 1386 | ||
1387 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); | 1387 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); |
1388 | #endif | 1388 | #endif |
1389 | #if defined(__powerpc__) | 1389 | #if defined(__powerpc__) |
1390 | *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); | 1390 | *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); |
1391 | #endif | 1391 | #endif |
1392 | #if defined (__v850e__) | 1392 | #if defined (__v850e__) |
1393 | /* We write two shorts instead of a long because even 32-bit insns | 1393 | /* We write two shorts instead of a long because even 32-bit insns |
1394 | only need half-word alignment, but the 32-bit data write needs | 1394 | only need half-word alignment, but the 32-bit data write needs |
1395 | to be long-word aligned. */ | 1395 | to be long-word aligned. */ |
1396 | ((unsigned short *)loc)[0] = | 1396 | ((unsigned short *)loc)[0] = |
1397 | (*(unsigned short *)loc & 0xffc0) /* opcode + reg */ | 1397 | (*(unsigned short *)loc & 0xffc0) /* opcode + reg */ |
1398 | | ((v >> 16) & 0x3f); /* offs high part */ | 1398 | | ((v >> 16) & 0x3f); /* offs high part */ |
1399 | ((unsigned short *)loc)[1] = | 1399 | ((unsigned short *)loc)[1] = |
1400 | (v & 0xffff); /* offs low part */ | 1400 | (v & 0xffff); /* offs low part */ |
1401 | #endif | 1401 | #endif |
1402 | break; | 1402 | break; |
1403 | #endif /* CONFIG_USE_PLT_ENTRIES */ | 1403 | #endif /* CONFIG_USE_PLT_ENTRIES */ |
1404 | 1404 | ||
1405 | #if defined(CONFIG_USE_GOT_ENTRIES) | 1405 | #if defined(CONFIG_USE_GOT_ENTRIES) |
1406 | bb_use_got: | 1406 | bb_use_got: |
1407 | 1407 | ||
1408 | assert(isym != NULL); | 1408 | assert(isym != NULL); |
1409 | /* needs an entry in the .got: set it, once */ | 1409 | /* needs an entry in the .got: set it, once */ |
1410 | if (!isym->gotent.inited) { | 1410 | if (!isym->gotent.inited) { |
1411 | isym->gotent.inited = 1; | 1411 | isym->gotent.inited = 1; |
1412 | *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v; | 1412 | *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v; |
1413 | } | 1413 | } |
1414 | /* make the reloc with_respect_to_.got */ | 1414 | /* make the reloc with_respect_to_.got */ |
1415 | #if defined(__sh__) | 1415 | #if defined(__sh__) |
1416 | *loc += isym->gotent.offset + rel->r_addend; | 1416 | *loc += isym->gotent.offset + rel->r_addend; |
1417 | #elif defined(__i386__) || defined(__arm__) || defined(__mc68000__) | 1417 | #elif defined(__i386__) || defined(__arm__) || defined(__mc68000__) |
1418 | *loc += isym->gotent.offset; | 1418 | *loc += isym->gotent.offset; |
1419 | #endif | 1419 | #endif |
1420 | break; | 1420 | break; |
1421 | 1421 | ||
1422 | #endif /* CONFIG_USE_GOT_ENTRIES */ | 1422 | #endif /* CONFIG_USE_GOT_ENTRIES */ |
1423 | } | 1423 | } |
@@ -1484,7 +1484,7 @@ static struct obj_section *arch_xsect_init(struct obj_file *f, char *name, | |||
1484 | obj_extend_section(myrelsec, offset); | 1484 | obj_extend_section(myrelsec, offset); |
1485 | } else { | 1485 | } else { |
1486 | myrelsec = obj_create_alloced_section(f, name, | 1486 | myrelsec = obj_create_alloced_section(f, name, |
1487 | size, offset); | 1487 | size, offset); |
1488 | assert(myrelsec); | 1488 | assert(myrelsec); |
1489 | } | 1489 | } |
1490 | 1490 | ||
@@ -1504,7 +1504,7 @@ static void arch_create_got(struct obj_file *f) | |||
1504 | #if defined(CONFIG_USE_PLT_ENTRIES) | 1504 | #if defined(CONFIG_USE_PLT_ENTRIES) |
1505 | int plt_offset = 0, plt_needed = 0, plt_allocate; | 1505 | int plt_offset = 0, plt_needed = 0, plt_allocate; |
1506 | #endif | 1506 | #endif |
1507 | struct obj_section *relsec, *symsec, *strsec; | 1507 | struct obj_section *relsec, *symsec, *strsec; |
1508 | ElfW(RelM) *rel, *relend; | 1508 | ElfW(RelM) *rel, *relend; |
1509 | ElfW(Sym) *symtab, *extsym; | 1509 | ElfW(Sym) *symtab, *extsym; |
1510 | const char *strtab, *name; | 1510 | const char *strtab, *name; |
@@ -1535,62 +1535,62 @@ static void arch_create_got(struct obj_file *f) | |||
1535 | 1535 | ||
1536 | switch (ELF32_R_TYPE(rel->r_info)) { | 1536 | switch (ELF32_R_TYPE(rel->r_info)) { |
1537 | #if defined(__arm__) | 1537 | #if defined(__arm__) |
1538 | case R_ARM_PC24: | 1538 | case R_ARM_PC24: |
1539 | case R_ARM_PLT32: | 1539 | case R_ARM_PLT32: |
1540 | plt_allocate = 1; | 1540 | plt_allocate = 1; |
1541 | break; | 1541 | break; |
1542 | 1542 | ||
1543 | case R_ARM_GOTOFF: | 1543 | case R_ARM_GOTOFF: |
1544 | case R_ARM_GOTPC: | 1544 | case R_ARM_GOTPC: |
1545 | got_needed = 1; | 1545 | got_needed = 1; |
1546 | continue; | 1546 | continue; |
1547 | 1547 | ||
1548 | case R_ARM_GOT32: | 1548 | case R_ARM_GOT32: |
1549 | got_allocate = 1; | 1549 | got_allocate = 1; |
1550 | break; | 1550 | break; |
1551 | 1551 | ||
1552 | #elif defined(__i386__) | 1552 | #elif defined(__i386__) |
1553 | case R_386_GOTPC: | 1553 | case R_386_GOTPC: |
1554 | case R_386_GOTOFF: | 1554 | case R_386_GOTOFF: |
1555 | got_needed = 1; | 1555 | got_needed = 1; |
1556 | continue; | 1556 | continue; |
1557 | 1557 | ||
1558 | case R_386_GOT32: | 1558 | case R_386_GOT32: |
1559 | got_allocate = 1; | 1559 | got_allocate = 1; |
1560 | break; | 1560 | break; |
1561 | 1561 | ||
1562 | #elif defined(__powerpc__) | 1562 | #elif defined(__powerpc__) |
1563 | case R_PPC_REL24: | 1563 | case R_PPC_REL24: |
1564 | plt_allocate = 1; | 1564 | plt_allocate = 1; |
1565 | break; | 1565 | break; |
1566 | 1566 | ||
1567 | #elif defined(__mc68000__) | 1567 | #elif defined(__mc68000__) |
1568 | case R_68K_GOT32: | 1568 | case R_68K_GOT32: |
1569 | got_allocate = 1; | 1569 | got_allocate = 1; |
1570 | break; | 1570 | break; |
1571 | 1571 | ||
1572 | case R_68K_GOTOFF: | 1572 | case R_68K_GOTOFF: |
1573 | got_needed = 1; | 1573 | got_needed = 1; |
1574 | continue; | 1574 | continue; |
1575 | 1575 | ||
1576 | #elif defined(__sh__) | 1576 | #elif defined(__sh__) |
1577 | case R_SH_GOT32: | 1577 | case R_SH_GOT32: |
1578 | got_allocate = 1; | 1578 | got_allocate = 1; |
1579 | break; | 1579 | break; |
1580 | 1580 | ||
1581 | case R_SH_GOTPC: | 1581 | case R_SH_GOTPC: |
1582 | case R_SH_GOTOFF: | 1582 | case R_SH_GOTOFF: |
1583 | got_needed = 1; | 1583 | got_needed = 1; |
1584 | continue; | 1584 | continue; |
1585 | 1585 | ||
1586 | #elif defined (__v850e__) | 1586 | #elif defined (__v850e__) |
1587 | case R_V850_22_PCREL: | 1587 | case R_V850_22_PCREL: |
1588 | plt_needed = 1; | 1588 | plt_needed = 1; |
1589 | break; | 1589 | break; |
1590 | 1590 | ||
1591 | #endif | 1591 | #endif |
1592 | default: | 1592 | default: |
1593 | continue; | 1593 | continue; |
1594 | } | 1594 | } |
1595 | 1595 | ||
1596 | if (extsym->st_name != 0) { | 1596 | if (extsym->st_name != 0) { |
@@ -1602,8 +1602,8 @@ static void arch_create_got(struct obj_file *f) | |||
1602 | #if defined(CONFIG_USE_GOT_ENTRIES) | 1602 | #if defined(CONFIG_USE_GOT_ENTRIES) |
1603 | if (got_allocate) { | 1603 | if (got_allocate) { |
1604 | got_offset += arch_single_init( | 1604 | got_offset += arch_single_init( |
1605 | rel, &intsym->gotent, | 1605 | rel, &intsym->gotent, |
1606 | got_offset, CONFIG_GOT_ENTRY_SIZE); | 1606 | got_offset, CONFIG_GOT_ENTRY_SIZE); |
1607 | 1607 | ||
1608 | got_needed = 1; | 1608 | got_needed = 1; |
1609 | } | 1609 | } |
@@ -1612,12 +1612,12 @@ static void arch_create_got(struct obj_file *f) | |||
1612 | if (plt_allocate) { | 1612 | if (plt_allocate) { |
1613 | #if defined(CONFIG_USE_PLT_LIST) | 1613 | #if defined(CONFIG_USE_PLT_LIST) |
1614 | plt_offset += arch_list_add( | 1614 | plt_offset += arch_list_add( |
1615 | rel, &intsym->pltent, | 1615 | rel, &intsym->pltent, |
1616 | plt_offset, CONFIG_PLT_ENTRY_SIZE); | 1616 | plt_offset, CONFIG_PLT_ENTRY_SIZE); |
1617 | #else | 1617 | #else |
1618 | plt_offset += arch_single_init( | 1618 | plt_offset += arch_single_init( |
1619 | rel, &intsym->pltent, | 1619 | rel, &intsym->pltent, |
1620 | plt_offset, CONFIG_PLT_ENTRY_SIZE); | 1620 | plt_offset, CONFIG_PLT_ENTRY_SIZE); |
1621 | #endif | 1621 | #endif |
1622 | plt_needed = 1; | 1622 | plt_needed = 1; |
1623 | } | 1623 | } |
@@ -1628,14 +1628,14 @@ static void arch_create_got(struct obj_file *f) | |||
1628 | #if defined(CONFIG_USE_GOT_ENTRIES) | 1628 | #if defined(CONFIG_USE_GOT_ENTRIES) |
1629 | if (got_needed) { | 1629 | if (got_needed) { |
1630 | ifile->got = arch_xsect_init(f, ".got", got_offset, | 1630 | ifile->got = arch_xsect_init(f, ".got", got_offset, |
1631 | CONFIG_GOT_ENTRY_SIZE); | 1631 | CONFIG_GOT_ENTRY_SIZE); |
1632 | } | 1632 | } |
1633 | #endif | 1633 | #endif |
1634 | 1634 | ||
1635 | #if defined(CONFIG_USE_PLT_ENTRIES) | 1635 | #if defined(CONFIG_USE_PLT_ENTRIES) |
1636 | if (plt_needed) { | 1636 | if (plt_needed) { |
1637 | ifile->plt = arch_xsect_init(f, ".plt", plt_offset, | 1637 | ifile->plt = arch_xsect_init(f, ".plt", plt_offset, |
1638 | CONFIG_PLT_ENTRY_SIZE); | 1638 | CONFIG_PLT_ENTRY_SIZE); |
1639 | } | 1639 | } |
1640 | #endif | 1640 | #endif |
1641 | 1641 | ||
@@ -1786,10 +1786,10 @@ obj_add_symbol(struct obj_file *f, const char *name, | |||
1786 | /* Don't unify COMMON symbols with object types the programmer | 1786 | /* Don't unify COMMON symbols with object types the programmer |
1787 | doesn't expect. */ | 1787 | doesn't expect. */ |
1788 | else if (secidx == SHN_COMMON | 1788 | else if (secidx == SHN_COMMON |
1789 | && (o_type == STT_NOTYPE || o_type == STT_OBJECT)) | 1789 | && (o_type == STT_NOTYPE || o_type == STT_OBJECT)) |
1790 | return sym; | 1790 | return sym; |
1791 | else if (o_secidx == SHN_COMMON | 1791 | else if (o_secidx == SHN_COMMON |
1792 | && (n_type == STT_NOTYPE || n_type == STT_OBJECT)) | 1792 | && (n_type == STT_NOTYPE || n_type == STT_OBJECT)) |
1793 | goto found; | 1793 | goto found; |
1794 | else { | 1794 | else { |
1795 | /* Don't report an error if the symbol is coming from | 1795 | /* Don't report an error if the symbol is coming from |
@@ -1814,7 +1814,7 @@ obj_add_symbol(struct obj_file *f, const char *name, | |||
1814 | f->local_symtab[symidx] = sym; | 1814 | f->local_symtab[symidx] = sym; |
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | found: | 1817 | found: |
1818 | sym->name = name; | 1818 | sym->name = name; |
1819 | sym->value = value; | 1819 | sym->value = value; |
1820 | sym->size = size; | 1820 | sym->size = size; |
@@ -1870,7 +1870,7 @@ static int obj_load_order_prio(struct obj_section *a) | |||
1870 | 1870 | ||
1871 | ac = 0; | 1871 | ac = 0; |
1872 | if (a->name[0] != '.' || strlen(a->name) != 10 || | 1872 | if (a->name[0] != '.' || strlen(a->name) != 10 || |
1873 | strcmp(a->name + 5, ".init")) | 1873 | strcmp(a->name + 5, ".init")) |
1874 | ac |= 32; | 1874 | ac |= 32; |
1875 | if (af & SHF_ALLOC) | 1875 | if (af & SHF_ALLOC) |
1876 | ac |= 16; | 1876 | ac |= 16; |
@@ -2028,9 +2028,9 @@ add_symbols_from( | |||
2028 | strcpy (name, name_buf); | 2028 | strcpy (name, name_buf); |
2029 | #endif | 2029 | #endif |
2030 | sym = obj_add_symbol(f, name, -1, | 2030 | sym = obj_add_symbol(f, name, -1, |
2031 | ELFW(ST_INFO) (STB_GLOBAL, | 2031 | ELFW(ST_INFO) (STB_GLOBAL, |
2032 | STT_NOTYPE), | 2032 | STT_NOTYPE), |
2033 | idx, s->value, 0); | 2033 | idx, s->value, 0); |
2034 | /* Did our symbol just get installed? If so, mark the | 2034 | /* Did our symbol just get installed? If so, mark the |
2035 | module as "used". */ | 2035 | module as "used". */ |
2036 | if (sym->secidx == idx) | 2036 | if (sym->secidx == idx) |
@@ -2050,8 +2050,8 @@ static void add_kernel_symbols(struct obj_file *f) | |||
2050 | 2050 | ||
2051 | for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) | 2051 | for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) |
2052 | if (m->nsyms | 2052 | if (m->nsyms |
2053 | && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, | 2053 | && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, |
2054 | m->nsyms)) m->used = 1, ++nused; | 2054 | m->nsyms)) m->used = 1, ++nused; |
2055 | 2055 | ||
2056 | n_ext_modules_used = nused; | 2056 | n_ext_modules_used = nused; |
2057 | 2057 | ||
@@ -2104,7 +2104,7 @@ old_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
2104 | if ((q = strchr(p, '=')) == NULL) { | 2104 | if ((q = strchr(p, '=')) == NULL) { |
2105 | argc--; | 2105 | argc--; |
2106 | continue; | 2106 | continue; |
2107 | } | 2107 | } |
2108 | *q++ = '\0'; | 2108 | *q++ = '\0'; |
2109 | 2109 | ||
2110 | sym = obj_find_symbol(f, p); | 2110 | sym = obj_find_symbol(f, p); |
@@ -2128,52 +2128,52 @@ old_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
2128 | return 0; | 2128 | return 0; |
2129 | } else if (*q == '\\') | 2129 | } else if (*q == '\\') |
2130 | switch (*++q) { | 2130 | switch (*++q) { |
2131 | case 'a': | 2131 | case 'a': |
2132 | *r = '\a'; | 2132 | *r = '\a'; |
2133 | break; | 2133 | break; |
2134 | case 'b': | 2134 | case 'b': |
2135 | *r = '\b'; | 2135 | *r = '\b'; |
2136 | break; | 2136 | break; |
2137 | case 'e': | 2137 | case 'e': |
2138 | *r = '\033'; | 2138 | *r = '\033'; |
2139 | break; | 2139 | break; |
2140 | case 'f': | 2140 | case 'f': |
2141 | *r = '\f'; | 2141 | *r = '\f'; |
2142 | break; | 2142 | break; |
2143 | case 'n': | 2143 | case 'n': |
2144 | *r = '\n'; | 2144 | *r = '\n'; |
2145 | break; | 2145 | break; |
2146 | case 'r': | 2146 | case 'r': |
2147 | *r = '\r'; | 2147 | *r = '\r'; |
2148 | break; | 2148 | break; |
2149 | case 't': | 2149 | case 't': |
2150 | *r = '\t'; | 2150 | *r = '\t'; |
2151 | break; | 2151 | break; |
2152 | 2152 | ||
2153 | case '0': | 2153 | case '0': |
2154 | case '1': | 2154 | case '1': |
2155 | case '2': | 2155 | case '2': |
2156 | case '3': | 2156 | case '3': |
2157 | case '4': | 2157 | case '4': |
2158 | case '5': | 2158 | case '5': |
2159 | case '6': | 2159 | case '6': |
2160 | case '7': | 2160 | case '7': |
2161 | { | 2161 | { |
2162 | int c = *q - '0'; | 2162 | int c = *q - '0'; |
2163 | if (q[1] >= '0' && q[1] <= '7') { | 2163 | if (q[1] >= '0' && q[1] <= '7') { |
2164 | c = (c * 8) + *++q - '0'; | ||
2165 | if (q[1] >= '0' && q[1] <= '7') | ||
2166 | c = (c * 8) + *++q - '0'; | 2164 | c = (c * 8) + *++q - '0'; |
2165 | if (q[1] >= '0' && q[1] <= '7') | ||
2166 | c = (c * 8) + *++q - '0'; | ||
2167 | } | ||
2168 | *r = c; | ||
2167 | } | 2169 | } |
2168 | *r = c; | 2170 | break; |
2169 | } | ||
2170 | break; | ||
2171 | 2171 | ||
2172 | default: | 2172 | default: |
2173 | *r = *q; | ||
2174 | break; | ||
2175 | } else | ||
2173 | *r = *q; | 2176 | *r = *q; |
2174 | break; | ||
2175 | } else | ||
2176 | *r = *q; | ||
2177 | } | 2177 | } |
2178 | *r = '\0'; | 2178 | *r = '\0'; |
2179 | obj_string_patch(f, sym->secidx, sym->value, str); | 2179 | obj_string_patch(f, sym->secidx, sym->value, str); |
@@ -2264,7 +2264,7 @@ static int old_get_kernel_symbols(const char *m_name) | |||
2264 | 2264 | ||
2265 | if (get_kernel_syms(ks) != nks) { | 2265 | if (get_kernel_syms(ks) != nks) { |
2266 | perror("inconsistency with get_kernel_syms -- is someone else " | 2266 | perror("inconsistency with get_kernel_syms -- is someone else " |
2267 | "playing with modules?"); | 2267 | "playing with modules?"); |
2268 | free(ks); | 2268 | free(ks); |
2269 | return 0; | 2269 | return 0; |
2270 | } | 2270 | } |
@@ -2322,8 +2322,8 @@ static int old_is_kernel_checksummed(void) | |||
2322 | { | 2322 | { |
2323 | /* Using_Versions is the first symbol. */ | 2323 | /* Using_Versions is the first symbol. */ |
2324 | if (nksyms > 0 | 2324 | if (nksyms > 0 |
2325 | && strcmp((char *) ksyms[0].name, | 2325 | && strcmp((char *) ksyms[0].name, |
2326 | "Using_Versions") == 0) return ksyms[0].value; | 2326 | "Using_Versions") == 0) return ksyms[0].value; |
2327 | else | 2327 | else |
2328 | return 0; | 2328 | return 0; |
2329 | } | 2329 | } |
@@ -2334,11 +2334,11 @@ static int old_create_mod_use_count(struct obj_file *f) | |||
2334 | struct obj_section *sec; | 2334 | struct obj_section *sec; |
2335 | 2335 | ||
2336 | sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long), | 2336 | sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long), |
2337 | sizeof(long)); | 2337 | sizeof(long)); |
2338 | 2338 | ||
2339 | obj_add_symbol(f, "mod_use_count_", -1, | 2339 | obj_add_symbol(f, "mod_use_count_", -1, |
2340 | ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, | 2340 | ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, |
2341 | sizeof(long)); | 2341 | sizeof(long)); |
2342 | 2342 | ||
2343 | return 1; | 2343 | return 1; |
2344 | } | 2344 | } |
@@ -2363,7 +2363,7 @@ old_init_module(const char *m_name, struct obj_file *f, | |||
2363 | struct obj_symbol *sym; | 2363 | struct obj_symbol *sym; |
2364 | for (sym = f->symtab[i]; sym; sym = sym->next) | 2364 | for (sym = f->symtab[i]; sym; sym = sym->next) |
2365 | if (ELFW(ST_BIND) (sym->info) != STB_LOCAL | 2365 | if (ELFW(ST_BIND) (sym->info) != STB_LOCAL |
2366 | && sym->secidx <= SHN_HIRESERVE) | 2366 | && sym->secidx <= SHN_HIRESERVE) |
2367 | { | 2367 | { |
2368 | sym->ksymidx = nsyms++; | 2368 | sym->ksymidx = nsyms++; |
2369 | strsize += strlen(sym->name) + 1; | 2369 | strsize += strlen(sym->name) + 1; |
@@ -2372,9 +2372,9 @@ old_init_module(const char *m_name, struct obj_file *f, | |||
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | total = (sizeof(struct old_symbol_table) | 2374 | total = (sizeof(struct old_symbol_table) |
2375 | + nsyms * sizeof(struct old_module_symbol) | 2375 | + nsyms * sizeof(struct old_module_symbol) |
2376 | + n_ext_modules_used * sizeof(struct old_module_ref) | 2376 | + n_ext_modules_used * sizeof(struct old_module_ref) |
2377 | + strsize); | 2377 | + strsize); |
2378 | symtab = xmalloc(total); | 2378 | symtab = xmalloc(total); |
2379 | symtab->size = total; | 2379 | symtab->size = total; |
2380 | symtab->n_symbols = nsyms; | 2380 | symtab->n_symbols = nsyms; |
@@ -2387,7 +2387,7 @@ old_init_module(const char *m_name, struct obj_file *f, | |||
2387 | 2387 | ||
2388 | ksym = symtab->symbol; | 2388 | ksym = symtab->symbol; |
2389 | str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol) | 2389 | str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol) |
2390 | + n_ext_modules_used * sizeof(struct old_module_ref)); | 2390 | + n_ext_modules_used * sizeof(struct old_module_ref)); |
2391 | 2391 | ||
2392 | for (i = 0; i < HASH_BUCKETS; ++i) { | 2392 | for (i = 0; i < HASH_BUCKETS; ++i) { |
2393 | struct obj_symbol *sym; | 2393 | struct obj_symbol *sym; |
@@ -2434,8 +2434,8 @@ old_init_module(const char *m_name, struct obj_file *f, | |||
2434 | mod_use_count. However the old module kernel support assume that | 2434 | mod_use_count. However the old module kernel support assume that |
2435 | it is receiving something which does not contain mod_use_count. */ | 2435 | it is receiving something which does not contain mod_use_count. */ |
2436 | ret = old_sys_init_module(m_name, image + sizeof(long), | 2436 | ret = old_sys_init_module(m_name, image + sizeof(long), |
2437 | m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN | 2437 | m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN |
2438 | : 0), &routines, symtab); | 2438 | : 0), &routines, symtab); |
2439 | if (ret) | 2439 | if (ret) |
2440 | bb_perror_msg("init_module: %s", m_name); | 2440 | bb_perror_msg("init_module: %s", m_name); |
2441 | 2441 | ||
@@ -2470,7 +2470,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
2470 | if ((q = strchr(p, '=')) == NULL) { | 2470 | if ((q = strchr(p, '=')) == NULL) { |
2471 | argc--; | 2471 | argc--; |
2472 | continue; | 2472 | continue; |
2473 | } | 2473 | } |
2474 | 2474 | ||
2475 | key = alloca(q - p + 6); | 2475 | key = alloca(q - p + 6); |
2476 | memcpy(key, "parm_", 5); | 2476 | memcpy(key, "parm_", 5); |
@@ -2528,52 +2528,52 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
2528 | return 0; | 2528 | return 0; |
2529 | } else if (*q == '\\') | 2529 | } else if (*q == '\\') |
2530 | switch (*++q) { | 2530 | switch (*++q) { |
2531 | case 'a': | 2531 | case 'a': |
2532 | *r = '\a'; | 2532 | *r = '\a'; |
2533 | break; | 2533 | break; |
2534 | case 'b': | 2534 | case 'b': |
2535 | *r = '\b'; | 2535 | *r = '\b'; |
2536 | break; | 2536 | break; |
2537 | case 'e': | 2537 | case 'e': |
2538 | *r = '\033'; | 2538 | *r = '\033'; |
2539 | break; | 2539 | break; |
2540 | case 'f': | 2540 | case 'f': |
2541 | *r = '\f'; | 2541 | *r = '\f'; |
2542 | break; | 2542 | break; |
2543 | case 'n': | 2543 | case 'n': |
2544 | *r = '\n'; | 2544 | *r = '\n'; |
2545 | break; | 2545 | break; |
2546 | case 'r': | 2546 | case 'r': |
2547 | *r = '\r'; | 2547 | *r = '\r'; |
2548 | break; | 2548 | break; |
2549 | case 't': | 2549 | case 't': |
2550 | *r = '\t'; | 2550 | *r = '\t'; |
2551 | break; | 2551 | break; |
2552 | 2552 | ||
2553 | case '0': | 2553 | case '0': |
2554 | case '1': | 2554 | case '1': |
2555 | case '2': | 2555 | case '2': |
2556 | case '3': | 2556 | case '3': |
2557 | case '4': | 2557 | case '4': |
2558 | case '5': | 2558 | case '5': |
2559 | case '6': | 2559 | case '6': |
2560 | case '7': | 2560 | case '7': |
2561 | { | 2561 | { |
2562 | int c = *q - '0'; | 2562 | int c = *q - '0'; |
2563 | if (q[1] >= '0' && q[1] <= '7') { | 2563 | if (q[1] >= '0' && q[1] <= '7') { |
2564 | c = (c * 8) + *++q - '0'; | ||
2565 | if (q[1] >= '0' && q[1] <= '7') | ||
2566 | c = (c * 8) + *++q - '0'; | 2564 | c = (c * 8) + *++q - '0'; |
2565 | if (q[1] >= '0' && q[1] <= '7') | ||
2566 | c = (c * 8) + *++q - '0'; | ||
2567 | } | ||
2568 | *r = c; | ||
2567 | } | 2569 | } |
2568 | *r = c; | 2570 | break; |
2569 | } | ||
2570 | break; | ||
2571 | 2571 | ||
2572 | default: | 2572 | default: |
2573 | *r = *q; | ||
2574 | break; | ||
2575 | } else | ||
2573 | *r = *q; | 2576 | *r = *q; |
2574 | break; | ||
2575 | } else | ||
2576 | *r = *q; | ||
2577 | } | 2577 | } |
2578 | *r = '\0'; | 2578 | *r = '\0'; |
2579 | ++q; | 2579 | ++q; |
@@ -2637,55 +2637,55 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
2637 | } else { | 2637 | } else { |
2638 | long v = strtoul(q, &q, 0); | 2638 | long v = strtoul(q, &q, 0); |
2639 | switch (*p) { | 2639 | switch (*p) { |
2640 | case 'b': | 2640 | case 'b': |
2641 | *loc++ = v; | 2641 | *loc++ = v; |
2642 | break; | 2642 | break; |
2643 | case 'h': | 2643 | case 'h': |
2644 | *(short *) loc = v; | 2644 | *(short *) loc = v; |
2645 | loc += tgt_sizeof_short; | 2645 | loc += tgt_sizeof_short; |
2646 | break; | 2646 | break; |
2647 | case 'i': | 2647 | case 'i': |
2648 | *(int *) loc = v; | 2648 | *(int *) loc = v; |
2649 | loc += tgt_sizeof_int; | 2649 | loc += tgt_sizeof_int; |
2650 | break; | 2650 | break; |
2651 | case 'l': | 2651 | case 'l': |
2652 | *(long *) loc = v; | 2652 | *(long *) loc = v; |
2653 | loc += tgt_sizeof_long; | 2653 | loc += tgt_sizeof_long; |
2654 | break; | 2654 | break; |
2655 | 2655 | ||
2656 | default: | 2656 | default: |
2657 | bb_error_msg("unknown parameter type '%c' for %s", *p, key); | 2657 | bb_error_msg("unknown parameter type '%c' for %s", *p, key); |
2658 | return 0; | 2658 | return 0; |
2659 | } | 2659 | } |
2660 | } | 2660 | } |
2661 | 2661 | ||
2662 | retry_end_of_value: | 2662 | retry_end_of_value: |
2663 | switch (*q) { | 2663 | switch (*q) { |
2664 | case '\0': | 2664 | case '\0': |
2665 | goto end_of_arg; | 2665 | goto end_of_arg; |
2666 | |||
2667 | case ' ': | ||
2668 | case '\t': | ||
2669 | case '\n': | ||
2670 | case '\r': | ||
2671 | ++q; | ||
2672 | goto retry_end_of_value; | ||
2673 | |||
2674 | case ',': | ||
2675 | if (++n > max) { | ||
2676 | bb_error_msg("too many values for %s (max %d)", key, max); | ||
2677 | return 0; | ||
2678 | } | ||
2679 | ++q; | ||
2680 | break; | ||
2681 | 2666 | ||
2682 | default: | 2667 | case ' ': |
2683 | bb_error_msg("invalid argument syntax for %s", key); | 2668 | case '\t': |
2684 | return 0; | 2669 | case '\n': |
2670 | case '\r': | ||
2671 | ++q; | ||
2672 | goto retry_end_of_value; | ||
2673 | |||
2674 | case ',': | ||
2675 | if (++n > max) { | ||
2676 | bb_error_msg("too many values for %s (max %d)", key, max); | ||
2677 | return 0; | ||
2678 | } | ||
2679 | ++q; | ||
2680 | break; | ||
2681 | |||
2682 | default: | ||
2683 | bb_error_msg("invalid argument syntax for %s", key); | ||
2684 | return 0; | ||
2685 | } | 2685 | } |
2686 | } | 2686 | } |
2687 | 2687 | ||
2688 | end_of_arg: | 2688 | end_of_arg: |
2689 | if (n < min) { | 2689 | if (n < min) { |
2690 | bb_error_msg("too few values for %s (min %d)", key, min); | 2690 | bb_error_msg("too few values for %s (min %d)", key, min); |
2691 | return 0; | 2691 | return 0; |
@@ -2750,7 +2750,7 @@ static int new_get_kernel_symbols(void) | |||
2750 | /* Collect the loaded modules. */ | 2750 | /* Collect the loaded modules. */ |
2751 | 2751 | ||
2752 | module_names = xmalloc(bufsize = 256); | 2752 | module_names = xmalloc(bufsize = 256); |
2753 | retry_modules_load: | 2753 | retry_modules_load: |
2754 | if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { | 2754 | if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { |
2755 | if (errno == ENOSPC && bufsize < ret) { | 2755 | if (errno == ENOSPC && bufsize < ret) { |
2756 | module_names = xrealloc(module_names, bufsize = ret); | 2756 | module_names = xrealloc(module_names, bufsize = ret); |
@@ -2768,9 +2768,9 @@ static int new_get_kernel_symbols(void) | |||
2768 | ext_modules = modules = xmalloc(nmod * sizeof(*modules)); | 2768 | ext_modules = modules = xmalloc(nmod * sizeof(*modules)); |
2769 | memset(modules, 0, nmod * sizeof(*modules)); | 2769 | memset(modules, 0, nmod * sizeof(*modules)); |
2770 | for (i = 0, mn = module_names, m = modules; | 2770 | for (i = 0, mn = module_names, m = modules; |
2771 | i < nmod; ++i, ++m, mn += strlen(mn) + 1) { | 2771 | i < nmod; ++i, ++m, mn += strlen(mn) + 1) { |
2772 | struct new_module_info info; | 2772 | struct new_module_info info; |
2773 | 2773 | ||
2774 | if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) { | 2774 | if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) { |
2775 | if (errno == ENOENT) { | 2775 | if (errno == ENOENT) { |
2776 | /* The module was removed out from underneath us. */ | 2776 | /* The module was removed out from underneath us. */ |
@@ -2779,29 +2779,29 @@ static int new_get_kernel_symbols(void) | |||
2779 | bb_perror_msg("query_module: QM_INFO: %s", mn); | 2779 | bb_perror_msg("query_module: QM_INFO: %s", mn); |
2780 | return 0; | 2780 | return 0; |
2781 | } | 2781 | } |
2782 | 2782 | ||
2783 | syms = xmalloc(bufsize = 1024); | 2783 | syms = xmalloc(bufsize = 1024); |
2784 | retry_mod_sym_load: | 2784 | retry_mod_sym_load: |
2785 | if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { | 2785 | if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { |
2786 | switch (errno) { | 2786 | switch (errno) { |
2787 | case ENOSPC: | 2787 | case ENOSPC: |
2788 | syms = xrealloc(syms, bufsize = ret); | 2788 | syms = xrealloc(syms, bufsize = ret); |
2789 | goto retry_mod_sym_load; | 2789 | goto retry_mod_sym_load; |
2790 | case ENOENT: | 2790 | case ENOENT: |
2791 | /* The module was removed out from underneath us. */ | 2791 | /* The module was removed out from underneath us. */ |
2792 | continue; | 2792 | continue; |
2793 | default: | 2793 | default: |
2794 | bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); | 2794 | bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); |
2795 | return 0; | 2795 | return 0; |
2796 | } | 2796 | } |
2797 | } | 2797 | } |
2798 | nsyms = ret; | 2798 | nsyms = ret; |
2799 | 2799 | ||
2800 | m->name = mn; | 2800 | m->name = mn; |
2801 | m->addr = info.addr; | 2801 | m->addr = info.addr; |
2802 | m->nsyms = nsyms; | 2802 | m->nsyms = nsyms; |
2803 | m->syms = syms; | 2803 | m->syms = syms; |
2804 | 2804 | ||
2805 | for (j = 0, s = syms; j < nsyms; ++j, ++s) { | 2805 | for (j = 0, s = syms; j < nsyms; ++j, ++s) { |
2806 | s->name += (unsigned long) syms; | 2806 | s->name += (unsigned long) syms; |
2807 | } | 2807 | } |
@@ -2811,7 +2811,7 @@ static int new_get_kernel_symbols(void) | |||
2811 | /* Collect the kernel's symbols. */ | 2811 | /* Collect the kernel's symbols. */ |
2812 | 2812 | ||
2813 | syms = xmalloc(bufsize = 16 * 1024); | 2813 | syms = xmalloc(bufsize = 16 * 1024); |
2814 | retry_kern_sym_load: | 2814 | retry_kern_sym_load: |
2815 | if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { | 2815 | if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { |
2816 | if (errno == ENOSPC && bufsize < ret) { | 2816 | if (errno == ENOSPC && bufsize < ret) { |
2817 | syms = xrealloc(syms, bufsize = ret); | 2817 | syms = xrealloc(syms, bufsize = ret); |
@@ -2852,15 +2852,15 @@ static int new_create_this_module(struct obj_file *f, const char *m_name) | |||
2852 | struct obj_section *sec; | 2852 | struct obj_section *sec; |
2853 | 2853 | ||
2854 | sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, | 2854 | sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, |
2855 | sizeof(struct new_module)); | 2855 | sizeof(struct new_module)); |
2856 | memset(sec->contents, 0, sizeof(struct new_module)); | 2856 | memset(sec->contents, 0, sizeof(struct new_module)); |
2857 | 2857 | ||
2858 | obj_add_symbol(f, SPFX "__this_module", -1, | 2858 | obj_add_symbol(f, SPFX "__this_module", -1, |
2859 | ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, | 2859 | ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, |
2860 | sizeof(struct new_module)); | 2860 | sizeof(struct new_module)); |
2861 | 2861 | ||
2862 | obj_string_patch(f, sec->idx, offsetof(struct new_module, name), | 2862 | obj_string_patch(f, sec->idx, offsetof(struct new_module, name), |
2863 | m_name); | 2863 | m_name); |
2864 | 2864 | ||
2865 | return 1; | 2865 | return 1; |
2866 | } | 2866 | } |
@@ -2884,12 +2884,12 @@ static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym) | |||
2884 | } | 2884 | } |
2885 | if (!sec) | 2885 | if (!sec) |
2886 | sec = obj_create_alloced_section(f, "__ksymtab", | 2886 | sec = obj_create_alloced_section(f, "__ksymtab", |
2887 | tgt_sizeof_void_p, 0); | 2887 | tgt_sizeof_void_p, 0); |
2888 | if (!sec) | 2888 | if (!sec) |
2889 | return; | 2889 | return; |
2890 | sec->header.sh_flags |= SHF_ALLOC; | 2890 | sec->header.sh_flags |= SHF_ALLOC; |
2891 | sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might | 2891 | sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might |
2892 | be byte-aligned */ | 2892 | be byte-aligned */ |
2893 | ofs = sec->header.sh_size; | 2893 | ofs = sec->header.sh_size; |
2894 | obj_symbol_patch(f, sec->idx, ofs, sym); | 2894 | obj_symbol_patch(f, sec->idx, ofs, sym); |
2895 | obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name); | 2895 | obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name); |
@@ -2909,8 +2909,8 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2909 | struct obj_symbol *tm; | 2909 | struct obj_symbol *tm; |
2910 | 2910 | ||
2911 | sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p, | 2911 | sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p, |
2912 | (sizeof(struct new_module_ref) | 2912 | (sizeof(struct new_module_ref) |
2913 | * n_ext_modules_used)); | 2913 | * n_ext_modules_used)); |
2914 | if (!sec) | 2914 | if (!sec) |
2915 | return 0; | 2915 | return 0; |
2916 | 2916 | ||
@@ -2920,7 +2920,7 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2920 | if (ext_modules[i].used) { | 2920 | if (ext_modules[i].used) { |
2921 | dep->dep = ext_modules[i].addr; | 2921 | dep->dep = ext_modules[i].addr; |
2922 | obj_symbol_patch(f, sec->idx, | 2922 | obj_symbol_patch(f, sec->idx, |
2923 | (char *) &dep->ref - sec->contents, tm); | 2923 | (char *) &dep->ref - sec->contents, tm); |
2924 | dep->next_ref = 0; | 2924 | dep->next_ref = 0; |
2925 | ++dep; | 2925 | ++dep; |
2926 | } | 2926 | } |
@@ -2932,7 +2932,7 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2932 | 2932 | ||
2933 | sec = | 2933 | sec = |
2934 | obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, | 2934 | obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, |
2935 | 0); | 2935 | 0); |
2936 | 2936 | ||
2937 | /* We don't want to export symbols residing in sections that | 2937 | /* We don't want to export symbols residing in sections that |
2938 | aren't loaded. There are a number of these created so that | 2938 | aren't loaded. There are a number of these created so that |
@@ -2946,14 +2946,14 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2946 | struct obj_symbol *sym; | 2946 | struct obj_symbol *sym; |
2947 | for (sym = f->symtab[i]; sym; sym = sym->next) | 2947 | for (sym = f->symtab[i]; sym; sym = sym->next) |
2948 | if (ELFW(ST_BIND) (sym->info) != STB_LOCAL | 2948 | if (ELFW(ST_BIND) (sym->info) != STB_LOCAL |
2949 | && sym->secidx <= SHN_HIRESERVE | 2949 | && sym->secidx <= SHN_HIRESERVE |
2950 | && (sym->secidx >= SHN_LORESERVE | 2950 | && (sym->secidx >= SHN_LORESERVE |
2951 | || loaded[sym->secidx])) { | 2951 | || loaded[sym->secidx])) { |
2952 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; | 2952 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; |
2953 | 2953 | ||
2954 | obj_symbol_patch(f, sec->idx, ofs, sym); | 2954 | obj_symbol_patch(f, sec->idx, ofs, sym); |
2955 | obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, | 2955 | obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, |
2956 | sym->name); | 2956 | sym->name); |
2957 | 2957 | ||
2958 | nsyms++; | 2958 | nsyms++; |
2959 | } | 2959 | } |
@@ -3017,8 +3017,8 @@ new_init_module(const char *m_name, struct obj_file *f, | |||
3017 | sec = obj_find_section(f, ".data.init"); | 3017 | sec = obj_find_section(f, ".data.init"); |
3018 | if (sec) { | 3018 | if (sec) { |
3019 | if (!module->runsize || | 3019 | if (!module->runsize || |
3020 | module->runsize > sec->header.sh_addr - m_addr) | 3020 | module->runsize > sec->header.sh_addr - m_addr) |
3021 | module->runsize = sec->header.sh_addr - m_addr; | 3021 | module->runsize = sec->header.sh_addr - m_addr; |
3022 | } | 3022 | } |
3023 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); | 3023 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); |
3024 | if (sec && sec->header.sh_size) { | 3024 | if (sec && sec->header.sh_size) { |
@@ -3232,8 +3232,8 @@ static void obj_allocate_commons(struct obj_file *f) | |||
3232 | struct obj_section *s = f->sections[i]; | 3232 | struct obj_section *s = f->sections[i]; |
3233 | if (s->header.sh_type == SHT_NOBITS) { | 3233 | if (s->header.sh_type == SHT_NOBITS) { |
3234 | if (s->header.sh_size != 0) | 3234 | if (s->header.sh_size != 0) |
3235 | s->contents = memset(xmalloc(s->header.sh_size), | 3235 | s->contents = memset(xmalloc(s->header.sh_size), |
3236 | 0, s->header.sh_size); | 3236 | 0, s->header.sh_size); |
3237 | else | 3237 | else |
3238 | s->contents = NULL; | 3238 | s->contents = NULL; |
3239 | 3239 | ||
@@ -3330,7 +3330,7 @@ static int obj_relocate(struct obj_file *f, ElfW(Addr) base) | |||
3330 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) | 3330 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) |
3331 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ | 3331 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ |
3332 | if (!extsym || !extsym->st_name || | 3332 | if (!extsym || !extsym->st_name || |
3333 | ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL) | 3333 | ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL) |
3334 | #endif | 3334 | #endif |
3335 | value += rel->r_addend; | 3335 | value += rel->r_addend; |
3336 | #endif | 3336 | #endif |
@@ -3338,28 +3338,28 @@ static int obj_relocate(struct obj_file *f, ElfW(Addr) base) | |||
3338 | /* Do it! */ | 3338 | /* Do it! */ |
3339 | switch (arch_apply_relocation | 3339 | switch (arch_apply_relocation |
3340 | (f, targsec, symsec, intsym, rel, value)) { | 3340 | (f, targsec, symsec, intsym, rel, value)) { |
3341 | case obj_reloc_ok: | 3341 | case obj_reloc_ok: |
3342 | break; | 3342 | break; |
3343 | 3343 | ||
3344 | case obj_reloc_overflow: | 3344 | case obj_reloc_overflow: |
3345 | errmsg = "Relocation overflow"; | 3345 | errmsg = "Relocation overflow"; |
3346 | goto bad_reloc; | 3346 | goto bad_reloc; |
3347 | case obj_reloc_dangerous: | 3347 | case obj_reloc_dangerous: |
3348 | errmsg = "Dangerous relocation"; | 3348 | errmsg = "Dangerous relocation"; |
3349 | goto bad_reloc; | 3349 | goto bad_reloc; |
3350 | case obj_reloc_unhandled: | 3350 | case obj_reloc_unhandled: |
3351 | errmsg = "Unhandled relocation"; | 3351 | errmsg = "Unhandled relocation"; |
3352 | bad_reloc: | 3352 | bad_reloc: |
3353 | if (extsym) { | 3353 | if (extsym) { |
3354 | bb_error_msg("%s of type %ld for %s", errmsg, | 3354 | bb_error_msg("%s of type %ld for %s", errmsg, |
3355 | (long) ELFW(R_TYPE) (rel->r_info), | 3355 | (long) ELFW(R_TYPE) (rel->r_info), |
3356 | strtab + extsym->st_name); | 3356 | strtab + extsym->st_name); |
3357 | } else { | 3357 | } else { |
3358 | bb_error_msg("%s of type %ld", errmsg, | 3358 | bb_error_msg("%s of type %ld", errmsg, |
3359 | (long) ELFW(R_TYPE) (rel->r_info)); | 3359 | (long) ELFW(R_TYPE) (rel->r_info)); |
3360 | } | 3360 | } |
3361 | ret = 0; | 3361 | ret = 0; |
3362 | break; | 3362 | break; |
3363 | } | 3363 | } |
3364 | } | 3364 | } |
3365 | } | 3365 | } |
@@ -3437,16 +3437,16 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
3437 | } | 3437 | } |
3438 | 3438 | ||
3439 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 | 3439 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 |
3440 | || f->header.e_ident[EI_MAG1] != ELFMAG1 | 3440 | || f->header.e_ident[EI_MAG1] != ELFMAG1 |
3441 | || f->header.e_ident[EI_MAG2] != ELFMAG2 | 3441 | || f->header.e_ident[EI_MAG2] != ELFMAG2 |
3442 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { | 3442 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { |
3443 | bb_error_msg("not an ELF file"); | 3443 | bb_error_msg("not an ELF file"); |
3444 | return NULL; | 3444 | return NULL; |
3445 | } | 3445 | } |
3446 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM | 3446 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM |
3447 | || f->header.e_ident[EI_DATA] != ELFDATAM | 3447 | || f->header.e_ident[EI_DATA] != ELFDATAM |
3448 | || f->header.e_ident[EI_VERSION] != EV_CURRENT | 3448 | || f->header.e_ident[EI_VERSION] != EV_CURRENT |
3449 | || !MATCH_MACHINE(f->header.e_machine)) { | 3449 | || !MATCH_MACHINE(f->header.e_machine)) { |
3450 | bb_error_msg("ELF file not for this architecture"); | 3450 | bb_error_msg("ELF file not for this architecture"); |
3451 | return NULL; | 3451 | return NULL; |
3452 | } | 3452 | } |
@@ -3487,56 +3487,56 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
3487 | sec->idx = i; | 3487 | sec->idx = i; |
3488 | 3488 | ||
3489 | if(sec->header.sh_size) switch (sec->header.sh_type) { | 3489 | if(sec->header.sh_size) switch (sec->header.sh_type) { |
3490 | case SHT_NULL: | 3490 | case SHT_NULL: |
3491 | case SHT_NOTE: | 3491 | case SHT_NOTE: |
3492 | case SHT_NOBITS: | 3492 | case SHT_NOBITS: |
3493 | /* ignore */ | 3493 | /* ignore */ |
3494 | break; | 3494 | break; |
3495 | 3495 | ||
3496 | case SHT_PROGBITS: | 3496 | case SHT_PROGBITS: |
3497 | #if LOADBITS | 3497 | #if LOADBITS |
3498 | if (!loadprogbits) { | 3498 | if (!loadprogbits) { |
3499 | sec->contents = NULL; | 3499 | sec->contents = NULL; |
3500 | break; | 3500 | break; |
3501 | } | 3501 | } |
3502 | #endif | 3502 | #endif |
3503 | case SHT_SYMTAB: | 3503 | case SHT_SYMTAB: |
3504 | case SHT_STRTAB: | 3504 | case SHT_STRTAB: |
3505 | case SHT_RELM: | 3505 | case SHT_RELM: |
3506 | if (sec->header.sh_size > 0) { | 3506 | if (sec->header.sh_size > 0) { |
3507 | sec->contents = xmalloc(sec->header.sh_size); | 3507 | sec->contents = xmalloc(sec->header.sh_size); |
3508 | fseek(fp, sec->header.sh_offset, SEEK_SET); | 3508 | fseek(fp, sec->header.sh_offset, SEEK_SET); |
3509 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { | 3509 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { |
3510 | bb_perror_msg("error reading ELF section data"); | 3510 | bb_perror_msg("error reading ELF section data"); |
3511 | return NULL; | 3511 | return NULL; |
3512 | } | ||
3513 | } else { | ||
3514 | sec->contents = NULL; | ||
3512 | } | 3515 | } |
3513 | } else { | 3516 | break; |
3514 | sec->contents = NULL; | ||
3515 | } | ||
3516 | break; | ||
3517 | 3517 | ||
3518 | #if SHT_RELM == SHT_REL | 3518 | #if SHT_RELM == SHT_REL |
3519 | case SHT_RELA: | 3519 | case SHT_RELA: |
3520 | bb_error_msg("RELA relocations not supported on this architecture"); | 3520 | bb_error_msg("RELA relocations not supported on this architecture"); |
3521 | return NULL; | 3521 | return NULL; |
3522 | #else | 3522 | #else |
3523 | case SHT_REL: | 3523 | case SHT_REL: |
3524 | bb_error_msg("REL relocations not supported on this architecture"); | 3524 | bb_error_msg("REL relocations not supported on this architecture"); |
3525 | return NULL; | 3525 | return NULL; |
3526 | #endif | 3526 | #endif |
3527 | 3527 | ||
3528 | default: | 3528 | default: |
3529 | if (sec->header.sh_type >= SHT_LOPROC) { | 3529 | if (sec->header.sh_type >= SHT_LOPROC) { |
3530 | /* Assume processor specific section types are debug | 3530 | /* Assume processor specific section types are debug |
3531 | info and can safely be ignored. If this is ever not | 3531 | info and can safely be ignored. If this is ever not |
3532 | the case (Hello MIPS?), don't put ifdefs here but | 3532 | the case (Hello MIPS?), don't put ifdefs here but |
3533 | create an arch_load_proc_section(). */ | 3533 | create an arch_load_proc_section(). */ |
3534 | break; | 3534 | break; |
3535 | } | 3535 | } |
3536 | 3536 | ||
3537 | bb_error_msg("can't handle sections of type %ld", | 3537 | bb_error_msg("can't handle sections of type %ld", |
3538 | (long) sec->header.sh_type); | 3538 | (long) sec->header.sh_type); |
3539 | return NULL; | 3539 | return NULL; |
3540 | } | 3540 | } |
3541 | } | 3541 | } |
3542 | 3542 | ||
@@ -3562,65 +3562,65 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
3562 | obj_insert_section_load_order(f, sec); | 3562 | obj_insert_section_load_order(f, sec); |
3563 | 3563 | ||
3564 | switch (sec->header.sh_type) { | 3564 | switch (sec->header.sh_type) { |
3565 | case SHT_SYMTAB: | 3565 | case SHT_SYMTAB: |
3566 | { | 3566 | { |
3567 | unsigned long nsym, j; | 3567 | unsigned long nsym, j; |
3568 | char *strtab; | 3568 | char *strtab; |
3569 | ElfW(Sym) * sym; | 3569 | ElfW(Sym) * sym; |
3570 | 3570 | ||
3571 | if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { | 3571 | if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { |
3572 | bb_error_msg("symbol size mismatch: %lu != %lu", | 3572 | bb_error_msg("symbol size mismatch: %lu != %lu", |
3573 | (unsigned long) sec->header.sh_entsize, | 3573 | (unsigned long) sec->header.sh_entsize, |
3574 | (unsigned long) sizeof(ElfW(Sym))); | 3574 | (unsigned long) sizeof(ElfW(Sym))); |
3575 | return NULL; | 3575 | return NULL; |
3576 | } | 3576 | } |
3577 | 3577 | ||
3578 | nsym = sec->header.sh_size / sizeof(ElfW(Sym)); | 3578 | nsym = sec->header.sh_size / sizeof(ElfW(Sym)); |
3579 | strtab = f->sections[sec->header.sh_link]->contents; | 3579 | strtab = f->sections[sec->header.sh_link]->contents; |
3580 | sym = (ElfW(Sym) *) sec->contents; | 3580 | sym = (ElfW(Sym) *) sec->contents; |
3581 | 3581 | ||
3582 | /* Allocate space for a table of local symbols. */ | 3582 | /* Allocate space for a table of local symbols. */ |
3583 | j = f->local_symtab_size = sec->header.sh_info; | 3583 | j = f->local_symtab_size = sec->header.sh_info; |
3584 | f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *)); | 3584 | f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *)); |
3585 | 3585 | ||
3586 | /* Insert all symbols into the hash table. */ | 3586 | /* Insert all symbols into the hash table. */ |
3587 | for (j = 1, ++sym; j < nsym; ++j, ++sym) { | 3587 | for (j = 1, ++sym; j < nsym; ++j, ++sym) { |
3588 | ElfW(Addr) val = sym->st_value; | 3588 | ElfW(Addr) val = sym->st_value; |
3589 | const char *name; | 3589 | const char *name; |
3590 | if (sym->st_name) | 3590 | if (sym->st_name) |
3591 | name = strtab + sym->st_name; | 3591 | name = strtab + sym->st_name; |
3592 | else | 3592 | else |
3593 | name = f->sections[sym->st_shndx]->name; | 3593 | name = f->sections[sym->st_shndx]->name; |
3594 | 3594 | ||
3595 | #if defined(__SH5__) | 3595 | #if defined(__SH5__) |
3596 | /* | 3596 | /* |
3597 | * For sh64 it is possible that the target of a branch | 3597 | * For sh64 it is possible that the target of a branch |
3598 | * requires a mode switch (32 to 16 and back again). | 3598 | * requires a mode switch (32 to 16 and back again). |
3599 | * | 3599 | * |
3600 | * This is implied by the lsb being set in the target | 3600 | * This is implied by the lsb being set in the target |
3601 | * address for SHmedia mode and clear for SHcompact. | 3601 | * address for SHmedia mode and clear for SHcompact. |
3602 | */ | 3602 | */ |
3603 | val |= sym->st_other & 4; | 3603 | val |= sym->st_other & 4; |
3604 | #endif | 3604 | #endif |
3605 | 3605 | ||
3606 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, | 3606 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, |
3607 | val, sym->st_size); | 3607 | val, sym->st_size); |
3608 | } | ||
3608 | } | 3609 | } |
3609 | } | 3610 | break; |
3610 | break; | ||
3611 | 3611 | ||
3612 | case SHT_RELM: | 3612 | case SHT_RELM: |
3613 | if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { | 3613 | if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { |
3614 | bb_error_msg("relocation entry size mismatch: %lu != %lu", | 3614 | bb_error_msg("relocation entry size mismatch: %lu != %lu", |
3615 | (unsigned long) sec->header.sh_entsize, | 3615 | (unsigned long) sec->header.sh_entsize, |
3616 | (unsigned long) sizeof(ElfW(RelM))); | 3616 | (unsigned long) sizeof(ElfW(RelM))); |
3617 | return NULL; | 3617 | return NULL; |
3618 | } | 3618 | } |
3619 | break; | 3619 | break; |
3620 | /* XXX Relocation code from modutils-2.3.19 is not here. | 3620 | /* XXX Relocation code from modutils-2.3.19 is not here. |
3621 | * Why? That's about 20 lines of code from obj/obj_load.c, | 3621 | * Why? That's about 20 lines of code from obj/obj_load.c, |
3622 | * which gets done in a second pass through the sections. | 3622 | * which gets done in a second pass through the sections. |
3623 | * This BusyBox insmod does similar work in obj_relocate(). */ | 3623 | * This BusyBox insmod does similar work in obj_relocate(). */ |
3624 | } | 3624 | } |
3625 | } | 3625 | } |
3626 | 3626 | ||
@@ -3637,13 +3637,13 @@ static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase) | |||
3637 | { | 3637 | { |
3638 | ElfW(Addr) base = f->baseaddr; | 3638 | ElfW(Addr) base = f->baseaddr; |
3639 | struct obj_section* sec; | 3639 | struct obj_section* sec; |
3640 | 3640 | ||
3641 | for (sec = f->load_order; sec; sec = sec->load_next) { | 3641 | for (sec = f->load_order; sec; sec = sec->load_next) { |
3642 | 3642 | ||
3643 | /* section already loaded? */ | 3643 | /* section already loaded? */ |
3644 | if (sec->contents != NULL) | 3644 | if (sec->contents != NULL) |
3645 | continue; | 3645 | continue; |
3646 | 3646 | ||
3647 | if (sec->header.sh_size == 0) | 3647 | if (sec->header.sh_size == 0) |
3648 | continue; | 3648 | continue; |
3649 | 3649 | ||
@@ -3803,13 +3803,13 @@ static int | |||
3803 | get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | 3803 | get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) |
3804 | { | 3804 | { |
3805 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING | 3805 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING |
3806 | if (get_modinfo_value(f, "kernel_version") == NULL) | 3806 | if (get_modinfo_value(f, "kernel_version") == NULL) |
3807 | return old_get_module_version(f, str); | 3807 | return old_get_module_version(f, str); |
3808 | else | 3808 | else |
3809 | return new_get_module_version(f, str); | 3809 | return new_get_module_version(f, str); |
3810 | #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | 3810 | #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ |
3811 | strncpy(str, "???", sizeof(str)); | 3811 | strncpy(str, "???", sizeof(str)); |
3812 | return -1; | 3812 | return -1; |
3813 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | 3813 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ |
3814 | } | 3814 | } |
3815 | 3815 | ||
@@ -3834,7 +3834,7 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
3834 | ".rodata", | 3834 | ".rodata", |
3835 | ".data", | 3835 | ".data", |
3836 | ".bss" | 3836 | ".bss" |
3837 | ".sbss" | 3837 | ".sbss" |
3838 | }; | 3838 | }; |
3839 | 3839 | ||
3840 | if (realpath(filename, real)) { | 3840 | if (realpath(filename, real)) { |
@@ -3864,27 +3864,27 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
3864 | * one symbol is less readable but saves kernel space. | 3864 | * one symbol is less readable but saves kernel space. |
3865 | */ | 3865 | */ |
3866 | l = sizeof(symprefix)+ /* "__insmod_" */ | 3866 | l = sizeof(symprefix)+ /* "__insmod_" */ |
3867 | lm_name+ /* module name */ | 3867 | lm_name+ /* module name */ |
3868 | 2+ /* "_O" */ | 3868 | 2+ /* "_O" */ |
3869 | lfilename+ /* object filename */ | 3869 | lfilename+ /* object filename */ |
3870 | 2+ /* "_M" */ | 3870 | 2+ /* "_M" */ |
3871 | 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ | 3871 | 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ |
3872 | 2+ /* "_V" */ | 3872 | 2+ /* "_V" */ |
3873 | 8+ /* version in dec */ | 3873 | 8+ /* version in dec */ |
3874 | 1; /* nul */ | 3874 | 1; /* nul */ |
3875 | name = xmalloc(l); | 3875 | name = xmalloc(l); |
3876 | if (stat(absolute_filename, &statbuf) != 0) | 3876 | if (stat(absolute_filename, &statbuf) != 0) |
3877 | statbuf.st_mtime = 0; | 3877 | statbuf.st_mtime = 0; |
3878 | version = get_module_version(f, str); /* -1 if not found */ | 3878 | version = get_module_version(f, str); /* -1 if not found */ |
3879 | snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", | 3879 | snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", |
3880 | symprefix, m_name, absolute_filename, | 3880 | symprefix, m_name, absolute_filename, |
3881 | (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, | 3881 | (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, |
3882 | version); | 3882 | version); |
3883 | sym = obj_add_symbol(f, name, -1, | 3883 | sym = obj_add_symbol(f, name, -1, |
3884 | ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | 3884 | ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), |
3885 | sec->idx, sec->header.sh_addr, 0); | 3885 | sec->idx, sec->header.sh_addr, 0); |
3886 | if (use_ksymtab) | 3886 | if (use_ksymtab) |
3887 | new_add_ksymtab(f, sym); | 3887 | new_add_ksymtab(f, sym); |
3888 | } | 3888 | } |
3889 | free(absolute_filename); | 3889 | free(absolute_filename); |
3890 | #ifdef _NOT_SUPPORTED_ | 3890 | #ifdef _NOT_SUPPORTED_ |
@@ -3898,18 +3898,18 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
3898 | 1; /* nul */ | 3898 | 1; /* nul */ |
3899 | name = xmalloc(l); | 3899 | name = xmalloc(l); |
3900 | snprintf(name, l, "%s%s_P%s", | 3900 | snprintf(name, l, "%s%s_P%s", |
3901 | symprefix, m_name, f->persist); | 3901 | symprefix, m_name, f->persist); |
3902 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | 3902 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), |
3903 | sec->idx, sec->header.sh_addr, 0); | 3903 | sec->idx, sec->header.sh_addr, 0); |
3904 | if (use_ksymtab) | 3904 | if (use_ksymtab) |
3905 | new_add_ksymtab(f, sym); | 3905 | new_add_ksymtab(f, sym); |
3906 | } | 3906 | } |
3907 | #endif /* _NOT_SUPPORTED_ */ | 3907 | #endif /* _NOT_SUPPORTED_ */ |
3908 | /* tag the desired sections if size is non-zero */ | 3908 | /* tag the desired sections if size is non-zero */ |
3909 | 3909 | ||
3910 | for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) { | 3910 | for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) { |
3911 | if ((sec = obj_find_section(f, section_names[i])) && | 3911 | if ((sec = obj_find_section(f, section_names[i])) && |
3912 | sec->header.sh_size) { | 3912 | sec->header.sh_size) { |
3913 | l = sizeof(symprefix)+ /* "__insmod_" */ | 3913 | l = sizeof(symprefix)+ /* "__insmod_" */ |
3914 | lm_name+ /* module name */ | 3914 | lm_name+ /* module name */ |
3915 | 2+ /* "_S" */ | 3915 | 2+ /* "_S" */ |
@@ -3919,12 +3919,12 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
3919 | 1; /* nul */ | 3919 | 1; /* nul */ |
3920 | name = xmalloc(l); | 3920 | name = xmalloc(l); |
3921 | snprintf(name, l, "%s%s_S%s_L%ld", | 3921 | snprintf(name, l, "%s%s_S%s_L%ld", |
3922 | symprefix, m_name, sec->name, | 3922 | symprefix, m_name, sec->name, |
3923 | (long)sec->header.sh_size); | 3923 | (long)sec->header.sh_size); |
3924 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), | 3924 | sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), |
3925 | sec->idx, sec->header.sh_addr, 0); | 3925 | sec->idx, sec->header.sh_addr, 0); |
3926 | if (use_ksymtab) | 3926 | if (use_ksymtab) |
3927 | new_add_ksymtab(f, sym); | 3927 | new_add_ksymtab(f, sym); |
3928 | } | 3928 | } |
3929 | } | 3929 | } |
3930 | } | 3930 | } |
@@ -4055,51 +4055,52 @@ extern int insmod_main( int argc, char **argv) | |||
4055 | 4055 | ||
4056 | /* Parse any options */ | 4056 | /* Parse any options */ |
4057 | #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP | 4057 | #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP |
4058 | while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0) { | 4058 | while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0) |
4059 | #else | 4059 | #else |
4060 | while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) { | 4060 | while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) |
4061 | #endif | 4061 | #endif |
4062 | switch (opt) { | 4062 | { |
4063 | case 'f': /* force loading */ | 4063 | switch (opt) { |
4064 | flag_force_load = 1; | 4064 | case 'f': /* force loading */ |
4065 | break; | 4065 | flag_force_load = 1; |
4066 | case 'k': /* module loaded by kerneld, auto-cleanable */ | 4066 | break; |
4067 | flag_autoclean = 1; | 4067 | case 'k': /* module loaded by kerneld, auto-cleanable */ |
4068 | break; | 4068 | flag_autoclean = 1; |
4069 | case 's': /* log to syslog */ | 4069 | break; |
4070 | /* log to syslog -- not supported */ | 4070 | case 's': /* log to syslog */ |
4071 | /* but kernel needs this for request_module(), */ | 4071 | /* log to syslog -- not supported */ |
4072 | /* as this calls: modprobe -k -s -- <module> */ | 4072 | /* but kernel needs this for request_module(), */ |
4073 | /* so silently ignore this flag */ | 4073 | /* as this calls: modprobe -k -s -- <module> */ |
4074 | break; | 4074 | /* so silently ignore this flag */ |
4075 | case 'v': /* verbose output */ | 4075 | break; |
4076 | flag_verbose = 1; | 4076 | case 'v': /* verbose output */ |
4077 | break; | 4077 | flag_verbose = 1; |
4078 | case 'q': /* silent */ | 4078 | break; |
4079 | flag_quiet = 1; | 4079 | case 'q': /* silent */ |
4080 | break; | 4080 | flag_quiet = 1; |
4081 | case 'x': /* do not export externs */ | 4081 | break; |
4082 | flag_export = 0; | 4082 | case 'x': /* do not export externs */ |
4083 | break; | 4083 | flag_export = 0; |
4084 | case 'o': /* name the output module */ | 4084 | break; |
4085 | free(m_name); | 4085 | case 'o': /* name the output module */ |
4086 | m_name = bb_xstrdup(optarg); | 4086 | free(m_name); |
4087 | break; | 4087 | m_name = bb_xstrdup(optarg); |
4088 | case 'L': /* Stub warning */ | 4088 | break; |
4089 | /* This is needed for compatibility with modprobe. | 4089 | case 'L': /* Stub warning */ |
4090 | * In theory, this does locking, but we don't do | 4090 | /* This is needed for compatibility with modprobe. |
4091 | * that. So be careful and plan your life around not | 4091 | * In theory, this does locking, but we don't do |
4092 | * loading the same module 50 times concurrently. */ | 4092 | * that. So be careful and plan your life around not |
4093 | break; | 4093 | * loading the same module 50 times concurrently. */ |
4094 | break; | ||
4094 | #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP | 4095 | #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP |
4095 | case 'm': /* print module load map */ | 4096 | case 'm': /* print module load map */ |
4096 | flag_print_load_map = 1; | 4097 | flag_print_load_map = 1; |
4097 | break; | 4098 | break; |
4098 | #endif | 4099 | #endif |
4099 | default: | 4100 | default: |
4100 | bb_show_usage(); | 4101 | bb_show_usage(); |
4102 | } | ||
4101 | } | 4103 | } |
4102 | } | ||
4103 | 4104 | ||
4104 | if (argv[optind] == NULL) { | 4105 | if (argv[optind] == NULL) { |
4105 | bb_show_usage(); | 4106 | bb_show_usage(); |
@@ -4118,16 +4119,16 @@ extern int insmod_main( int argc, char **argv) | |||
4118 | 4119 | ||
4119 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 4120 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
4120 | if (k_version > 4 && len > 3 && tmp[len - 3] == '.' && | 4121 | if (k_version > 4 && len > 3 && tmp[len - 3] == '.' && |
4121 | tmp[len - 2] == 'k' && tmp[len - 1] == 'o') { | 4122 | tmp[len - 2] == 'k' && tmp[len - 1] == 'o') { |
4122 | len-=3; | 4123 | len-=3; |
4123 | tmp[len] = '\0'; | 4124 | tmp[len] = '\0'; |
4124 | } | 4125 | } |
4125 | else | 4126 | else |
4126 | #endif | 4127 | #endif |
4127 | if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') { | 4128 | if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') { |
4128 | len-=2; | 4129 | len-=2; |
4129 | tmp[len] = '\0'; | 4130 | tmp[len] = '\0'; |
4130 | } | 4131 | } |
4131 | 4132 | ||
4132 | 4133 | ||
4133 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 4134 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
@@ -4135,7 +4136,7 @@ extern int insmod_main( int argc, char **argv) | |||
4135 | bb_xasprintf(&m_fullName, "%s.ko", tmp); | 4136 | bb_xasprintf(&m_fullName, "%s.ko", tmp); |
4136 | else | 4137 | else |
4137 | #else | 4138 | #else |
4138 | bb_xasprintf(&m_fullName, "%s.o", tmp); | 4139 | bb_xasprintf(&m_fullName, "%s.o", tmp); |
4139 | #endif | 4140 | #endif |
4140 | 4141 | ||
4141 | if (!m_name) { | 4142 | if (!m_name) { |
@@ -4166,7 +4167,7 @@ extern int insmod_main( int argc, char **argv) | |||
4166 | else | 4167 | else |
4167 | module_dir = real_module_dir; | 4168 | module_dir = real_module_dir; |
4168 | recursive_action(module_dir, TRUE, FALSE, FALSE, | 4169 | recursive_action(module_dir, TRUE, FALSE, FALSE, |
4169 | check_module_name_match, 0, m_fullName); | 4170 | check_module_name_match, 0, m_fullName); |
4170 | free(tmdn); | 4171 | free(tmdn); |
4171 | } | 4172 | } |
4172 | 4173 | ||
@@ -4287,8 +4288,8 @@ extern int insmod_main( int argc, char **argv) | |||
4287 | /* Allocate common symbols, symbol tables, and string tables. */ | 4288 | /* Allocate common symbols, symbol tables, and string tables. */ |
4288 | 4289 | ||
4289 | if (k_new_syscalls | 4290 | if (k_new_syscalls |
4290 | ? !new_create_this_module(f, m_name) | 4291 | ? !new_create_this_module(f, m_name) |
4291 | : !old_create_mod_use_count(f)) | 4292 | : !old_create_mod_use_count(f)) |
4292 | { | 4293 | { |
4293 | goto out; | 4294 | goto out; |
4294 | } | 4295 | } |
@@ -4304,8 +4305,8 @@ extern int insmod_main( int argc, char **argv) | |||
4304 | 4305 | ||
4305 | if (optind < argc) { | 4306 | if (optind < argc) { |
4306 | if (m_has_modinfo | 4307 | if (m_has_modinfo |
4307 | ? !new_process_module_arguments(f, argc - optind, argv + optind) | 4308 | ? !new_process_module_arguments(f, argc - optind, argv + optind) |
4308 | : !old_process_module_arguments(f, argc - optind, argv + optind)) | 4309 | : !old_process_module_arguments(f, argc - optind, argv + optind)) |
4309 | { | 4310 | { |
4310 | goto out; | 4311 | goto out; |
4311 | } | 4312 | } |
@@ -4327,16 +4328,16 @@ extern int insmod_main( int argc, char **argv) | |||
4327 | 4328 | ||
4328 | m_addr = create_module(m_name, m_size); | 4329 | m_addr = create_module(m_name, m_size); |
4329 | if (m_addr == -1) switch (errno) { | 4330 | if (m_addr == -1) switch (errno) { |
4330 | case EEXIST: | 4331 | case EEXIST: |
4331 | bb_error_msg("A module named %s already exists", m_name); | 4332 | bb_error_msg("A module named %s already exists", m_name); |
4332 | goto out; | 4333 | goto out; |
4333 | case ENOMEM: | 4334 | case ENOMEM: |
4334 | bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes", | 4335 | bb_error_msg("Can't allocate kernel memory for module; needed %lu bytes", |
4335 | m_size); | 4336 | m_size); |
4336 | goto out; | 4337 | goto out; |
4337 | default: | 4338 | default: |
4338 | bb_perror_msg("create_module: %s", m_name); | 4339 | bb_perror_msg("create_module: %s", m_name); |
4339 | goto out; | 4340 | goto out; |
4340 | } | 4341 | } |
4341 | 4342 | ||
4342 | #if !LOADBITS | 4343 | #if !LOADBITS |
@@ -4356,8 +4357,8 @@ extern int insmod_main( int argc, char **argv) | |||
4356 | } | 4357 | } |
4357 | 4358 | ||
4358 | if (k_new_syscalls | 4359 | if (k_new_syscalls |
4359 | ? !new_init_module(m_name, f, m_size) | 4360 | ? !new_init_module(m_name, f, m_size) |
4360 | : !old_init_module(m_name, f, m_size)) | 4361 | : !old_init_module(m_name, f, m_size)) |
4361 | { | 4362 | { |
4362 | delete_module(m_name); | 4363 | delete_module(m_name); |
4363 | goto out; | 4364 | goto out; |
@@ -4373,7 +4374,7 @@ extern int insmod_main( int argc, char **argv) | |||
4373 | out: | 4374 | out: |
4374 | #ifdef CONFIG_FEATURE_CLEAN_UP | 4375 | #ifdef CONFIG_FEATURE_CLEAN_UP |
4375 | if(fp) | 4376 | if(fp) |
4376 | fclose(fp); | 4377 | fclose(fp); |
4377 | if(tmp1) { | 4378 | if(tmp1) { |
4378 | free(tmp1); | 4379 | free(tmp1); |
4379 | } else { | 4380 | } else { |
@@ -4398,16 +4399,16 @@ out: | |||
4398 | static const char *moderror(int err) | 4399 | static const char *moderror(int err) |
4399 | { | 4400 | { |
4400 | switch (err) { | 4401 | switch (err) { |
4401 | case ENOEXEC: | 4402 | case ENOEXEC: |
4402 | return "Invalid module format"; | 4403 | return "Invalid module format"; |
4403 | case ENOENT: | 4404 | case ENOENT: |
4404 | return "Unknown symbol in module"; | 4405 | return "Unknown symbol in module"; |
4405 | case ESRCH: | 4406 | case ESRCH: |
4406 | return "Module has wrong symbol version"; | 4407 | return "Module has wrong symbol version"; |
4407 | case EINVAL: | 4408 | case EINVAL: |
4408 | return "Invalid parameters"; | 4409 | return "Invalid parameters"; |
4409 | default: | 4410 | default: |
4410 | return strerror(err); | 4411 | return strerror(err); |
4411 | } | 4412 | } |
4412 | } | 4413 | } |
4413 | 4414 | ||
@@ -4420,7 +4421,7 @@ extern int insmod_ng_main( int argc, char **argv) | |||
4420 | unsigned long len; | 4421 | unsigned long len; |
4421 | void *map; | 4422 | void *map; |
4422 | char *filename, *options = bb_xstrdup(""); | 4423 | char *filename, *options = bb_xstrdup(""); |
4423 | 4424 | ||
4424 | filename = argv[1]; | 4425 | filename = argv[1]; |
4425 | if (!filename) { | 4426 | if (!filename) { |
4426 | bb_show_usage(); | 4427 | bb_show_usage(); |
@@ -4455,9 +4456,9 @@ extern int insmod_ng_main( int argc, char **argv) | |||
4455 | ret = syscall(__NR_init_module, map, len, options); | 4456 | ret = syscall(__NR_init_module, map, len, options); |
4456 | if (ret != 0) { | 4457 | if (ret != 0) { |
4457 | bb_perror_msg_and_die("cannot insert `%s': %s (%li)", | 4458 | bb_perror_msg_and_die("cannot insert `%s': %s (%li)", |
4458 | filename, moderror(errno), ret); | 4459 | filename, moderror(errno), ret); |
4459 | } | 4460 | } |
4460 | 4461 | ||
4461 | return 0; | 4462 | return 0; |
4462 | } | 4463 | } |
4463 | 4464 | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 6b4405a44..e300c0d2b 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -36,20 +36,20 @@ | |||
36 | struct dep_t { | 36 | struct dep_t { |
37 | char * m_module; | 37 | char * m_module; |
38 | char * m_options; | 38 | char * m_options; |
39 | 39 | ||
40 | int m_isalias : 1; | 40 | int m_isalias : 1; |
41 | int m_reserved : 15; | 41 | int m_reserved : 15; |
42 | 42 | ||
43 | int m_depcnt : 16; | 43 | int m_depcnt : 16; |
44 | char ** m_deparr; | 44 | char ** m_deparr; |
45 | 45 | ||
46 | struct dep_t * m_next; | 46 | struct dep_t * m_next; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct mod_list_t { | 49 | struct mod_list_t { |
50 | char * m_module; | 50 | char * m_module; |
51 | char * m_options; | 51 | char * m_options; |
52 | 52 | ||
53 | struct mod_list_t * m_prev; | 53 | struct mod_list_t * m_prev; |
54 | struct mod_list_t * m_next; | 54 | struct mod_list_t * m_next; |
55 | }; | 55 | }; |
@@ -74,7 +74,7 @@ int parse_tag_value ( char *buffer, char **ptag, char **pvalue ) | |||
74 | 74 | ||
75 | *ptag = tag; | 75 | *ptag = tag; |
76 | *pvalue = value; | 76 | *pvalue = value; |
77 | 77 | ||
78 | return bb_strlen( tag ) && bb_strlen( value ); | 78 | return bb_strlen( tag ) && bb_strlen( value ); |
79 | } | 79 | } |
80 | 80 | ||
@@ -85,16 +85,16 @@ int parse_tag_value ( char *buffer, char **ptag, char **pvalue ) | |||
85 | static char *reads ( int fd, char *buffer, size_t len ) | 85 | static char *reads ( int fd, char *buffer, size_t len ) |
86 | { | 86 | { |
87 | int n = read ( fd, buffer, len ); | 87 | int n = read ( fd, buffer, len ); |
88 | 88 | ||
89 | if ( n > 0 ) { | 89 | if ( n > 0 ) { |
90 | char *p; | 90 | char *p; |
91 | 91 | ||
92 | buffer [len-1] = 0; | 92 | buffer [len-1] = 0; |
93 | p = strchr ( buffer, '\n' ); | 93 | p = strchr ( buffer, '\n' ); |
94 | 94 | ||
95 | if ( p ) { | 95 | if ( p ) { |
96 | off_t offset; | 96 | off_t offset; |
97 | 97 | ||
98 | offset = lseek ( fd, 0L, SEEK_CUR ); // Get the current file descriptor offset | 98 | offset = lseek ( fd, 0L, SEEK_CUR ); // Get the current file descriptor offset |
99 | lseek ( fd, offset-n + (p-buffer) + 1, SEEK_SET ); // Set the file descriptor offset to right after the \n | 99 | lseek ( fd, offset-n + (p-buffer) + 1, SEEK_SET ); // Set the file descriptor offset to right after the \n |
100 | 100 | ||
@@ -102,7 +102,7 @@ static char *reads ( int fd, char *buffer, size_t len ) | |||
102 | } | 102 | } |
103 | return buffer; | 103 | return buffer; |
104 | } | 104 | } |
105 | 105 | ||
106 | else | 106 | else |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
@@ -116,11 +116,11 @@ static struct dep_t *build_dep ( void ) | |||
116 | char buffer[256]; | 116 | char buffer[256]; |
117 | char *filename = buffer; | 117 | char *filename = buffer; |
118 | int continuation_line = 0; | 118 | int continuation_line = 0; |
119 | 119 | ||
120 | k_version = 0; | 120 | k_version = 0; |
121 | if ( uname ( &un )) | 121 | if ( uname ( &un )) |
122 | return 0; | 122 | return 0; |
123 | 123 | ||
124 | // check for buffer overflow in following code | 124 | // check for buffer overflow in following code |
125 | if ( bb_strlen ( un.release ) > ( sizeof( buffer ) - 64 )) { | 125 | if ( bb_strlen ( un.release ) > ( sizeof( buffer ) - 64 )) { |
126 | return 0; | 126 | return 0; |
@@ -128,7 +128,7 @@ static struct dep_t *build_dep ( void ) | |||
128 | if (un.release[0] == '2') { | 128 | if (un.release[0] == '2') { |
129 | k_version = un.release[2] - '0'; | 129 | k_version = un.release[2] - '0'; |
130 | } | 130 | } |
131 | 131 | ||
132 | strcpy ( filename, "/lib/modules/" ); | 132 | strcpy ( filename, "/lib/modules/" ); |
133 | strcat ( filename, un.release ); | 133 | strcat ( filename, un.release ); |
134 | strcat ( filename, "/modules.dep" ); | 134 | strcat ( filename, "/modules.dep" ); |
@@ -144,44 +144,44 @@ static struct dep_t *build_dep ( void ) | |||
144 | while ( reads ( fd, buffer, sizeof( buffer ))) { | 144 | while ( reads ( fd, buffer, sizeof( buffer ))) { |
145 | int l = bb_strlen ( buffer ); | 145 | int l = bb_strlen ( buffer ); |
146 | char *p = 0; | 146 | char *p = 0; |
147 | 147 | ||
148 | while ( isspace ( buffer [l-1] )) { | 148 | while ( isspace ( buffer [l-1] )) { |
149 | buffer [l-1] = 0; | 149 | buffer [l-1] = 0; |
150 | l--; | 150 | l--; |
151 | } | 151 | } |
152 | 152 | ||
153 | if ( l == 0 ) { | 153 | if ( l == 0 ) { |
154 | continuation_line = 0; | 154 | continuation_line = 0; |
155 | continue; | 155 | continue; |
156 | } | 156 | } |
157 | 157 | ||
158 | if ( !continuation_line ) { | 158 | if ( !continuation_line ) { |
159 | char *col = strchr ( buffer, ':' ); | 159 | char *col = strchr ( buffer, ':' ); |
160 | 160 | ||
161 | if ( col ) { | 161 | if ( col ) { |
162 | char *mods; | 162 | char *mods; |
163 | char *mod; | 163 | char *mod; |
164 | int ext = 0; | 164 | int ext = 0; |
165 | 165 | ||
166 | *col = 0; | 166 | *col = 0; |
167 | mods = strrchr ( buffer, '/' ); | 167 | mods = strrchr ( buffer, '/' ); |
168 | 168 | ||
169 | if ( !mods ) | 169 | if ( !mods ) |
170 | mods = buffer; | 170 | mods = buffer; |
171 | else | 171 | else |
172 | mods++; | 172 | mods++; |
173 | 173 | ||
174 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 174 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
175 | if ((k_version > 4) && ( *(col-3) == '.' ) && | 175 | if ((k_version > 4) && ( *(col-3) == '.' ) && |
176 | ( *(col-2) == 'k' ) && ( *(col-1) == 'o' )) | 176 | ( *(col-2) == 'k' ) && ( *(col-1) == 'o' )) |
177 | ext = 3; | 177 | ext = 3; |
178 | else | 178 | else |
179 | #endif | 179 | #endif |
180 | if (( *(col-2) == '.' ) && ( *(col-1) == 'o' )) | 180 | if (( *(col-2) == '.' ) && ( *(col-1) == 'o' )) |
181 | ext = 2; | 181 | ext = 2; |
182 | 182 | ||
183 | mod = bb_xstrndup ( mods, col - mods - ext ); | 183 | mod = bb_xstrndup ( mods, col - mods - ext ); |
184 | 184 | ||
185 | if ( !current ) { | 185 | if ( !current ) { |
186 | first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t )); | 186 | first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t )); |
187 | } | 187 | } |
@@ -195,9 +195,9 @@ static struct dep_t *build_dep ( void ) | |||
195 | current-> m_depcnt = 0; | 195 | current-> m_depcnt = 0; |
196 | current-> m_deparr = 0; | 196 | current-> m_deparr = 0; |
197 | current-> m_next = 0; | 197 | current-> m_next = 0; |
198 | 198 | ||
199 | //printf ( "%s:\n", mod ); | 199 | //printf ( "%s:\n", mod ); |
200 | 200 | ||
201 | p = col + 1; | 201 | p = col + 1; |
202 | } | 202 | } |
203 | else | 203 | else |
@@ -205,49 +205,49 @@ static struct dep_t *build_dep ( void ) | |||
205 | } | 205 | } |
206 | else | 206 | else |
207 | p = buffer; | 207 | p = buffer; |
208 | 208 | ||
209 | if ( p && *p ) { | 209 | if ( p && *p ) { |
210 | char *end = &buffer [l-1]; | 210 | char *end = &buffer [l-1]; |
211 | char *deps = strrchr ( end, '/' ); | 211 | char *deps = strrchr ( end, '/' ); |
212 | char *dep; | 212 | char *dep; |
213 | int ext = 0; | 213 | int ext = 0; |
214 | 214 | ||
215 | while ( isblank ( *end ) || ( *end == '\\' )) | 215 | while ( isblank ( *end ) || ( *end == '\\' )) |
216 | end--; | 216 | end--; |
217 | 217 | ||
218 | deps = strrchr ( p, '/' ); | 218 | deps = strrchr ( p, '/' ); |
219 | 219 | ||
220 | if ( !deps || ( deps < p )) { | 220 | if ( !deps || ( deps < p )) { |
221 | deps = p; | 221 | deps = p; |
222 | 222 | ||
223 | while ( isblank ( *deps )) | 223 | while ( isblank ( *deps )) |
224 | deps++; | 224 | deps++; |
225 | } | 225 | } |
226 | else | 226 | else |
227 | deps++; | 227 | deps++; |
228 | 228 | ||
229 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 229 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
230 | if ((k_version > 4) && ( *(end-2) == '.' ) && *(end-1) == 'k' && | 230 | if ((k_version > 4) && ( *(end-2) == '.' ) && *(end-1) == 'k' && |
231 | ( *end == 'o' )) | 231 | ( *end == 'o' )) |
232 | ext = 3; | 232 | ext = 3; |
233 | else | 233 | else |
234 | #endif | 234 | #endif |
235 | if (( *(end-1) == '.' ) && ( *end == 'o' )) | 235 | if (( *(end-1) == '.' ) && ( *end == 'o' )) |
236 | ext = 2; | 236 | ext = 2; |
237 | 237 | ||
238 | /* Cope with blank lines */ | 238 | /* Cope with blank lines */ |
239 | if ((end-deps-ext+1) <= 0) | 239 | if ((end-deps-ext+1) <= 0) |
240 | continue; | 240 | continue; |
241 | 241 | ||
242 | dep = bb_xstrndup ( deps, end - deps - ext + 1 ); | 242 | dep = bb_xstrndup ( deps, end - deps - ext + 1 ); |
243 | 243 | ||
244 | current-> m_depcnt++; | 244 | current-> m_depcnt++; |
245 | current-> m_deparr = (char **) xrealloc ( current-> m_deparr, sizeof ( char *) * current-> m_depcnt ); | 245 | current-> m_deparr = (char **) xrealloc ( current-> m_deparr, sizeof ( char *) * current-> m_depcnt ); |
246 | current-> m_deparr [current-> m_depcnt - 1] = dep; | 246 | current-> m_deparr [current-> m_depcnt - 1] = dep; |
247 | 247 | ||
248 | //printf ( " %d) %s\n", current-> m_depcnt, current-> m_deparr [current-> m_depcnt -1] ); | 248 | //printf ( " %d) %s\n", current-> m_depcnt, current-> m_deparr [current-> m_depcnt -1] ); |
249 | } | 249 | } |
250 | 250 | ||
251 | if ( buffer [l-1] == '\\' ) | 251 | if ( buffer [l-1] == '\\' ) |
252 | continuation_line = 1; | 252 | continuation_line = 1; |
253 | else | 253 | else |
@@ -260,35 +260,35 @@ static struct dep_t *build_dep ( void ) | |||
260 | if (( fd = open ( "/etc/modules.conf", O_RDONLY )) < 0 ) | 260 | if (( fd = open ( "/etc/modules.conf", O_RDONLY )) < 0 ) |
261 | if (( fd = open ( "/etc/conf.modules", O_RDONLY )) < 0 ) | 261 | if (( fd = open ( "/etc/conf.modules", O_RDONLY )) < 0 ) |
262 | return first; | 262 | return first; |
263 | 263 | ||
264 | continuation_line = 0; | 264 | continuation_line = 0; |
265 | while ( reads ( fd, buffer, sizeof( buffer ))) { | 265 | while ( reads ( fd, buffer, sizeof( buffer ))) { |
266 | int l; | 266 | int l; |
267 | char *p; | 267 | char *p; |
268 | 268 | ||
269 | p = strchr ( buffer, '#' ); | 269 | p = strchr ( buffer, '#' ); |
270 | if ( p ) | 270 | if ( p ) |
271 | *p = 0; | 271 | *p = 0; |
272 | 272 | ||
273 | l = bb_strlen ( buffer ); | 273 | l = bb_strlen ( buffer ); |
274 | 274 | ||
275 | while ( l && isspace ( buffer [l-1] )) { | 275 | while ( l && isspace ( buffer [l-1] )) { |
276 | buffer [l-1] = 0; | 276 | buffer [l-1] = 0; |
277 | l--; | 277 | l--; |
278 | } | 278 | } |
279 | 279 | ||
280 | if ( l == 0 ) { | 280 | if ( l == 0 ) { |
281 | continuation_line = 0; | 281 | continuation_line = 0; |
282 | continue; | 282 | continue; |
283 | } | 283 | } |
284 | 284 | ||
285 | if ( !continuation_line ) { | 285 | if ( !continuation_line ) { |
286 | if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) { | 286 | if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) { |
287 | char *alias, *mod; | 287 | char *alias, *mod; |
288 | 288 | ||
289 | if ( parse_tag_value ( buffer + 6, &alias, &mod )) { | 289 | if ( parse_tag_value ( buffer + 6, &alias, &mod )) { |
290 | // fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod ); | 290 | // fprintf ( stderr, "ALIAS: '%s' -> '%s'\n", alias, mod ); |
291 | 291 | ||
292 | if ( !current ) { | 292 | if ( !current ) { |
293 | first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t )); | 293 | first = current = (struct dep_t *) xmalloc ( sizeof ( struct dep_t )); |
294 | } | 294 | } |
@@ -298,7 +298,7 @@ static struct dep_t *build_dep ( void ) | |||
298 | } | 298 | } |
299 | current-> m_module = bb_xstrdup ( alias ); | 299 | current-> m_module = bb_xstrdup ( alias ); |
300 | current-> m_isalias = 1; | 300 | current-> m_isalias = 1; |
301 | 301 | ||
302 | if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) { | 302 | if (( strcmp ( alias, "off" ) == 0 ) || ( strcmp ( alias, "null" ) == 0 )) { |
303 | current-> m_depcnt = 0; | 303 | current-> m_depcnt = 0; |
304 | current-> m_deparr = 0; | 304 | current-> m_deparr = 0; |
@@ -313,10 +313,10 @@ static struct dep_t *build_dep ( void ) | |||
313 | } | 313 | } |
314 | else if (( strncmp ( buffer, "options", 7 ) == 0 ) && isspace ( buffer [7] )) { | 314 | else if (( strncmp ( buffer, "options", 7 ) == 0 ) && isspace ( buffer [7] )) { |
315 | char *mod, *opt; | 315 | char *mod, *opt; |
316 | 316 | ||
317 | if ( parse_tag_value ( buffer + 8, &mod, &opt )) { | 317 | if ( parse_tag_value ( buffer + 8, &mod, &opt )) { |
318 | struct dep_t *dt; | 318 | struct dep_t *dt; |
319 | 319 | ||
320 | for ( dt = first; dt; dt = dt-> m_next ) { | 320 | for ( dt = first; dt; dt = dt-> m_next ) { |
321 | if ( strcmp ( dt-> m_module, mod ) == 0 ) | 321 | if ( strcmp ( dt-> m_module, mod ) == 0 ) |
322 | break; | 322 | break; |
@@ -324,7 +324,7 @@ static struct dep_t *build_dep ( void ) | |||
324 | if ( dt ) { | 324 | if ( dt ) { |
325 | dt-> m_options = xrealloc ( dt-> m_options, bb_strlen( opt ) + 1 ); | 325 | dt-> m_options = xrealloc ( dt-> m_options, bb_strlen( opt ) + 1 ); |
326 | strcpy ( dt-> m_options, opt ); | 326 | strcpy ( dt-> m_options, opt ); |
327 | 327 | ||
328 | // fprintf ( stderr, "OPTION: '%s' -> '%s'\n", dt-> m_module, dt-> m_options ); | 328 | // fprintf ( stderr, "OPTION: '%s' -> '%s'\n", dt-> m_module, dt-> m_options ); |
329 | } | 329 | } |
330 | } | 330 | } |
@@ -332,7 +332,7 @@ static struct dep_t *build_dep ( void ) | |||
332 | } | 332 | } |
333 | } | 333 | } |
334 | close ( fd ); | 334 | close ( fd ); |
335 | 335 | ||
336 | return first; | 336 | return first; |
337 | } | 337 | } |
338 | 338 | ||
@@ -377,7 +377,7 @@ static int mod_process ( struct mod_list_t *list, int do_insert ) | |||
377 | if (already_loaded (list->m_module) != 0) | 377 | if (already_loaded (list->m_module) != 0) |
378 | snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s", do_syslog ? "-s" : "", list-> m_module ); | 378 | snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s", do_syslog ? "-s" : "", list-> m_module ); |
379 | } | 379 | } |
380 | 380 | ||
381 | if ( verbose ) | 381 | if ( verbose ) |
382 | printf ( "%s\n", lcmd ); | 382 | printf ( "%s\n", lcmd ); |
383 | if ( !show_only && *lcmd) { | 383 | if ( !show_only && *lcmd) { |
@@ -385,7 +385,7 @@ static int mod_process ( struct mod_list_t *list, int do_insert ) | |||
385 | if (do_insert) rc = rc2; /* only last module matters */ | 385 | if (do_insert) rc = rc2; /* only last module matters */ |
386 | else if (!rc2) rc = 0; /* success if remove any mod */ | 386 | else if (!rc2) rc = 0; /* success if remove any mod */ |
387 | } | 387 | } |
388 | 388 | ||
389 | list = do_insert ? list-> m_prev : list-> m_next; | 389 | list = do_insert ? list-> m_prev : list-> m_next; |
390 | } | 390 | } |
391 | return (show_only) ? 0 : rc; | 391 | return (show_only) ? 0 : rc; |
@@ -403,12 +403,12 @@ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t * | |||
403 | 403 | ||
404 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 404 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
405 | if ((k_version > 4) && ( mod [lm-3] == '.' ) && | 405 | if ((k_version > 4) && ( mod [lm-3] == '.' ) && |
406 | ( mod [lm-2] == 'k' ) && ( mod [lm-1] == 'o' )) | 406 | ( mod [lm-2] == 'k' ) && ( mod [lm-1] == 'o' )) |
407 | mod [lm-3] = 0; | 407 | mod [lm-3] = 0; |
408 | else | 408 | else |
409 | #endif | 409 | #endif |
410 | if (( mod [lm-2] == '.' ) && ( mod [lm-1] == 'o' )) | 410 | if (( mod [lm-2] == '.' ) && ( mod [lm-1] == 'o' )) |
411 | mod [lm-2] = 0; | 411 | mod [lm-2] = 0; |
412 | 412 | ||
413 | // check dependencies | 413 | // check dependencies |
414 | for ( dt = depend; dt; dt = dt-> m_next ) { | 414 | for ( dt = depend; dt; dt = dt-> m_next ) { |
@@ -417,12 +417,12 @@ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t * | |||
417 | break; | 417 | break; |
418 | } | 418 | } |
419 | } | 419 | } |
420 | 420 | ||
421 | // resolve alias names | 421 | // resolve alias names |
422 | while ( dt && dt-> m_isalias ) { | 422 | while ( dt && dt-> m_isalias ) { |
423 | if ( dt-> m_depcnt == 1 ) { | 423 | if ( dt-> m_depcnt == 1 ) { |
424 | struct dep_t *adt; | 424 | struct dep_t *adt; |
425 | 425 | ||
426 | for ( adt = depend; adt; adt = adt-> m_next ) { | 426 | for ( adt = depend; adt; adt = adt-> m_next ) { |
427 | if ( strcmp ( adt-> m_module, dt-> m_deparr [0] ) == 0 ) | 427 | if ( strcmp ( adt-> m_module, dt-> m_deparr [0] ) == 0 ) |
428 | break; | 428 | break; |
@@ -439,7 +439,7 @@ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t * | |||
439 | else | 439 | else |
440 | return; | 440 | return; |
441 | } | 441 | } |
442 | 442 | ||
443 | // search for duplicates | 443 | // search for duplicates |
444 | for ( find = *head; find; find = find-> m_next ) { | 444 | for ( find = *head; find; find = find-> m_next ) { |
445 | if ( !strcmp ( mod, find-> m_module )) { | 445 | if ( !strcmp ( mod, find-> m_module )) { |
@@ -449,12 +449,12 @@ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t * | |||
449 | find-> m_prev-> m_next = find-> m_next; | 449 | find-> m_prev-> m_next = find-> m_next; |
450 | else | 450 | else |
451 | *head = find-> m_next; | 451 | *head = find-> m_next; |
452 | 452 | ||
453 | if ( find-> m_next ) | 453 | if ( find-> m_next ) |
454 | find-> m_next-> m_prev = find-> m_prev; | 454 | find-> m_next-> m_prev = find-> m_prev; |
455 | else | 455 | else |
456 | *tail = find-> m_prev; | 456 | *tail = find-> m_prev; |
457 | 457 | ||
458 | break; // there can be only one duplicate | 458 | break; // there can be only one duplicate |
459 | } | 459 | } |
460 | } | 460 | } |
@@ -474,10 +474,10 @@ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t * | |||
474 | if ( !*head ) | 474 | if ( !*head ) |
475 | *head = find; | 475 | *head = find; |
476 | *tail = find; | 476 | *tail = find; |
477 | 477 | ||
478 | if ( dt ) { | 478 | if ( dt ) { |
479 | int i; | 479 | int i; |
480 | 480 | ||
481 | for ( i = 0; i < dt-> m_depcnt; i++ ) | 481 | for ( i = 0; i < dt-> m_depcnt; i++ ) |
482 | check_dep ( dt-> m_deparr [i], head, tail ); | 482 | check_dep ( dt-> m_deparr [i], head, tail ); |
483 | } | 483 | } |
@@ -490,34 +490,34 @@ static int mod_insert ( char *mod, int argc, char **argv ) | |||
490 | struct mod_list_t *tail = 0; | 490 | struct mod_list_t *tail = 0; |
491 | struct mod_list_t *head = 0; | 491 | struct mod_list_t *head = 0; |
492 | int rc; | 492 | int rc; |
493 | 493 | ||
494 | // get dep list for module mod | 494 | // get dep list for module mod |
495 | check_dep ( mod, &head, &tail ); | 495 | check_dep ( mod, &head, &tail ); |
496 | 496 | ||
497 | if ( head && tail ) { | 497 | if ( head && tail ) { |
498 | if ( argc ) { | 498 | if ( argc ) { |
499 | int i; | 499 | int i; |
500 | int l = 0; | 500 | int l = 0; |
501 | 501 | ||
502 | // append module args | 502 | // append module args |
503 | for ( i = 0; i < argc; i++ ) | 503 | for ( i = 0; i < argc; i++ ) |
504 | l += ( bb_strlen ( argv [i] ) + 1 ); | 504 | l += ( bb_strlen ( argv [i] ) + 1 ); |
505 | 505 | ||
506 | head-> m_options = xrealloc ( head-> m_options, l + 1 ); | 506 | head-> m_options = xrealloc ( head-> m_options, l + 1 ); |
507 | head-> m_options [0] = 0; | 507 | head-> m_options [0] = 0; |
508 | 508 | ||
509 | for ( i = 0; i < argc; i++ ) { | 509 | for ( i = 0; i < argc; i++ ) { |
510 | strcat ( head-> m_options, argv [i] ); | 510 | strcat ( head-> m_options, argv [i] ); |
511 | strcat ( head-> m_options, " " ); | 511 | strcat ( head-> m_options, " " ); |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | // process tail ---> head | 515 | // process tail ---> head |
516 | rc = mod_process ( tail, 1 ); | 516 | rc = mod_process ( tail, 1 ); |
517 | } | 517 | } |
518 | else | 518 | else |
519 | rc = 1; | 519 | rc = 1; |
520 | 520 | ||
521 | return rc; | 521 | return rc; |
522 | } | 522 | } |
523 | 523 | ||
@@ -525,21 +525,21 @@ static int mod_remove ( char *mod ) | |||
525 | { | 525 | { |
526 | int rc; | 526 | int rc; |
527 | static struct mod_list_t rm_a_dummy = { "-a", 0, 0 }; | 527 | static struct mod_list_t rm_a_dummy = { "-a", 0, 0 }; |
528 | 528 | ||
529 | struct mod_list_t *head = 0; | 529 | struct mod_list_t *head = 0; |
530 | struct mod_list_t *tail = 0; | 530 | struct mod_list_t *tail = 0; |
531 | 531 | ||
532 | if ( mod ) | 532 | if ( mod ) |
533 | check_dep ( mod, &head, &tail ); | 533 | check_dep ( mod, &head, &tail ); |
534 | else // autoclean | 534 | else // autoclean |
535 | head = tail = &rm_a_dummy; | 535 | head = tail = &rm_a_dummy; |
536 | 536 | ||
537 | if ( head && tail ) | 537 | if ( head && tail ) |
538 | rc = mod_process ( head, 0 ); // process head ---> tail | 538 | rc = mod_process ( head, 0 ); // process head ---> tail |
539 | else | 539 | else |
540 | rc = 1; | 540 | rc = 1; |
541 | return rc; | 541 | return rc; |
542 | 542 | ||
543 | } | 543 | } |
544 | 544 | ||
545 | 545 | ||
@@ -553,67 +553,67 @@ extern int modprobe_main(int argc, char** argv) | |||
553 | 553 | ||
554 | while ((opt = getopt(argc, argv, "acdklnqrst:vVC:")) != -1) { | 554 | while ((opt = getopt(argc, argv, "acdklnqrst:vVC:")) != -1) { |
555 | switch(opt) { | 555 | switch(opt) { |
556 | case 'c': // no config used | 556 | case 'c': // no config used |
557 | case 'l': // no pattern matching | 557 | case 'l': // no pattern matching |
558 | return EXIT_SUCCESS; | 558 | return EXIT_SUCCESS; |
559 | break; | 559 | break; |
560 | case 'C': // no config used | 560 | case 'C': // no config used |
561 | case 't': // no pattern matching | 561 | case 't': // no pattern matching |
562 | bb_error_msg_and_die("-t and -C not supported"); | 562 | bb_error_msg_and_die("-t and -C not supported"); |
563 | 563 | ||
564 | case 'a': // ignore | 564 | case 'a': // ignore |
565 | case 'd': // ignore | 565 | case 'd': // ignore |
566 | break; | 566 | break; |
567 | case 'k': | 567 | case 'k': |
568 | autoclean++; | 568 | autoclean++; |
569 | break; | 569 | break; |
570 | case 'n': | 570 | case 'n': |
571 | show_only++; | 571 | show_only++; |
572 | break; | 572 | break; |
573 | case 'q': | 573 | case 'q': |
574 | quiet++; | 574 | quiet++; |
575 | break; | 575 | break; |
576 | case 'r': | 576 | case 'r': |
577 | remove_opt++; | 577 | remove_opt++; |
578 | break; | 578 | break; |
579 | case 's': | 579 | case 's': |
580 | do_syslog++; | 580 | do_syslog++; |
581 | break; | 581 | break; |
582 | case 'v': | 582 | case 'v': |
583 | verbose++; | 583 | verbose++; |
584 | break; | 584 | break; |
585 | case 'V': | 585 | case 'V': |
586 | default: | 586 | default: |
587 | bb_show_usage(); | 587 | bb_show_usage(); |
588 | break; | 588 | break; |
589 | } | 589 | } |
590 | } | 590 | } |
591 | 591 | ||
592 | depend = build_dep ( ); | 592 | depend = build_dep ( ); |
593 | 593 | ||
594 | if ( !depend ) | 594 | if ( !depend ) |
595 | bb_error_msg_and_die ( "could not parse modules.dep\n" ); | 595 | bb_error_msg_and_die ( "could not parse modules.dep\n" ); |
596 | 596 | ||
597 | if (remove_opt) { | 597 | if (remove_opt) { |
598 | int rc = EXIT_SUCCESS; | 598 | int rc = EXIT_SUCCESS; |
599 | do { | 599 | do { |
600 | if (mod_remove ( optind < argc ? | 600 | if (mod_remove ( optind < argc ? |
601 | bb_xstrdup (argv [optind]) : NULL )) { | 601 | bb_xstrdup (argv [optind]) : NULL )) { |
602 | bb_error_msg ("failed to remove module %s", | 602 | bb_error_msg ("failed to remove module %s", |
603 | argv [optind] ); | 603 | argv [optind] ); |
604 | rc = EXIT_FAILURE; | 604 | rc = EXIT_FAILURE; |
605 | } | 605 | } |
606 | } while ( ++optind < argc ); | 606 | } while ( ++optind < argc ); |
607 | 607 | ||
608 | return rc; | 608 | return rc; |
609 | } | 609 | } |
610 | 610 | ||
611 | if (optind >= argc) | 611 | if (optind >= argc) |
612 | bb_error_msg_and_die ( "No module or pattern provided\n" ); | 612 | bb_error_msg_and_die ( "No module or pattern provided\n" ); |
613 | 613 | ||
614 | if ( mod_insert ( bb_xstrdup ( argv [optind] ), argc - optind - 1, argv + optind + 1 )) | 614 | if ( mod_insert ( bb_xstrdup ( argv [optind] ), argc - optind - 1, argv + optind + 1 )) |
615 | bb_error_msg_and_die ( "failed to load module %s", argv [optind] ); | 615 | bb_error_msg_and_die ( "failed to load module %s", argv [optind] ); |
616 | 616 | ||
617 | return EXIT_SUCCESS; | 617 | return EXIT_SUCCESS; |
618 | } | 618 | } |
619 | 619 | ||
diff --git a/modutils/rmmod.c b/modutils/rmmod.c index 311b03dc4..0cebb6e67 100644 --- a/modutils/rmmod.c +++ b/modutils/rmmod.c | |||
@@ -73,7 +73,7 @@ extern int rmmod_main(int argc, char **argv) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | if (optind == argc) | 75 | if (optind == argc) |
76 | bb_show_usage(); | 76 | bb_show_usage(); |
77 | 77 | ||
78 | for (n = optind; n < argc; n++) { | 78 | for (n = optind; n < argc; n++) { |
79 | if (syscall(__NR_delete_module, argv[n], flags) < 0) { | 79 | if (syscall(__NR_delete_module, argv[n], flags) < 0) { |