| OLD | NEW |
| 1 // arm.cc -- arm target support for gold. | 1 // arm.cc -- arm target support for gold. |
| 2 | 2 |
| 3 // Copyright 2009 Free Software Foundation, Inc. | 3 // Copyright 2009 Free Software Foundation, Inc. |
| 4 // Written by Doug Kwan <dougkwan@google.com> based on the i386 code | 4 // Written by Doug Kwan <dougkwan@google.com> based on the i386 code |
| 5 // by Ian Lance Taylor <iant@google.com>. | 5 // by Ian Lance Taylor <iant@google.com>. |
| 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 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 if (this->got_ == NULL) | 1068 if (this->got_ == NULL) |
| 1069 { | 1069 { |
| 1070 gold_assert(symtab != NULL && layout != NULL); | 1070 gold_assert(symtab != NULL && layout != NULL); |
| 1071 | 1071 |
| 1072 this->got_ = new Output_data_got<32, big_endian>(); | 1072 this->got_ = new Output_data_got<32, big_endian>(); |
| 1073 | 1073 |
| 1074 Output_section* os; | 1074 Output_section* os; |
| 1075 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, | 1075 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, |
| 1076 (elfcpp::SHF_ALLOC | 1076 (elfcpp::SHF_ALLOC |
| 1077 | elfcpp::SHF_WRITE), | 1077 | elfcpp::SHF_WRITE), |
| 1078 » » » » » this->got_); | 1078 » » » » » this->got_, false); |
| 1079 os->set_is_relro(); | 1079 os->set_is_relro(); |
| 1080 | 1080 |
| 1081 // The old GNU linker creates a .got.plt section. We just | 1081 // The old GNU linker creates a .got.plt section. We just |
| 1082 // create another set of data in the .got section. Note that we | 1082 // create another set of data in the .got section. Note that we |
| 1083 // always create a PLT if we create a GOT, although the PLT | 1083 // always create a PLT if we create a GOT, although the PLT |
| 1084 // might be empty. | 1084 // might be empty. |
| 1085 this->got_plt_ = new Output_data_space(4, "** GOT PLT"); | 1085 this->got_plt_ = new Output_data_space(4, "** GOT PLT"); |
| 1086 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, | 1086 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, |
| 1087 (elfcpp::SHF_ALLOC | 1087 (elfcpp::SHF_ALLOC |
| 1088 | elfcpp::SHF_WRITE), | 1088 | elfcpp::SHF_WRITE), |
| 1089 » » » » » this->got_plt_); | 1089 » » » » » this->got_plt_, false); |
| 1090 os->set_is_relro(); | 1090 os->set_is_relro(); |
| 1091 | 1091 |
| 1092 // The first three entries are reserved. | 1092 // The first three entries are reserved. |
| 1093 this->got_plt_->set_current_data_size(3 * 4); | 1093 this->got_plt_->set_current_data_size(3 * 4); |
| 1094 | 1094 |
| 1095 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. | 1095 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. |
| 1096 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, | 1096 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, |
| 1097 this->got_plt_, | 1097 this->got_plt_, |
| 1098 0, 0, elfcpp::STT_OBJECT, | 1098 0, 0, elfcpp::STT_OBJECT, |
| 1099 elfcpp::STB_LOCAL, | 1099 elfcpp::STB_LOCAL, |
| 1100 elfcpp::STV_HIDDEN, 0, | 1100 elfcpp::STV_HIDDEN, 0, |
| 1101 false, false); | 1101 false, false); |
| 1102 } | 1102 } |
| 1103 return this->got_; | 1103 return this->got_; |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 // Get the dynamic reloc section, creating it if necessary. | 1106 // Get the dynamic reloc section, creating it if necessary. |
| 1107 | 1107 |
| 1108 template<bool big_endian> | 1108 template<bool big_endian> |
| 1109 typename Target_arm<big_endian>::Reloc_section* | 1109 typename Target_arm<big_endian>::Reloc_section* |
| 1110 Target_arm<big_endian>::rel_dyn_section(Layout* layout) | 1110 Target_arm<big_endian>::rel_dyn_section(Layout* layout) |
| 1111 { | 1111 { |
| 1112 if (this->rel_dyn_ == NULL) | 1112 if (this->rel_dyn_ == NULL) |
| 1113 { | 1113 { |
| 1114 gold_assert(layout != NULL); | 1114 gold_assert(layout != NULL); |
| 1115 this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); | 1115 this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); |
| 1116 layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, | 1116 layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, |
| 1117 » » » » elfcpp::SHF_ALLOC, this->rel_dyn_); | 1117 » » » » elfcpp::SHF_ALLOC, this->rel_dyn_, true); |
| 1118 } | 1118 } |
| 1119 return this->rel_dyn_; | 1119 return this->rel_dyn_; |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 // A class to handle the PLT data. | 1122 // A class to handle the PLT data. |
| 1123 | 1123 |
| 1124 template<bool big_endian> | 1124 template<bool big_endian> |
| 1125 class Output_data_plt_arm : public Output_section_data | 1125 class Output_data_plt_arm : public Output_section_data |
| 1126 { | 1126 { |
| 1127 public: | 1127 public: |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 // since we need to refer to the start. We also create our own .got | 1179 // since we need to refer to the start. We also create our own .got |
| 1180 // section just for PLT entries. | 1180 // section just for PLT entries. |
| 1181 | 1181 |
| 1182 template<bool big_endian> | 1182 template<bool big_endian> |
| 1183 Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout, | 1183 Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout, |
| 1184 Output_data_space* got_plt) | 1184 Output_data_space* got_plt) |
| 1185 : Output_section_data(4), got_plt_(got_plt), count_(0) | 1185 : Output_section_data(4), got_plt_(got_plt), count_(0) |
| 1186 { | 1186 { |
| 1187 this->rel_ = new Reloc_section(false); | 1187 this->rel_ = new Reloc_section(false); |
| 1188 layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, | 1188 layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, |
| 1189 » » » » elfcpp::SHF_ALLOC, this->rel_); | 1189 » » » » elfcpp::SHF_ALLOC, this->rel_, true); |
| 1190 } | 1190 } |
| 1191 | 1191 |
| 1192 template<bool big_endian> | 1192 template<bool big_endian> |
| 1193 void | 1193 void |
| 1194 Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os) | 1194 Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os) |
| 1195 { | 1195 { |
| 1196 os->set_entsize(0); | 1196 os->set_entsize(0); |
| 1197 } | 1197 } |
| 1198 | 1198 |
| 1199 // Add an entry to the PLT. | 1199 // Add an entry to the PLT. |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 | 1341 |
| 1342 if (this->plt_ == NULL) | 1342 if (this->plt_ == NULL) |
| 1343 { | 1343 { |
| 1344 // Create the GOT sections first. | 1344 // Create the GOT sections first. |
| 1345 this->got_section(symtab, layout); | 1345 this->got_section(symtab, layout); |
| 1346 | 1346 |
| 1347 this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_); | 1347 this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_); |
| 1348 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, | 1348 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, |
| 1349 (elfcpp::SHF_ALLOC | 1349 (elfcpp::SHF_ALLOC |
| 1350 | elfcpp::SHF_EXECINSTR), | 1350 | elfcpp::SHF_EXECINSTR), |
| 1351 » » » » this->plt_); | 1351 » » » » this->plt_, false); |
| 1352 } | 1352 } |
| 1353 this->plt_->add_entry(gsym); | 1353 this->plt_->add_entry(gsym); |
| 1354 } | 1354 } |
| 1355 | 1355 |
| 1356 // Report an unsupported relocation against a local symbol. | 1356 // Report an unsupported relocation against a local symbol. |
| 1357 | 1357 |
| 1358 template<bool big_endian> | 1358 template<bool big_endian> |
| 1359 void | 1359 void |
| 1360 Target_arm<big_endian>::Scan::unsupported_reloc_local( | 1360 Target_arm<big_endian>::Scan::unsupported_reloc_local( |
| 1361 Sized_relobj<32, big_endian>* object, | 1361 Sized_relobj<32, big_endian>* object, |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1824 // Finalize the sections. | 1824 // Finalize the sections. |
| 1825 | 1825 |
| 1826 template<bool big_endian> | 1826 template<bool big_endian> |
| 1827 void | 1827 void |
| 1828 Target_arm<big_endian>::do_finalize_sections(Layout* layout) | 1828 Target_arm<big_endian>::do_finalize_sections(Layout* layout) |
| 1829 { | 1829 { |
| 1830 // Fill in some more dynamic tags. | 1830 // Fill in some more dynamic tags. |
| 1831 Output_data_dynamic* const odyn = layout->dynamic_data(); | 1831 Output_data_dynamic* const odyn = layout->dynamic_data(); |
| 1832 if (odyn != NULL) | 1832 if (odyn != NULL) |
| 1833 { | 1833 { |
| 1834 if (this->got_plt_ != NULL) | 1834 if (this->got_plt_ != NULL |
| 1835 » && this->got_plt_->output_section() != NULL) |
| 1835 odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_); | 1836 odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_); |
| 1836 | 1837 |
| 1837 if (this->plt_ != NULL) | 1838 if (this->plt_ != NULL |
| 1839 » && this->plt_->output_section() != NULL) |
| 1838 { | 1840 { |
| 1839 const Output_data* od = this->plt_->rel_plt(); | 1841 const Output_data* od = this->plt_->rel_plt(); |
| 1840 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); | 1842 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); |
| 1841 odyn->add_section_address(elfcpp::DT_JMPREL, od); | 1843 odyn->add_section_address(elfcpp::DT_JMPREL, od); |
| 1842 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL); | 1844 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL); |
| 1843 } | 1845 } |
| 1844 | 1846 |
| 1845 if (this->rel_dyn_ != NULL) | 1847 if (this->rel_dyn_ != NULL |
| 1848 » && this->rel_dyn_->output_section() != NULL) |
| 1846 { | 1849 { |
| 1847 const Output_data* od = this->rel_dyn_; | 1850 const Output_data* od = this->rel_dyn_; |
| 1848 odyn->add_section_address(elfcpp::DT_REL, od); | 1851 odyn->add_section_address(elfcpp::DT_REL, od); |
| 1849 odyn->add_section_size(elfcpp::DT_RELSZ, od); | 1852 odyn->add_section_size(elfcpp::DT_RELSZ, od); |
| 1850 odyn->add_constant(elfcpp::DT_RELENT, | 1853 odyn->add_constant(elfcpp::DT_RELENT, |
| 1851 elfcpp::Elf_sizes<32>::rel_size); | 1854 elfcpp::Elf_sizes<32>::rel_size); |
| 1852 } | 1855 } |
| 1853 | 1856 |
| 1854 if (!parameters->options().shared()) | 1857 if (!parameters->options().shared()) |
| 1855 { | 1858 { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1872 Output_section* exidx_section = | 1875 Output_section* exidx_section = |
| 1873 layout->find_output_section(".ARM.exidx"); | 1876 layout->find_output_section(".ARM.exidx"); |
| 1874 | 1877 |
| 1875 if (exidx_section != NULL | 1878 if (exidx_section != NULL |
| 1876 && exidx_section->type() == elfcpp::SHT_ARM_EXIDX) | 1879 && exidx_section->type() == elfcpp::SHT_ARM_EXIDX) |
| 1877 { | 1880 { |
| 1878 gold_assert(layout->find_output_segment(elfcpp::PT_ARM_EXIDX, 0, 0) | 1881 gold_assert(layout->find_output_segment(elfcpp::PT_ARM_EXIDX, 0, 0) |
| 1879 == NULL); | 1882 == NULL); |
| 1880 Output_segment* exidx_segment = | 1883 Output_segment* exidx_segment = |
| 1881 layout->make_output_segment(elfcpp::PT_ARM_EXIDX, elfcpp::PF_R); | 1884 layout->make_output_segment(elfcpp::PT_ARM_EXIDX, elfcpp::PF_R); |
| 1882 » exidx_segment->add_output_section(exidx_section, elfcpp::PF_R); | 1885 » exidx_segment->add_output_section(exidx_section, elfcpp::PF_R, |
| 1886 » » » » » false); |
| 1883 } | 1887 } |
| 1884 } | 1888 } |
| 1885 } | 1889 } |
| 1886 | 1890 |
| 1887 // Return whether a direct absolute static relocation needs to be applied. | 1891 // Return whether a direct absolute static relocation needs to be applied. |
| 1888 // In cases where Scan::local() or Scan::global() has created | 1892 // In cases where Scan::local() or Scan::global() has created |
| 1889 // a dynamic relocation other than R_ARM_RELATIVE, the addend | 1893 // a dynamic relocation other than R_ARM_RELATIVE, the addend |
| 1890 // of the relocation is carried in the data, and we must not | 1894 // of the relocation is carried in the data, and we must not |
| 1891 // apply the static relocation. | 1895 // apply the static relocation. |
| 1892 | 1896 |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 | 2482 |
| 2479 Target* | 2483 Target* |
| 2480 do_instantiate_target() | 2484 do_instantiate_target() |
| 2481 { return new Target_arm<big_endian>(); } | 2485 { return new Target_arm<big_endian>(); } |
| 2482 }; | 2486 }; |
| 2483 | 2487 |
| 2484 Target_selector_arm<false> target_selector_arm; | 2488 Target_selector_arm<false> target_selector_arm; |
| 2485 Target_selector_arm<true> target_selector_armbe; | 2489 Target_selector_arm<true> target_selector_armbe; |
| 2486 | 2490 |
| 2487 } // End anonymous namespace. | 2491 } // End anonymous namespace. |
| OLD | NEW |