diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-02-20 20:47:08 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-02-20 20:47:08 +0000 |
commit | 90fe7fea10b69d85c4d53e7061aaf85657136530 (patch) | |
tree | 880d32c3fe6684570da9eaedd0e1f86437c329b3 | |
parent | 477aedd77f5e4abeefbf686e21f395686aca16d3 (diff) | |
download | busybox-w32-90fe7fea10b69d85c4d53e7061aaf85657136530.tar.gz busybox-w32-90fe7fea10b69d85c4d53e7061aaf85657136530.tar.bz2 busybox-w32-90fe7fea10b69d85c4d53e7061aaf85657136530.zip |
Apply a patch from Magnus Damm <damm@opensource.se> to support
powerpc with busybox insmod
-Erik
-rw-r--r-- | insmod.c | 199 | ||||
-rw-r--r-- | modutils/insmod.c | 199 |
2 files changed, 322 insertions, 76 deletions
@@ -14,6 +14,12 @@ | |||
14 | * very minor changes required to also work with StrongArm and presumably | 14 | * very minor changes required to also work with StrongArm and presumably |
15 | * all ARM based systems. | 15 | * all ARM based systems. |
16 | * | 16 | * |
17 | * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001. | ||
18 | * PowerPC specific code stolen from modutils-2.3.16, | ||
19 | * written by Paul Mackerras, Copyright 1996, 1997 Linux International. | ||
20 | * I've only tested the code on mpc8xx platforms in big-endian mode. | ||
21 | * Did some cleanup and added BB_USE_xxx_ENTRIES... | ||
22 | * | ||
17 | * Based almost entirely on the Linux modutils-2.3.11 implementation. | 23 | * Based almost entirely on the Linux modutils-2.3.11 implementation. |
18 | * Copyright 1996, 1997 Linux International. | 24 | * Copyright 1996, 1997 Linux International. |
19 | * New implementation contributed by Richard Henderson <rth@tamu.edu> | 25 | * New implementation contributed by Richard Henderson <rth@tamu.edu> |
@@ -52,6 +58,28 @@ | |||
52 | #include <linux/unistd.h> | 58 | #include <linux/unistd.h> |
53 | #include "busybox.h" | 59 | #include "busybox.h" |
54 | 60 | ||
61 | #if defined(__powerpc__) | ||
62 | #define BB_USE_PLT_ENTRIES | ||
63 | #define BB_PLT_ENTRY_SIZE 16 | ||
64 | #endif | ||
65 | |||
66 | #if defined(__arm__) | ||
67 | #define BB_USE_PLT_ENTRIES | ||
68 | #define BB_PLT_ENTRY_SIZE 8 | ||
69 | #define BB_USE_GOT_ENTRIES | ||
70 | #define BB_GOT_ENTRY_SIZE 8 | ||
71 | #endif | ||
72 | |||
73 | #if defined(__sh__) | ||
74 | #define BB_USE_GOT_ENTRIES | ||
75 | #define BB_GOT_ENTRY_SIZE 4 | ||
76 | #endif | ||
77 | |||
78 | #if defined(__i386__) | ||
79 | #define BB_USE_GOT_ENTRIES | ||
80 | #define BB_GOT_ENTRY_SIZE 4 | ||
81 | #endif | ||
82 | |||
55 | //---------------------------------------------------------------------------- | 83 | //---------------------------------------------------------------------------- |
56 | //--------modutils module.h, lines 45-242 | 84 | //--------modutils module.h, lines 45-242 |
57 | //---------------------------------------------------------------------------- | 85 | //---------------------------------------------------------------------------- |
@@ -81,7 +109,7 @@ | |||
81 | #ifndef MODUTILS_MODULE_H | 109 | #ifndef MODUTILS_MODULE_H |
82 | static const int MODUTILS_MODULE_H = 1; | 110 | static const int MODUTILS_MODULE_H = 1; |
83 | 111 | ||
84 | #ident "$Id: insmod.c,v 1.48 2001/02/20 06:14:07 andersen Exp $" | 112 | #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" |
85 | 113 | ||
86 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | 114 | /* This file contains the structures used by the 2.0 and 2.1 kernels. |
87 | We do not use the kernel headers directly because we do not wish | 115 | We do not use the kernel headers directly because we do not wish |
@@ -287,7 +315,7 @@ int delete_module(const char *); | |||
287 | #ifndef MODUTILS_OBJ_H | 315 | #ifndef MODUTILS_OBJ_H |
288 | static const int MODUTILS_OBJ_H = 1; | 316 | static const int MODUTILS_OBJ_H = 1; |
289 | 317 | ||
290 | #ident "$Id: insmod.c,v 1.48 2001/02/20 06:14:07 andersen Exp $" | 318 | #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" |
291 | 319 | ||
292 | /* The relocatable object is manipulated using elfin types. */ | 320 | /* The relocatable object is manipulated using elfin types. */ |
293 | 321 | ||
@@ -311,21 +339,27 @@ static const int MODUTILS_OBJ_H = 1; | |||
311 | #endif | 339 | #endif |
312 | 340 | ||
313 | #define ELFCLASSM ELFCLASS32 | 341 | #define ELFCLASSM ELFCLASS32 |
314 | #define ELFDATAM ELFDATA2LSB | ||
315 | |||
316 | |||
317 | 342 | ||
318 | #if defined(__sh__) | 343 | #if defined(__sh__) |
319 | 344 | ||
320 | #define MATCH_MACHINE(x) (x == EM_SH) | 345 | #define MATCH_MACHINE(x) (x == EM_SH) |
321 | #define SHT_RELM SHT_RELA | 346 | #define SHT_RELM SHT_RELA |
322 | #define Elf32_RelM Elf32_Rela | 347 | #define Elf32_RelM Elf32_Rela |
348 | #define ELFDATAM ELFDATA2LSB | ||
323 | 349 | ||
324 | #elif defined(__arm__) | 350 | #elif defined(__arm__) |
325 | 351 | ||
326 | #define MATCH_MACHINE(x) (x == EM_ARM) | 352 | #define MATCH_MACHINE(x) (x == EM_ARM) |
327 | #define SHT_RELM SHT_REL | 353 | #define SHT_RELM SHT_REL |
328 | #define Elf32_RelM Elf32_Rel | 354 | #define Elf32_RelM Elf32_Rel |
355 | #define ELFDATAM ELFDATA2LSB | ||
356 | |||
357 | #elif defined(__powerpc__) | ||
358 | |||
359 | #define MATCH_MACHINE(x) (x == EM_PPC) | ||
360 | #define SHT_RELM SHT_RELA | ||
361 | #define Elf32_RelM Elf32_Rela | ||
362 | #define ELFDATAM ELFDATA2MSB | ||
329 | 363 | ||
330 | #elif defined(__i386__) | 364 | #elif defined(__i386__) |
331 | 365 | ||
@@ -340,6 +374,7 @@ static const int MODUTILS_OBJ_H = 1; | |||
340 | 374 | ||
341 | #define SHT_RELM SHT_REL | 375 | #define SHT_RELM SHT_REL |
342 | #define Elf32_RelM Elf32_Rel | 376 | #define Elf32_RelM Elf32_Rel |
377 | #define ELFDATAM ELFDATA2LSB | ||
343 | 378 | ||
344 | #else | 379 | #else |
345 | #error Sorry, but insmod.c does not yet support this architecture... | 380 | #error Sorry, but insmod.c does not yet support this architecture... |
@@ -540,8 +575,10 @@ int flag_export = 1; | |||
540 | 575 | ||
541 | /* Done ;-) */ | 576 | /* Done ;-) */ |
542 | 577 | ||
543 | #if defined(__arm__) | 578 | |
544 | struct arm_plt_entry | 579 | |
580 | #if defined(BB_USE_PLT_ENTRIES) | ||
581 | struct arch_plt_entry | ||
545 | { | 582 | { |
546 | int offset; | 583 | int offset; |
547 | int allocated:1; | 584 | int allocated:1; |
@@ -549,26 +586,32 @@ struct arm_plt_entry | |||
549 | }; | 586 | }; |
550 | #endif | 587 | #endif |
551 | 588 | ||
589 | #if defined(BB_USE_GOT_ENTRIES) | ||
552 | struct arch_got_entry { | 590 | struct arch_got_entry { |
553 | int offset; | 591 | int offset; |
554 | unsigned offset_done:1; | 592 | unsigned offset_done:1; |
555 | unsigned reloc_done:1; | 593 | unsigned reloc_done:1; |
556 | }; | 594 | }; |
595 | #endif | ||
557 | 596 | ||
558 | struct arch_file { | 597 | struct arch_file { |
559 | struct obj_file root; | 598 | struct obj_file root; |
560 | #if defined(__arm__) | 599 | #if defined(BB_USE_PLT_ENTRIES) |
561 | struct obj_section *plt; | 600 | struct obj_section *plt; |
562 | #endif | 601 | #endif |
602 | #if defined(BB_USE_GOT_ENTRIES) | ||
563 | struct obj_section *got; | 603 | struct obj_section *got; |
604 | #endif | ||
564 | }; | 605 | }; |
565 | 606 | ||
566 | struct arch_symbol { | 607 | struct arch_symbol { |
567 | struct obj_symbol root; | 608 | struct obj_symbol root; |
568 | #if defined(__arm__) | 609 | #if defined(BB_USE_PLT_ENTRIES) |
569 | struct arm_plt_entry pltent; | 610 | struct arch_plt_entry pltent; |
570 | #endif | 611 | #endif |
612 | #if defined(BB_USE_GOT_ENTRIES) | ||
571 | struct arch_got_entry gotent; | 613 | struct arch_got_entry gotent; |
614 | #endif | ||
572 | }; | 615 | }; |
573 | 616 | ||
574 | 617 | ||
@@ -618,7 +661,8 @@ extern int delete_module(const char *); | |||
618 | _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks) | 661 | _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks) |
619 | #endif | 662 | #endif |
620 | 663 | ||
621 | #if defined(__i386__) || defined(__m68k__) || defined(__arm__) | 664 | #if defined(__i386__) || defined(__m68k__) || defined(__arm__) \ |
665 | || defined(__powerpc__) | ||
622 | /* Jump through hoops to fixup error return codes */ | 666 | /* Jump through hoops to fixup error return codes */ |
623 | #define __NR__create_module __NR_create_module | 667 | #define __NR__create_module __NR_create_module |
624 | static inline _syscall2(long, _create_module, const char *, name, size_t, | 668 | static inline _syscall2(long, _create_module, const char *, name, size_t, |
@@ -673,7 +717,14 @@ struct obj_file *arch_new_file(void) | |||
673 | { | 717 | { |
674 | struct arch_file *f; | 718 | struct arch_file *f; |
675 | f = xmalloc(sizeof(*f)); | 719 | f = xmalloc(sizeof(*f)); |
720 | |||
721 | #if defined(BB_USE_PLT_ENTRIES) | ||
722 | f->plt = NULL; | ||
723 | #endif | ||
724 | #if defined(BB_USE_GOT_ENTRIES) | ||
676 | f->got = NULL; | 725 | f->got = NULL; |
726 | #endif | ||
727 | |||
677 | return &f->root; | 728 | return &f->root; |
678 | } | 729 | } |
679 | 730 | ||
@@ -686,7 +737,14 @@ struct obj_symbol *arch_new_symbol(void) | |||
686 | { | 737 | { |
687 | struct arch_symbol *sym; | 738 | struct arch_symbol *sym; |
688 | sym = xmalloc(sizeof(*sym)); | 739 | sym = xmalloc(sizeof(*sym)); |
740 | |||
741 | #if defined(BB_USE_PLT_ENTRIES) | ||
742 | memset(&sym->pltent, 0, sizeof(sym->pltent)); | ||
743 | #endif | ||
744 | #if defined(BB_USE_GOT_ENTRIES) | ||
689 | memset(&sym->gotent, 0, sizeof(sym->gotent)); | 745 | memset(&sym->gotent, 0, sizeof(sym->gotent)); |
746 | #endif | ||
747 | |||
690 | return &sym->root; | 748 | return &sym->root; |
691 | } | 749 | } |
692 | 750 | ||
@@ -702,14 +760,14 @@ arch_apply_relocation(struct obj_file *f, | |||
702 | 760 | ||
703 | ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); | 761 | ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); |
704 | ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; | 762 | ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; |
763 | #if defined(BB_USE_GOT_ENTRIES) | ||
705 | ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; | 764 | ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; |
706 | #if defined(__arm__) | 765 | #endif |
766 | #if defined(BB_USE_PLT_ENTRIES) | ||
707 | ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; | 767 | ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; |
708 | 768 | struct arch_plt_entry *pe; | |
709 | struct arm_plt_entry *pe; | ||
710 | unsigned long *ip; | 769 | unsigned long *ip; |
711 | #endif | 770 | #endif |
712 | |||
713 | enum obj_reloc ret = obj_reloc_ok; | 771 | enum obj_reloc ret = obj_reloc_ok; |
714 | 772 | ||
715 | switch (ELF32_R_TYPE(rel->r_info)) { | 773 | switch (ELF32_R_TYPE(rel->r_info)) { |
@@ -723,6 +781,8 @@ arch_apply_relocation(struct obj_file *f, | |||
723 | case R_ARM_NONE: | 781 | case R_ARM_NONE: |
724 | #elif defined(__i386__) | 782 | #elif defined(__i386__) |
725 | case R_386_NONE: | 783 | case R_386_NONE: |
784 | #elif defined(__powerpc__) | ||
785 | case R_PPC_NONE: | ||
726 | #endif | 786 | #endif |
727 | break; | 787 | break; |
728 | 788 | ||
@@ -731,11 +791,27 @@ arch_apply_relocation(struct obj_file *f, | |||
731 | #elif defined(__arm__) | 791 | #elif defined(__arm__) |
732 | case R_ARM_ABS32: | 792 | case R_ARM_ABS32: |
733 | #elif defined(__i386__) | 793 | #elif defined(__i386__) |
734 | case R_386_32: | 794 | case R_386_32: |
795 | #elif defined(__powerpc__) | ||
796 | case R_PPC_ADDR32: | ||
735 | #endif | 797 | #endif |
736 | *loc += v; | 798 | *loc += v; |
737 | break; | 799 | break; |
738 | 800 | ||
801 | #if defined(__powerpc__) | ||
802 | case R_PPC_ADDR16_HA: | ||
803 | *(unsigned short *)loc = (v + 0x8000) >> 16; | ||
804 | break; | ||
805 | |||
806 | case R_PPC_ADDR16_HI: | ||
807 | *(unsigned short *)loc = v >> 16; | ||
808 | break; | ||
809 | |||
810 | case R_PPC_ADDR16_LO: | ||
811 | *(unsigned short *)loc = v; | ||
812 | break; | ||
813 | #endif | ||
814 | |||
739 | #if defined(__arm__) | 815 | #if defined(__arm__) |
740 | #elif defined(__sh__) | 816 | #elif defined(__sh__) |
741 | case R_SH_REL32: | 817 | case R_SH_REL32: |
@@ -746,22 +822,48 @@ arch_apply_relocation(struct obj_file *f, | |||
746 | case R_386_PC32: | 822 | case R_386_PC32: |
747 | *loc += v - dot; | 823 | *loc += v - dot; |
748 | break; | 824 | break; |
825 | #elif defined(__powerpc__) | ||
826 | case R_PPC_REL32: | ||
827 | *loc = v - dot; | ||
828 | break; | ||
749 | #endif | 829 | #endif |
750 | 830 | ||
751 | #if defined(__sh__) | 831 | #if defined(__sh__) |
752 | case R_SH_PLT32: | 832 | case R_SH_PLT32: |
753 | *loc = v - dot; | 833 | *loc = v - dot; |
754 | break; | 834 | break; |
755 | #elif defined(__arm__) | 835 | #elif defined(__i386__) |
836 | #endif | ||
837 | |||
838 | #if defined(BB_USE_PLT_ENTRIES) | ||
839 | |||
840 | #if defined(__arm__) | ||
756 | case R_ARM_PC24: | 841 | case R_ARM_PC24: |
757 | case R_ARM_PLT32: | 842 | case R_ARM_PLT32: |
843 | #endif | ||
844 | #if defined(__powerpc__) | ||
845 | case R_PPC_REL24: | ||
846 | #endif | ||
758 | /* find the plt entry and initialize it if necessary */ | 847 | /* find the plt entry and initialize it if necessary */ |
759 | assert(isym != NULL); | 848 | assert(isym != NULL); |
760 | pe = (struct arm_plt_entry*) &isym->pltent; | 849 | |
850 | pe = (struct arch_plt_entry*) &isym->pltent; | ||
851 | |||
761 | if (! pe->inited) { | 852 | if (! pe->inited) { |
762 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); | 853 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); |
854 | |||
855 | /* generate some machine code */ | ||
856 | |||
857 | #if defined(__arm__) | ||
763 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ | 858 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ |
764 | ip[1] = v; /* sym@ */ | 859 | ip[1] = v; /* sym@ */ |
860 | #endif | ||
861 | #if defined(__powerpc__) | ||
862 | ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ | ||
863 | ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ | ||
864 | ip[2] = 0x7d6903a6; /* mtctr r11 */ | ||
865 | ip[3] = 0x4e800420; /* bctr */ | ||
866 | #endif | ||
765 | pe->inited = 1; | 867 | pe->inited = 1; |
766 | } | 868 | } |
767 | 869 | ||
@@ -775,15 +877,18 @@ arch_apply_relocation(struct obj_file *f, | |||
775 | if (v & 3) | 877 | if (v & 3) |
776 | ret = obj_reloc_dangerous; | 878 | ret = obj_reloc_dangerous; |
777 | 879 | ||
880 | /* merge the offset into the instruction. */ | ||
881 | #if defined(__arm__) | ||
778 | /* Convert to words. */ | 882 | /* Convert to words. */ |
779 | v >>= 2; | 883 | v >>= 2; |
780 | 884 | ||
781 | /* merge the offset into the instruction. */ | ||
782 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); | 885 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); |
783 | break; | ||
784 | #elif defined(__i386__) | ||
785 | #endif | 886 | #endif |
786 | 887 | #if defined(__powerpc__) | |
888 | *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); | ||
889 | #endif | ||
890 | break; | ||
891 | #endif /* BB_USE_PLT_ENTRIES */ | ||
787 | 892 | ||
788 | #if defined(__arm__) | 893 | #if defined(__arm__) |
789 | #elif defined(__sh__) | 894 | #elif defined(__sh__) |
@@ -809,6 +914,8 @@ arch_apply_relocation(struct obj_file *f, | |||
809 | break; | 914 | break; |
810 | #endif | 915 | #endif |
811 | 916 | ||
917 | #if defined(BB_USE_GOT_ENTRIES) | ||
918 | |||
812 | #if defined(__sh__) | 919 | #if defined(__sh__) |
813 | case R_SH_GOTPC: | 920 | case R_SH_GOTPC: |
814 | #elif defined(__arm__) | 921 | #elif defined(__arm__) |
@@ -827,7 +934,7 @@ arch_apply_relocation(struct obj_file *f, | |||
827 | #if defined(__sh__) | 934 | #if defined(__sh__) |
828 | case R_SH_GOT32: | 935 | case R_SH_GOT32: |
829 | #elif defined(__arm__) | 936 | #elif defined(__arm__) |
830 | case R_ARM_GOT32: | 937 | case R_ARM_GOT32: |
831 | #elif defined(__i386__) | 938 | #elif defined(__i386__) |
832 | case R_386_GOT32: | 939 | case R_386_GOT32: |
833 | #endif | 940 | #endif |
@@ -849,7 +956,7 @@ arch_apply_relocation(struct obj_file *f, | |||
849 | #if defined(__sh__) | 956 | #if defined(__sh__) |
850 | case R_SH_GOTOFF: | 957 | case R_SH_GOTOFF: |
851 | #elif defined(__arm__) | 958 | #elif defined(__arm__) |
852 | case R_ARM_GOTOFF: | 959 | case R_ARM_GOTOFF: |
853 | #elif defined(__i386__) | 960 | #elif defined(__i386__) |
854 | case R_386_GOTOFF: | 961 | case R_386_GOTOFF: |
855 | #endif | 962 | #endif |
@@ -857,6 +964,8 @@ arch_apply_relocation(struct obj_file *f, | |||
857 | *loc += v - got; | 964 | *loc += v - got; |
858 | break; | 965 | break; |
859 | 966 | ||
967 | #endif /* BB_USE_GOT_ENTRIES */ | ||
968 | |||
860 | default: | 969 | default: |
861 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); | 970 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); |
862 | ret = obj_reloc_unhandled; | 971 | ret = obj_reloc_unhandled; |
@@ -869,8 +978,11 @@ arch_apply_relocation(struct obj_file *f, | |||
869 | int arch_create_got(struct obj_file *f) | 978 | int arch_create_got(struct obj_file *f) |
870 | { | 979 | { |
871 | struct arch_file *ifile = (struct arch_file *) f; | 980 | struct arch_file *ifile = (struct arch_file *) f; |
872 | int i, got_offset = 0, gotneeded = 0; | 981 | int i; |
873 | #if defined(__arm__) | 982 | #if defined(BB_USE_GOT_ENTRIES) |
983 | int got_offset = 0, gotneeded = 0; | ||
984 | #endif | ||
985 | #if defined(BB_USE_PLT_ENTRIES) | ||
874 | int plt_offset = 0, pltneeded = 0; | 986 | int plt_offset = 0, pltneeded = 0; |
875 | #endif | 987 | #endif |
876 | struct obj_section *relsec, *symsec, *strsec; | 988 | struct obj_section *relsec, *symsec, *strsec; |
@@ -898,12 +1010,20 @@ int arch_create_got(struct obj_file *f) | |||
898 | switch (ELF32_R_TYPE(rel->r_info)) { | 1010 | switch (ELF32_R_TYPE(rel->r_info)) { |
899 | #if defined(__arm__) | 1011 | #if defined(__arm__) |
900 | case R_ARM_GOT32: | 1012 | case R_ARM_GOT32: |
1013 | break; | ||
901 | #elif defined(__sh__) | 1014 | #elif defined(__sh__) |
902 | case R_SH_GOT32: | 1015 | case R_SH_GOT32: |
1016 | break; | ||
903 | #elif defined(__i386__) | 1017 | #elif defined(__i386__) |
904 | case R_386_GOT32: | 1018 | case R_386_GOT32: |
1019 | break; | ||
905 | #endif | 1020 | #endif |
1021 | |||
1022 | #if defined(__powerpc__) | ||
1023 | case R_PPC_REL24: | ||
1024 | pltneeded = 1; | ||
906 | break; | 1025 | break; |
1026 | #endif | ||
907 | 1027 | ||
908 | #if defined(__arm__) | 1028 | #if defined(__arm__) |
909 | case R_ARM_PC24: | 1029 | case R_ARM_PC24: |
@@ -936,17 +1056,18 @@ int arch_create_got(struct obj_file *f) | |||
936 | name = f->sections[extsym->st_shndx]->name; | 1056 | name = f->sections[extsym->st_shndx]->name; |
937 | } | 1057 | } |
938 | intsym = (struct arch_symbol *) obj_find_symbol(f, name); | 1058 | intsym = (struct arch_symbol *) obj_find_symbol(f, name); |
939 | 1059 | #if defined(BB_USE_GOT_ENTRIES) | |
940 | if (!intsym->gotent.offset_done) { | 1060 | if (!intsym->gotent.offset_done) { |
941 | intsym->gotent.offset_done = 1; | 1061 | intsym->gotent.offset_done = 1; |
942 | intsym->gotent.offset = got_offset; | 1062 | intsym->gotent.offset = got_offset; |
943 | got_offset += 4; | 1063 | got_offset += BB_GOT_ENTRY_SIZE; |
944 | } | 1064 | } |
945 | #if defined(__arm__) | 1065 | #endif |
1066 | #if defined(BB_USE_PLT_ENTRIES) | ||
946 | if (pltneeded && intsym->pltent.allocated == 0) { | 1067 | if (pltneeded && intsym->pltent.allocated == 0) { |
947 | intsym->pltent.allocated = 1; | 1068 | intsym->pltent.allocated = 1; |
948 | intsym->pltent.offset = plt_offset; | 1069 | intsym->pltent.offset = plt_offset; |
949 | plt_offset += 8; | 1070 | plt_offset += BB_PLT_ENTRY_SIZE; |
950 | intsym->pltent.inited = 0; | 1071 | intsym->pltent.inited = 0; |
951 | pltneeded = 0; | 1072 | pltneeded = 0; |
952 | } | 1073 | } |
@@ -954,27 +1075,29 @@ int arch_create_got(struct obj_file *f) | |||
954 | } | 1075 | } |
955 | } | 1076 | } |
956 | 1077 | ||
957 | #if defined(__arm__) | 1078 | #if defined(BB_USE_GOT_ENTRIES) |
958 | if (got_offset) { | 1079 | if (got_offset) { |
959 | struct obj_section* relsec = obj_find_section(f, ".got"); | 1080 | struct obj_section* relsec = obj_find_section(f, ".got"); |
960 | 1081 | ||
961 | if (relsec) { | 1082 | if (relsec) { |
962 | obj_extend_section(relsec, got_offset); | 1083 | obj_extend_section(relsec, got_offset); |
963 | } else { | 1084 | } else { |
964 | relsec = obj_create_alloced_section(f, ".got", 8, got_offset); | 1085 | relsec = obj_create_alloced_section(f, ".got", |
1086 | BB_GOT_ENTRY_SIZE, | ||
1087 | got_offset); | ||
965 | assert(relsec); | 1088 | assert(relsec); |
966 | } | 1089 | } |
967 | 1090 | ||
968 | ifile->got = relsec; | 1091 | ifile->got = relsec; |
969 | } | 1092 | } |
1093 | #endif | ||
970 | 1094 | ||
1095 | #if defined(BB_USE_PLT_ENTRIES) | ||
971 | if (plt_offset) | 1096 | if (plt_offset) |
972 | ifile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset); | 1097 | ifile->plt = obj_create_alloced_section(f, ".plt", |
973 | #else | 1098 | BB_PLT_ENTRY_SIZE, |
974 | if (got_offset > 0 || gotneeded) | 1099 | plt_offset); |
975 | ifile->got = obj_create_alloced_section(f, ".got", 4, got_offset); | ||
976 | #endif | 1100 | #endif |
977 | |||
978 | return 1; | 1101 | return 1; |
979 | } | 1102 | } |
980 | 1103 | ||
diff --git a/modutils/insmod.c b/modutils/insmod.c index 166f0fc4b..7af135902 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -14,6 +14,12 @@ | |||
14 | * very minor changes required to also work with StrongArm and presumably | 14 | * very minor changes required to also work with StrongArm and presumably |
15 | * all ARM based systems. | 15 | * all ARM based systems. |
16 | * | 16 | * |
17 | * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001. | ||
18 | * PowerPC specific code stolen from modutils-2.3.16, | ||
19 | * written by Paul Mackerras, Copyright 1996, 1997 Linux International. | ||
20 | * I've only tested the code on mpc8xx platforms in big-endian mode. | ||
21 | * Did some cleanup and added BB_USE_xxx_ENTRIES... | ||
22 | * | ||
17 | * Based almost entirely on the Linux modutils-2.3.11 implementation. | 23 | * Based almost entirely on the Linux modutils-2.3.11 implementation. |
18 | * Copyright 1996, 1997 Linux International. | 24 | * Copyright 1996, 1997 Linux International. |
19 | * New implementation contributed by Richard Henderson <rth@tamu.edu> | 25 | * New implementation contributed by Richard Henderson <rth@tamu.edu> |
@@ -52,6 +58,28 @@ | |||
52 | #include <linux/unistd.h> | 58 | #include <linux/unistd.h> |
53 | #include "busybox.h" | 59 | #include "busybox.h" |
54 | 60 | ||
61 | #if defined(__powerpc__) | ||
62 | #define BB_USE_PLT_ENTRIES | ||
63 | #define BB_PLT_ENTRY_SIZE 16 | ||
64 | #endif | ||
65 | |||
66 | #if defined(__arm__) | ||
67 | #define BB_USE_PLT_ENTRIES | ||
68 | #define BB_PLT_ENTRY_SIZE 8 | ||
69 | #define BB_USE_GOT_ENTRIES | ||
70 | #define BB_GOT_ENTRY_SIZE 8 | ||
71 | #endif | ||
72 | |||
73 | #if defined(__sh__) | ||
74 | #define BB_USE_GOT_ENTRIES | ||
75 | #define BB_GOT_ENTRY_SIZE 4 | ||
76 | #endif | ||
77 | |||
78 | #if defined(__i386__) | ||
79 | #define BB_USE_GOT_ENTRIES | ||
80 | #define BB_GOT_ENTRY_SIZE 4 | ||
81 | #endif | ||
82 | |||
55 | //---------------------------------------------------------------------------- | 83 | //---------------------------------------------------------------------------- |
56 | //--------modutils module.h, lines 45-242 | 84 | //--------modutils module.h, lines 45-242 |
57 | //---------------------------------------------------------------------------- | 85 | //---------------------------------------------------------------------------- |
@@ -81,7 +109,7 @@ | |||
81 | #ifndef MODUTILS_MODULE_H | 109 | #ifndef MODUTILS_MODULE_H |
82 | static const int MODUTILS_MODULE_H = 1; | 110 | static const int MODUTILS_MODULE_H = 1; |
83 | 111 | ||
84 | #ident "$Id: insmod.c,v 1.48 2001/02/20 06:14:07 andersen Exp $" | 112 | #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" |
85 | 113 | ||
86 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | 114 | /* This file contains the structures used by the 2.0 and 2.1 kernels. |
87 | We do not use the kernel headers directly because we do not wish | 115 | We do not use the kernel headers directly because we do not wish |
@@ -287,7 +315,7 @@ int delete_module(const char *); | |||
287 | #ifndef MODUTILS_OBJ_H | 315 | #ifndef MODUTILS_OBJ_H |
288 | static const int MODUTILS_OBJ_H = 1; | 316 | static const int MODUTILS_OBJ_H = 1; |
289 | 317 | ||
290 | #ident "$Id: insmod.c,v 1.48 2001/02/20 06:14:07 andersen Exp $" | 318 | #ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" |
291 | 319 | ||
292 | /* The relocatable object is manipulated using elfin types. */ | 320 | /* The relocatable object is manipulated using elfin types. */ |
293 | 321 | ||
@@ -311,21 +339,27 @@ static const int MODUTILS_OBJ_H = 1; | |||
311 | #endif | 339 | #endif |
312 | 340 | ||
313 | #define ELFCLASSM ELFCLASS32 | 341 | #define ELFCLASSM ELFCLASS32 |
314 | #define ELFDATAM ELFDATA2LSB | ||
315 | |||
316 | |||
317 | 342 | ||
318 | #if defined(__sh__) | 343 | #if defined(__sh__) |
319 | 344 | ||
320 | #define MATCH_MACHINE(x) (x == EM_SH) | 345 | #define MATCH_MACHINE(x) (x == EM_SH) |
321 | #define SHT_RELM SHT_RELA | 346 | #define SHT_RELM SHT_RELA |
322 | #define Elf32_RelM Elf32_Rela | 347 | #define Elf32_RelM Elf32_Rela |
348 | #define ELFDATAM ELFDATA2LSB | ||
323 | 349 | ||
324 | #elif defined(__arm__) | 350 | #elif defined(__arm__) |
325 | 351 | ||
326 | #define MATCH_MACHINE(x) (x == EM_ARM) | 352 | #define MATCH_MACHINE(x) (x == EM_ARM) |
327 | #define SHT_RELM SHT_REL | 353 | #define SHT_RELM SHT_REL |
328 | #define Elf32_RelM Elf32_Rel | 354 | #define Elf32_RelM Elf32_Rel |
355 | #define ELFDATAM ELFDATA2LSB | ||
356 | |||
357 | #elif defined(__powerpc__) | ||
358 | |||
359 | #define MATCH_MACHINE(x) (x == EM_PPC) | ||
360 | #define SHT_RELM SHT_RELA | ||
361 | #define Elf32_RelM Elf32_Rela | ||
362 | #define ELFDATAM ELFDATA2MSB | ||
329 | 363 | ||
330 | #elif defined(__i386__) | 364 | #elif defined(__i386__) |
331 | 365 | ||
@@ -340,6 +374,7 @@ static const int MODUTILS_OBJ_H = 1; | |||
340 | 374 | ||
341 | #define SHT_RELM SHT_REL | 375 | #define SHT_RELM SHT_REL |
342 | #define Elf32_RelM Elf32_Rel | 376 | #define Elf32_RelM Elf32_Rel |
377 | #define ELFDATAM ELFDATA2LSB | ||
343 | 378 | ||
344 | #else | 379 | #else |
345 | #error Sorry, but insmod.c does not yet support this architecture... | 380 | #error Sorry, but insmod.c does not yet support this architecture... |
@@ -540,8 +575,10 @@ int flag_export = 1; | |||
540 | 575 | ||
541 | /* Done ;-) */ | 576 | /* Done ;-) */ |
542 | 577 | ||
543 | #if defined(__arm__) | 578 | |
544 | struct arm_plt_entry | 579 | |
580 | #if defined(BB_USE_PLT_ENTRIES) | ||
581 | struct arch_plt_entry | ||
545 | { | 582 | { |
546 | int offset; | 583 | int offset; |
547 | int allocated:1; | 584 | int allocated:1; |
@@ -549,26 +586,32 @@ struct arm_plt_entry | |||
549 | }; | 586 | }; |
550 | #endif | 587 | #endif |
551 | 588 | ||
589 | #if defined(BB_USE_GOT_ENTRIES) | ||
552 | struct arch_got_entry { | 590 | struct arch_got_entry { |
553 | int offset; | 591 | int offset; |
554 | unsigned offset_done:1; | 592 | unsigned offset_done:1; |
555 | unsigned reloc_done:1; | 593 | unsigned reloc_done:1; |
556 | }; | 594 | }; |
595 | #endif | ||
557 | 596 | ||
558 | struct arch_file { | 597 | struct arch_file { |
559 | struct obj_file root; | 598 | struct obj_file root; |
560 | #if defined(__arm__) | 599 | #if defined(BB_USE_PLT_ENTRIES) |
561 | struct obj_section *plt; | 600 | struct obj_section *plt; |
562 | #endif | 601 | #endif |
602 | #if defined(BB_USE_GOT_ENTRIES) | ||
563 | struct obj_section *got; | 603 | struct obj_section *got; |
604 | #endif | ||
564 | }; | 605 | }; |
565 | 606 | ||
566 | struct arch_symbol { | 607 | struct arch_symbol { |
567 | struct obj_symbol root; | 608 | struct obj_symbol root; |
568 | #if defined(__arm__) | 609 | #if defined(BB_USE_PLT_ENTRIES) |
569 | struct arm_plt_entry pltent; | 610 | struct arch_plt_entry pltent; |
570 | #endif | 611 | #endif |
612 | #if defined(BB_USE_GOT_ENTRIES) | ||
571 | struct arch_got_entry gotent; | 613 | struct arch_got_entry gotent; |
614 | #endif | ||
572 | }; | 615 | }; |
573 | 616 | ||
574 | 617 | ||
@@ -618,7 +661,8 @@ extern int delete_module(const char *); | |||
618 | _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks) | 661 | _syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks) |
619 | #endif | 662 | #endif |
620 | 663 | ||
621 | #if defined(__i386__) || defined(__m68k__) || defined(__arm__) | 664 | #if defined(__i386__) || defined(__m68k__) || defined(__arm__) \ |
665 | || defined(__powerpc__) | ||
622 | /* Jump through hoops to fixup error return codes */ | 666 | /* Jump through hoops to fixup error return codes */ |
623 | #define __NR__create_module __NR_create_module | 667 | #define __NR__create_module __NR_create_module |
624 | static inline _syscall2(long, _create_module, const char *, name, size_t, | 668 | static inline _syscall2(long, _create_module, const char *, name, size_t, |
@@ -673,7 +717,14 @@ struct obj_file *arch_new_file(void) | |||
673 | { | 717 | { |
674 | struct arch_file *f; | 718 | struct arch_file *f; |
675 | f = xmalloc(sizeof(*f)); | 719 | f = xmalloc(sizeof(*f)); |
720 | |||
721 | #if defined(BB_USE_PLT_ENTRIES) | ||
722 | f->plt = NULL; | ||
723 | #endif | ||
724 | #if defined(BB_USE_GOT_ENTRIES) | ||
676 | f->got = NULL; | 725 | f->got = NULL; |
726 | #endif | ||
727 | |||
677 | return &f->root; | 728 | return &f->root; |
678 | } | 729 | } |
679 | 730 | ||
@@ -686,7 +737,14 @@ struct obj_symbol *arch_new_symbol(void) | |||
686 | { | 737 | { |
687 | struct arch_symbol *sym; | 738 | struct arch_symbol *sym; |
688 | sym = xmalloc(sizeof(*sym)); | 739 | sym = xmalloc(sizeof(*sym)); |
740 | |||
741 | #if defined(BB_USE_PLT_ENTRIES) | ||
742 | memset(&sym->pltent, 0, sizeof(sym->pltent)); | ||
743 | #endif | ||
744 | #if defined(BB_USE_GOT_ENTRIES) | ||
689 | memset(&sym->gotent, 0, sizeof(sym->gotent)); | 745 | memset(&sym->gotent, 0, sizeof(sym->gotent)); |
746 | #endif | ||
747 | |||
690 | return &sym->root; | 748 | return &sym->root; |
691 | } | 749 | } |
692 | 750 | ||
@@ -702,14 +760,14 @@ arch_apply_relocation(struct obj_file *f, | |||
702 | 760 | ||
703 | ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); | 761 | ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); |
704 | ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; | 762 | ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; |
763 | #if defined(BB_USE_GOT_ENTRIES) | ||
705 | ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; | 764 | ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; |
706 | #if defined(__arm__) | 765 | #endif |
766 | #if defined(BB_USE_PLT_ENTRIES) | ||
707 | ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; | 767 | ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; |
708 | 768 | struct arch_plt_entry *pe; | |
709 | struct arm_plt_entry *pe; | ||
710 | unsigned long *ip; | 769 | unsigned long *ip; |
711 | #endif | 770 | #endif |
712 | |||
713 | enum obj_reloc ret = obj_reloc_ok; | 771 | enum obj_reloc ret = obj_reloc_ok; |
714 | 772 | ||
715 | switch (ELF32_R_TYPE(rel->r_info)) { | 773 | switch (ELF32_R_TYPE(rel->r_info)) { |
@@ -723,6 +781,8 @@ arch_apply_relocation(struct obj_file *f, | |||
723 | case R_ARM_NONE: | 781 | case R_ARM_NONE: |
724 | #elif defined(__i386__) | 782 | #elif defined(__i386__) |
725 | case R_386_NONE: | 783 | case R_386_NONE: |
784 | #elif defined(__powerpc__) | ||
785 | case R_PPC_NONE: | ||
726 | #endif | 786 | #endif |
727 | break; | 787 | break; |
728 | 788 | ||
@@ -731,11 +791,27 @@ arch_apply_relocation(struct obj_file *f, | |||
731 | #elif defined(__arm__) | 791 | #elif defined(__arm__) |
732 | case R_ARM_ABS32: | 792 | case R_ARM_ABS32: |
733 | #elif defined(__i386__) | 793 | #elif defined(__i386__) |
734 | case R_386_32: | 794 | case R_386_32: |
795 | #elif defined(__powerpc__) | ||
796 | case R_PPC_ADDR32: | ||
735 | #endif | 797 | #endif |
736 | *loc += v; | 798 | *loc += v; |
737 | break; | 799 | break; |
738 | 800 | ||
801 | #if defined(__powerpc__) | ||
802 | case R_PPC_ADDR16_HA: | ||
803 | *(unsigned short *)loc = (v + 0x8000) >> 16; | ||
804 | break; | ||
805 | |||
806 | case R_PPC_ADDR16_HI: | ||
807 | *(unsigned short *)loc = v >> 16; | ||
808 | break; | ||
809 | |||
810 | case R_PPC_ADDR16_LO: | ||
811 | *(unsigned short *)loc = v; | ||
812 | break; | ||
813 | #endif | ||
814 | |||
739 | #if defined(__arm__) | 815 | #if defined(__arm__) |
740 | #elif defined(__sh__) | 816 | #elif defined(__sh__) |
741 | case R_SH_REL32: | 817 | case R_SH_REL32: |
@@ -746,22 +822,48 @@ arch_apply_relocation(struct obj_file *f, | |||
746 | case R_386_PC32: | 822 | case R_386_PC32: |
747 | *loc += v - dot; | 823 | *loc += v - dot; |
748 | break; | 824 | break; |
825 | #elif defined(__powerpc__) | ||
826 | case R_PPC_REL32: | ||
827 | *loc = v - dot; | ||
828 | break; | ||
749 | #endif | 829 | #endif |
750 | 830 | ||
751 | #if defined(__sh__) | 831 | #if defined(__sh__) |
752 | case R_SH_PLT32: | 832 | case R_SH_PLT32: |
753 | *loc = v - dot; | 833 | *loc = v - dot; |
754 | break; | 834 | break; |
755 | #elif defined(__arm__) | 835 | #elif defined(__i386__) |
836 | #endif | ||
837 | |||
838 | #if defined(BB_USE_PLT_ENTRIES) | ||
839 | |||
840 | #if defined(__arm__) | ||
756 | case R_ARM_PC24: | 841 | case R_ARM_PC24: |
757 | case R_ARM_PLT32: | 842 | case R_ARM_PLT32: |
843 | #endif | ||
844 | #if defined(__powerpc__) | ||
845 | case R_PPC_REL24: | ||
846 | #endif | ||
758 | /* find the plt entry and initialize it if necessary */ | 847 | /* find the plt entry and initialize it if necessary */ |
759 | assert(isym != NULL); | 848 | assert(isym != NULL); |
760 | pe = (struct arm_plt_entry*) &isym->pltent; | 849 | |
850 | pe = (struct arch_plt_entry*) &isym->pltent; | ||
851 | |||
761 | if (! pe->inited) { | 852 | if (! pe->inited) { |
762 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); | 853 | ip = (unsigned long *) (ifile->plt->contents + pe->offset); |
854 | |||
855 | /* generate some machine code */ | ||
856 | |||
857 | #if defined(__arm__) | ||
763 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ | 858 | ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ |
764 | ip[1] = v; /* sym@ */ | 859 | ip[1] = v; /* sym@ */ |
860 | #endif | ||
861 | #if defined(__powerpc__) | ||
862 | ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ | ||
863 | ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ | ||
864 | ip[2] = 0x7d6903a6; /* mtctr r11 */ | ||
865 | ip[3] = 0x4e800420; /* bctr */ | ||
866 | #endif | ||
765 | pe->inited = 1; | 867 | pe->inited = 1; |
766 | } | 868 | } |
767 | 869 | ||
@@ -775,15 +877,18 @@ arch_apply_relocation(struct obj_file *f, | |||
775 | if (v & 3) | 877 | if (v & 3) |
776 | ret = obj_reloc_dangerous; | 878 | ret = obj_reloc_dangerous; |
777 | 879 | ||
880 | /* merge the offset into the instruction. */ | ||
881 | #if defined(__arm__) | ||
778 | /* Convert to words. */ | 882 | /* Convert to words. */ |
779 | v >>= 2; | 883 | v >>= 2; |
780 | 884 | ||
781 | /* merge the offset into the instruction. */ | ||
782 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); | 885 | *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); |
783 | break; | ||
784 | #elif defined(__i386__) | ||
785 | #endif | 886 | #endif |
786 | 887 | #if defined(__powerpc__) | |
888 | *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); | ||
889 | #endif | ||
890 | break; | ||
891 | #endif /* BB_USE_PLT_ENTRIES */ | ||
787 | 892 | ||
788 | #if defined(__arm__) | 893 | #if defined(__arm__) |
789 | #elif defined(__sh__) | 894 | #elif defined(__sh__) |
@@ -809,6 +914,8 @@ arch_apply_relocation(struct obj_file *f, | |||
809 | break; | 914 | break; |
810 | #endif | 915 | #endif |
811 | 916 | ||
917 | #if defined(BB_USE_GOT_ENTRIES) | ||
918 | |||
812 | #if defined(__sh__) | 919 | #if defined(__sh__) |
813 | case R_SH_GOTPC: | 920 | case R_SH_GOTPC: |
814 | #elif defined(__arm__) | 921 | #elif defined(__arm__) |
@@ -827,7 +934,7 @@ arch_apply_relocation(struct obj_file *f, | |||
827 | #if defined(__sh__) | 934 | #if defined(__sh__) |
828 | case R_SH_GOT32: | 935 | case R_SH_GOT32: |
829 | #elif defined(__arm__) | 936 | #elif defined(__arm__) |
830 | case R_ARM_GOT32: | 937 | case R_ARM_GOT32: |
831 | #elif defined(__i386__) | 938 | #elif defined(__i386__) |
832 | case R_386_GOT32: | 939 | case R_386_GOT32: |
833 | #endif | 940 | #endif |
@@ -849,7 +956,7 @@ arch_apply_relocation(struct obj_file *f, | |||
849 | #if defined(__sh__) | 956 | #if defined(__sh__) |
850 | case R_SH_GOTOFF: | 957 | case R_SH_GOTOFF: |
851 | #elif defined(__arm__) | 958 | #elif defined(__arm__) |
852 | case R_ARM_GOTOFF: | 959 | case R_ARM_GOTOFF: |
853 | #elif defined(__i386__) | 960 | #elif defined(__i386__) |
854 | case R_386_GOTOFF: | 961 | case R_386_GOTOFF: |
855 | #endif | 962 | #endif |
@@ -857,6 +964,8 @@ arch_apply_relocation(struct obj_file *f, | |||
857 | *loc += v - got; | 964 | *loc += v - got; |
858 | break; | 965 | break; |
859 | 966 | ||
967 | #endif /* BB_USE_GOT_ENTRIES */ | ||
968 | |||
860 | default: | 969 | default: |
861 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); | 970 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); |
862 | ret = obj_reloc_unhandled; | 971 | ret = obj_reloc_unhandled; |
@@ -869,8 +978,11 @@ arch_apply_relocation(struct obj_file *f, | |||
869 | int arch_create_got(struct obj_file *f) | 978 | int arch_create_got(struct obj_file *f) |
870 | { | 979 | { |
871 | struct arch_file *ifile = (struct arch_file *) f; | 980 | struct arch_file *ifile = (struct arch_file *) f; |
872 | int i, got_offset = 0, gotneeded = 0; | 981 | int i; |
873 | #if defined(__arm__) | 982 | #if defined(BB_USE_GOT_ENTRIES) |
983 | int got_offset = 0, gotneeded = 0; | ||
984 | #endif | ||
985 | #if defined(BB_USE_PLT_ENTRIES) | ||
874 | int plt_offset = 0, pltneeded = 0; | 986 | int plt_offset = 0, pltneeded = 0; |
875 | #endif | 987 | #endif |
876 | struct obj_section *relsec, *symsec, *strsec; | 988 | struct obj_section *relsec, *symsec, *strsec; |
@@ -898,12 +1010,20 @@ int arch_create_got(struct obj_file *f) | |||
898 | switch (ELF32_R_TYPE(rel->r_info)) { | 1010 | switch (ELF32_R_TYPE(rel->r_info)) { |
899 | #if defined(__arm__) | 1011 | #if defined(__arm__) |
900 | case R_ARM_GOT32: | 1012 | case R_ARM_GOT32: |
1013 | break; | ||
901 | #elif defined(__sh__) | 1014 | #elif defined(__sh__) |
902 | case R_SH_GOT32: | 1015 | case R_SH_GOT32: |
1016 | break; | ||
903 | #elif defined(__i386__) | 1017 | #elif defined(__i386__) |
904 | case R_386_GOT32: | 1018 | case R_386_GOT32: |
1019 | break; | ||
905 | #endif | 1020 | #endif |
1021 | |||
1022 | #if defined(__powerpc__) | ||
1023 | case R_PPC_REL24: | ||
1024 | pltneeded = 1; | ||
906 | break; | 1025 | break; |
1026 | #endif | ||
907 | 1027 | ||
908 | #if defined(__arm__) | 1028 | #if defined(__arm__) |
909 | case R_ARM_PC24: | 1029 | case R_ARM_PC24: |
@@ -936,17 +1056,18 @@ int arch_create_got(struct obj_file *f) | |||
936 | name = f->sections[extsym->st_shndx]->name; | 1056 | name = f->sections[extsym->st_shndx]->name; |
937 | } | 1057 | } |
938 | intsym = (struct arch_symbol *) obj_find_symbol(f, name); | 1058 | intsym = (struct arch_symbol *) obj_find_symbol(f, name); |
939 | 1059 | #if defined(BB_USE_GOT_ENTRIES) | |
940 | if (!intsym->gotent.offset_done) { | 1060 | if (!intsym->gotent.offset_done) { |
941 | intsym->gotent.offset_done = 1; | 1061 | intsym->gotent.offset_done = 1; |
942 | intsym->gotent.offset = got_offset; | 1062 | intsym->gotent.offset = got_offset; |
943 | got_offset += 4; | 1063 | got_offset += BB_GOT_ENTRY_SIZE; |
944 | } | 1064 | } |
945 | #if defined(__arm__) | 1065 | #endif |
1066 | #if defined(BB_USE_PLT_ENTRIES) | ||
946 | if (pltneeded && intsym->pltent.allocated == 0) { | 1067 | if (pltneeded && intsym->pltent.allocated == 0) { |
947 | intsym->pltent.allocated = 1; | 1068 | intsym->pltent.allocated = 1; |
948 | intsym->pltent.offset = plt_offset; | 1069 | intsym->pltent.offset = plt_offset; |
949 | plt_offset += 8; | 1070 | plt_offset += BB_PLT_ENTRY_SIZE; |
950 | intsym->pltent.inited = 0; | 1071 | intsym->pltent.inited = 0; |
951 | pltneeded = 0; | 1072 | pltneeded = 0; |
952 | } | 1073 | } |
@@ -954,27 +1075,29 @@ int arch_create_got(struct obj_file *f) | |||
954 | } | 1075 | } |
955 | } | 1076 | } |
956 | 1077 | ||
957 | #if defined(__arm__) | 1078 | #if defined(BB_USE_GOT_ENTRIES) |
958 | if (got_offset) { | 1079 | if (got_offset) { |
959 | struct obj_section* relsec = obj_find_section(f, ".got"); | 1080 | struct obj_section* relsec = obj_find_section(f, ".got"); |
960 | 1081 | ||
961 | if (relsec) { | 1082 | if (relsec) { |
962 | obj_extend_section(relsec, got_offset); | 1083 | obj_extend_section(relsec, got_offset); |
963 | } else { | 1084 | } else { |
964 | relsec = obj_create_alloced_section(f, ".got", 8, got_offset); | 1085 | relsec = obj_create_alloced_section(f, ".got", |
1086 | BB_GOT_ENTRY_SIZE, | ||
1087 | got_offset); | ||
965 | assert(relsec); | 1088 | assert(relsec); |
966 | } | 1089 | } |
967 | 1090 | ||
968 | ifile->got = relsec; | 1091 | ifile->got = relsec; |
969 | } | 1092 | } |
1093 | #endif | ||
970 | 1094 | ||
1095 | #if defined(BB_USE_PLT_ENTRIES) | ||
971 | if (plt_offset) | 1096 | if (plt_offset) |
972 | ifile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset); | 1097 | ifile->plt = obj_create_alloced_section(f, ".plt", |
973 | #else | 1098 | BB_PLT_ENTRY_SIZE, |
974 | if (got_offset > 0 || gotneeded) | 1099 | plt_offset); |
975 | ifile->got = obj_create_alloced_section(f, ".got", 4, got_offset); | ||
976 | #endif | 1100 | #endif |
977 | |||
978 | return 1; | 1101 | return 1; |
979 | } | 1102 | } |
980 | 1103 | ||