OLD | NEW |
1 // powerpc.cc -- powerpc target support for gold. | 1 // powerpc.cc -- powerpc target support for gold. |
2 | 2 |
3 // Copyright 2008, 2009 Free Software Foundation, Inc. | 3 // Copyright 2008, 2009 Free Software Foundation, Inc. |
4 // Written by David S. Miller <davem@davemloft.net> | 4 // Written by David S. Miller <davem@davemloft.net> |
5 // and David Edelsohn <edelsohn@gnu.org> | 5 // and David Edelsohn <edelsohn@gnu.org> |
6 | 6 |
7 // This file is part of gold. | 7 // This file is part of gold. |
8 | 8 |
9 // This program is free software; you can redistribute it and/or modify | 9 // This program is free software; you can redistribute it and/or modify |
10 // it under the terms of the GNU General Public License as published by | 10 // it under the terms of the GNU General Public License as published by |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 Layout* layout) | 706 Layout* layout) |
707 { | 707 { |
708 if (this->got_ == NULL) | 708 if (this->got_ == NULL) |
709 { | 709 { |
710 gold_assert(symtab != NULL && layout != NULL); | 710 gold_assert(symtab != NULL && layout != NULL); |
711 | 711 |
712 this->got_ = new Output_data_got<size, big_endian>(); | 712 this->got_ = new Output_data_got<size, big_endian>(); |
713 | 713 |
714 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, | 714 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, |
715 elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, | 715 elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, |
716 » » » » this->got_); | 716 » » » » this->got_, false); |
717 | 717 |
718 // Create the GOT2 or TOC in the .got section. | 718 // Create the GOT2 or TOC in the .got section. |
719 if (size == 32) | 719 if (size == 32) |
720 { | 720 { |
721 this->got2_ = new Output_data_space(4, "** GOT2"); | 721 this->got2_ = new Output_data_space(4, "** GOT2"); |
722 layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS, | 722 layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS, |
723 elfcpp::SHF_ALLOC | 723 elfcpp::SHF_ALLOC |
724 | elfcpp::SHF_WRITE, | 724 | elfcpp::SHF_WRITE, |
725 » » » » » this->got2_); | 725 » » » » » this->got2_, false); |
726 } | 726 } |
727 else | 727 else |
728 { | 728 { |
729 this->toc_ = new Output_data_space(8, "** TOC"); | 729 this->toc_ = new Output_data_space(8, "** TOC"); |
730 layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS, | 730 layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS, |
731 elfcpp::SHF_ALLOC | 731 elfcpp::SHF_ALLOC |
732 | elfcpp::SHF_WRITE, | 732 | elfcpp::SHF_WRITE, |
733 » » » » » this->toc_); | 733 » » » » » this->toc_, false); |
734 } | 734 } |
735 | 735 |
736 // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. | 736 // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. |
737 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, | 737 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, |
738 this->got_, | 738 this->got_, |
739 0, 0, elfcpp::STT_OBJECT, | 739 0, 0, elfcpp::STT_OBJECT, |
740 elfcpp::STB_LOCAL, | 740 elfcpp::STB_LOCAL, |
741 elfcpp::STV_HIDDEN, 0, | 741 elfcpp::STV_HIDDEN, 0, |
742 false, false); | 742 false, false); |
743 } | 743 } |
744 | 744 |
745 return this->got_; | 745 return this->got_; |
746 } | 746 } |
747 | 747 |
748 // Get the dynamic reloc section, creating it if necessary. | 748 // Get the dynamic reloc section, creating it if necessary. |
749 | 749 |
750 template<int size, bool big_endian> | 750 template<int size, bool big_endian> |
751 typename Target_powerpc<size, big_endian>::Reloc_section* | 751 typename Target_powerpc<size, big_endian>::Reloc_section* |
752 Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout) | 752 Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout) |
753 { | 753 { |
754 if (this->rela_dyn_ == NULL) | 754 if (this->rela_dyn_ == NULL) |
755 { | 755 { |
756 gold_assert(layout != NULL); | 756 gold_assert(layout != NULL); |
757 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); | 757 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); |
758 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, | 758 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, |
759 » » » » elfcpp::SHF_ALLOC, this->rela_dyn_); | 759 » » » » elfcpp::SHF_ALLOC, this->rela_dyn_, true); |
760 } | 760 } |
761 return this->rela_dyn_; | 761 return this->rela_dyn_; |
762 } | 762 } |
763 | 763 |
764 // A class to handle the PLT data. | 764 // A class to handle the PLT data. |
765 | 765 |
766 template<int size, bool big_endian> | 766 template<int size, bool big_endian> |
767 class Output_data_plt_powerpc : public Output_section_data | 767 class Output_data_plt_powerpc : public Output_section_data |
768 { | 768 { |
769 public: | 769 public: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 | 809 |
810 // Create the PLT section. The ordinary .got section is an argument, | 810 // Create the PLT section. The ordinary .got section is an argument, |
811 // since we need to refer to the start. | 811 // since we need to refer to the start. |
812 | 812 |
813 template<int size, bool big_endian> | 813 template<int size, bool big_endian> |
814 Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layou
t) | 814 Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layou
t) |
815 : Output_section_data(size == 32 ? 4 : 8), count_(0) | 815 : Output_section_data(size == 32 ? 4 : 8), count_(0) |
816 { | 816 { |
817 this->rel_ = new Reloc_section(false); | 817 this->rel_ = new Reloc_section(false); |
818 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, | 818 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, |
819 » » » » elfcpp::SHF_ALLOC, this->rel_); | 819 » » » » elfcpp::SHF_ALLOC, this->rel_, true); |
820 } | 820 } |
821 | 821 |
822 template<int size, bool big_endian> | 822 template<int size, bool big_endian> |
823 void | 823 void |
824 Output_data_plt_powerpc<size, big_endian>::do_adjust_output_section(Output_secti
on* os) | 824 Output_data_plt_powerpc<size, big_endian>::do_adjust_output_section(Output_secti
on* os) |
825 { | 825 { |
826 os->set_entsize(0); | 826 os->set_entsize(0); |
827 } | 827 } |
828 | 828 |
829 // Add an entry to the PLT. | 829 // Add an entry to the PLT. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 if (this->plt_ == NULL) | 938 if (this->plt_ == NULL) |
939 { | 939 { |
940 // Create the GOT section first. | 940 // Create the GOT section first. |
941 this->got_section(symtab, layout); | 941 this->got_section(symtab, layout); |
942 | 942 |
943 this->plt_ = new Output_data_plt_powerpc<size, big_endian>(layout); | 943 this->plt_ = new Output_data_plt_powerpc<size, big_endian>(layout); |
944 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, | 944 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, |
945 (elfcpp::SHF_ALLOC | 945 (elfcpp::SHF_ALLOC |
946 | elfcpp::SHF_EXECINSTR | 946 | elfcpp::SHF_EXECINSTR |
947 | elfcpp::SHF_WRITE), | 947 | elfcpp::SHF_WRITE), |
948 » » » » this->plt_); | 948 » » » » this->plt_, false); |
949 | 949 |
950 // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. | 950 // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. |
951 symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, | 951 symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, |
952 this->plt_, | 952 this->plt_, |
953 0, 0, elfcpp::STT_OBJECT, | 953 0, 0, elfcpp::STT_OBJECT, |
954 elfcpp::STB_LOCAL, | 954 elfcpp::STB_LOCAL, |
955 elfcpp::STV_HIDDEN, 0, | 955 elfcpp::STV_HIDDEN, 0, |
956 false, false); | 956 false, false); |
957 } | 957 } |
958 | 958 |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 } | 1505 } |
1506 | 1506 |
1507 // Define _SDA_BASE_ at the start of the .sdata section. | 1507 // Define _SDA_BASE_ at the start of the .sdata section. |
1508 if (sdata == NULL) | 1508 if (sdata == NULL) |
1509 { | 1509 { |
1510 // layout->find_output_section(".sdata") == NULL | 1510 // layout->find_output_section(".sdata") == NULL |
1511 sdata = new Output_data_space(4, "** sdata"); | 1511 sdata = new Output_data_space(4, "** sdata"); |
1512 Output_section* os = layout->add_output_section_data(".sdata", 0, | 1512 Output_section* os = layout->add_output_section_data(".sdata", 0, |
1513 elfcpp::SHF_ALLOC | 1513 elfcpp::SHF_ALLOC |
1514 | elfcpp::SHF_WRITE, | 1514 | elfcpp::SHF_WRITE, |
1515 » » » » » » » sdata); | 1515 » » » » » » » sdata, false); |
1516 symtab->define_in_output_data("_SDA_BASE_", NULL, | 1516 symtab->define_in_output_data("_SDA_BASE_", NULL, |
1517 os, | 1517 os, |
1518 32768, 0, | 1518 32768, 0, |
1519 elfcpp::STT_OBJECT, | 1519 elfcpp::STT_OBJECT, |
1520 elfcpp::STB_LOCAL, | 1520 elfcpp::STB_LOCAL, |
1521 elfcpp::STV_HIDDEN, 0, | 1521 elfcpp::STV_HIDDEN, 0, |
1522 false, false); | 1522 false, false); |
1523 } | 1523 } |
1524 | 1524 |
1525 gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>( | 1525 gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>( |
(...skipping 14 matching lines...) Expand all Loading... |
1540 // Finalize the sections. | 1540 // Finalize the sections. |
1541 | 1541 |
1542 template<int size, bool big_endian> | 1542 template<int size, bool big_endian> |
1543 void | 1543 void |
1544 Target_powerpc<size, big_endian>::do_finalize_sections(Layout* layout) | 1544 Target_powerpc<size, big_endian>::do_finalize_sections(Layout* layout) |
1545 { | 1545 { |
1546 // Fill in some more dynamic tags. | 1546 // Fill in some more dynamic tags. |
1547 Output_data_dynamic* const odyn = layout->dynamic_data(); | 1547 Output_data_dynamic* const odyn = layout->dynamic_data(); |
1548 if (odyn != NULL) | 1548 if (odyn != NULL) |
1549 { | 1549 { |
1550 if (this->plt_ != NULL) | 1550 if (this->plt_ != NULL |
| 1551 » && this->plt_->output_section() != NULL) |
1551 { | 1552 { |
1552 const Output_data* od = this->plt_->rel_plt(); | 1553 const Output_data* od = this->plt_->rel_plt(); |
1553 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); | 1554 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); |
1554 odyn->add_section_address(elfcpp::DT_JMPREL, od); | 1555 odyn->add_section_address(elfcpp::DT_JMPREL, od); |
1555 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA); | 1556 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA); |
1556 | 1557 |
1557 odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_); | 1558 odyn->add_section_address(elfcpp::DT_PLTGOT, this->plt_); |
1558 } | 1559 } |
1559 | 1560 |
1560 if (this->rela_dyn_ != NULL) | 1561 if (this->rela_dyn_ != NULL |
| 1562 » && this->rela_dyn_->output_section() != NULL) |
1561 { | 1563 { |
1562 const Output_data* od = this->rela_dyn_; | 1564 const Output_data* od = this->rela_dyn_; |
1563 odyn->add_section_address(elfcpp::DT_RELA, od); | 1565 odyn->add_section_address(elfcpp::DT_RELA, od); |
1564 odyn->add_section_size(elfcpp::DT_RELASZ, od); | 1566 odyn->add_section_size(elfcpp::DT_RELASZ, od); |
1565 odyn->add_constant(elfcpp::DT_RELAENT, | 1567 odyn->add_constant(elfcpp::DT_RELAENT, |
1566 elfcpp::Elf_sizes<size>::rela_size); | 1568 elfcpp::Elf_sizes<size>::rela_size); |
1567 } | 1569 } |
1568 | 1570 |
1569 if (!parameters->options().shared()) | 1571 if (!parameters->options().shared()) |
1570 { | 1572 { |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 Target* do_instantiate_target() | 2018 Target* do_instantiate_target() |
2017 { return new Target_powerpc<size, big_endian>(); } | 2019 { return new Target_powerpc<size, big_endian>(); } |
2018 }; | 2020 }; |
2019 | 2021 |
2020 Target_selector_powerpc<32, true> target_selector_ppc32; | 2022 Target_selector_powerpc<32, true> target_selector_ppc32; |
2021 Target_selector_powerpc<32, false> target_selector_ppc32le; | 2023 Target_selector_powerpc<32, false> target_selector_ppc32le; |
2022 Target_selector_powerpc<64, true> target_selector_ppc64; | 2024 Target_selector_powerpc<64, true> target_selector_ppc64; |
2023 Target_selector_powerpc<64, false> target_selector_ppc64le; | 2025 Target_selector_powerpc<64, false> target_selector_ppc64le; |
2024 | 2026 |
2025 } // End anonymous namespace. | 2027 } // End anonymous namespace. |
OLD | NEW |