diff options
| author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-02-20 20:47:08 +0000 |
|---|---|---|
| committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-02-20 20:47:08 +0000 |
| commit | 90c8e96ef462ddb2f558180fb42b4b5e603870c5 (patch) | |
| tree | 880d32c3fe6684570da9eaedd0e1f86437c329b3 /modutils | |
| parent | ab9dcd3b6b30f1e4833189f8c413b6d1e5aef71e (diff) | |
| download | busybox-w32-90c8e96ef462ddb2f558180fb42b4b5e603870c5.tar.gz busybox-w32-90c8e96ef462ddb2f558180fb42b4b5e603870c5.tar.bz2 busybox-w32-90c8e96ef462ddb2f558180fb42b4b5e603870c5.zip | |
Apply a patch from Magnus Damm <damm@opensource.se> to support
powerpc with busybox insmod
-Erik
git-svn-id: svn://busybox.net/trunk/busybox@1870 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'modutils')
| -rw-r--r-- | modutils/insmod.c | 199 |
1 files changed, 161 insertions, 38 deletions
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 | ||
