| 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 |