| OLD | NEW |
| 1 // i386.cc -- i386 target support for gold. | 1 // i386.cc -- i386 target support for gold. |
| 2 | 2 |
| 3 // Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | 3 // Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
| 4 // Written by Ian Lance Taylor <iant@google.com>. | 4 // Written by Ian Lance Taylor <iant@google.com>. |
| 5 | 5 |
| 6 // This file is part of gold. | 6 // This file is part of gold. |
| 7 | 7 |
| 8 // This program is free software; you can redistribute it and/or modify | 8 // This program is free software; you can redistribute it and/or modify |
| 9 // it under the terms of the GNU General Public License as published by | 9 // it under the terms of the GNU General Public License as published by |
| 10 // the Free Software Foundation; either version 3 of the License, or | 10 // the Free Software Foundation; either version 3 of the License, or |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 if (this->got_ == NULL) | 457 if (this->got_ == NULL) |
| 458 { | 458 { |
| 459 gold_assert(symtab != NULL && layout != NULL); | 459 gold_assert(symtab != NULL && layout != NULL); |
| 460 | 460 |
| 461 this->got_ = new Output_data_got<32, false>(); | 461 this->got_ = new Output_data_got<32, false>(); |
| 462 | 462 |
| 463 Output_section* os; | 463 Output_section* os; |
| 464 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, | 464 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, |
| 465 (elfcpp::SHF_ALLOC | 465 (elfcpp::SHF_ALLOC |
| 466 | elfcpp::SHF_WRITE), | 466 | elfcpp::SHF_WRITE), |
| 467 » » » » » this->got_); | 467 » » » » » this->got_, false); |
| 468 os->set_is_relro(); | 468 os->set_is_relro(); |
| 469 | 469 |
| 470 // The old GNU linker creates a .got.plt section. We just | 470 // The old GNU linker creates a .got.plt section. We just |
| 471 // create another set of data in the .got section. Note that we | 471 // create another set of data in the .got section. Note that we |
| 472 // always create a PLT if we create a GOT, although the PLT | 472 // always create a PLT if we create a GOT, although the PLT |
| 473 // might be empty. | 473 // might be empty. |
| 474 this->got_plt_ = new Output_data_space(4, "** GOT PLT"); | 474 this->got_plt_ = new Output_data_space(4, "** GOT PLT"); |
| 475 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, | 475 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, |
| 476 (elfcpp::SHF_ALLOC | 476 (elfcpp::SHF_ALLOC |
| 477 | elfcpp::SHF_WRITE), | 477 | elfcpp::SHF_WRITE), |
| 478 » » » » » this->got_plt_); | 478 » » » » » this->got_plt_, false); |
| 479 os->set_is_relro(); | 479 os->set_is_relro(); |
| 480 | 480 |
| 481 // The first three entries are reserved. | 481 // The first three entries are reserved. |
| 482 this->got_plt_->set_current_data_size(3 * 4); | 482 this->got_plt_->set_current_data_size(3 * 4); |
| 483 | 483 |
| 484 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. | 484 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. |
| 485 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, | 485 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, |
| 486 this->got_plt_, | 486 this->got_plt_, |
| 487 0, 0, elfcpp::STT_OBJECT, | 487 0, 0, elfcpp::STT_OBJECT, |
| 488 elfcpp::STB_LOCAL, | 488 elfcpp::STB_LOCAL, |
| 489 elfcpp::STV_HIDDEN, 0, | 489 elfcpp::STV_HIDDEN, 0, |
| 490 false, false); | 490 false, false); |
| 491 } | 491 } |
| 492 | 492 |
| 493 return this->got_; | 493 return this->got_; |
| 494 } | 494 } |
| 495 | 495 |
| 496 // Get the dynamic reloc section, creating it if necessary. | 496 // Get the dynamic reloc section, creating it if necessary. |
| 497 | 497 |
| 498 Target_i386::Reloc_section* | 498 Target_i386::Reloc_section* |
| 499 Target_i386::rel_dyn_section(Layout* layout) | 499 Target_i386::rel_dyn_section(Layout* layout) |
| 500 { | 500 { |
| 501 if (this->rel_dyn_ == NULL) | 501 if (this->rel_dyn_ == NULL) |
| 502 { | 502 { |
| 503 gold_assert(layout != NULL); | 503 gold_assert(layout != NULL); |
| 504 this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); | 504 this->rel_dyn_ = new Reloc_section(parameters->options().combreloc()); |
| 505 layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, | 505 layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL, |
| 506 » » » » elfcpp::SHF_ALLOC, this->rel_dyn_); | 506 » » » » elfcpp::SHF_ALLOC, this->rel_dyn_, true); |
| 507 } | 507 } |
| 508 return this->rel_dyn_; | 508 return this->rel_dyn_; |
| 509 } | 509 } |
| 510 | 510 |
| 511 // A class to handle the PLT data. | 511 // A class to handle the PLT data. |
| 512 | 512 |
| 513 class Output_data_plt_i386 : public Output_section_data | 513 class Output_data_plt_i386 : public Output_section_data |
| 514 { | 514 { |
| 515 public: | 515 public: |
| 516 typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section; | 516 typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 // Create the PLT section. The ordinary .got section is an argument, | 571 // Create the PLT section. The ordinary .got section is an argument, |
| 572 // since we need to refer to the start. We also create our own .got | 572 // since we need to refer to the start. We also create our own .got |
| 573 // section just for PLT entries. | 573 // section just for PLT entries. |
| 574 | 574 |
| 575 Output_data_plt_i386::Output_data_plt_i386(Layout* layout, | 575 Output_data_plt_i386::Output_data_plt_i386(Layout* layout, |
| 576 Output_data_space* got_plt) | 576 Output_data_space* got_plt) |
| 577 : Output_section_data(4), got_plt_(got_plt), count_(0) | 577 : Output_section_data(4), got_plt_(got_plt), count_(0) |
| 578 { | 578 { |
| 579 this->rel_ = new Reloc_section(false); | 579 this->rel_ = new Reloc_section(false); |
| 580 layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, | 580 layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL, |
| 581 » » » » elfcpp::SHF_ALLOC, this->rel_); | 581 » » » » elfcpp::SHF_ALLOC, this->rel_, true); |
| 582 } | 582 } |
| 583 | 583 |
| 584 void | 584 void |
| 585 Output_data_plt_i386::do_adjust_output_section(Output_section* os) | 585 Output_data_plt_i386::do_adjust_output_section(Output_section* os) |
| 586 { | 586 { |
| 587 // UnixWare sets the entsize of .plt to 4, and so does the old GNU | 587 // UnixWare sets the entsize of .plt to 4, and so does the old GNU |
| 588 // linker, and so do we. | 588 // linker, and so do we. |
| 589 os->set_entsize(4); | 589 os->set_entsize(4); |
| 590 } | 590 } |
| 591 | 591 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 | 756 |
| 757 if (this->plt_ == NULL) | 757 if (this->plt_ == NULL) |
| 758 { | 758 { |
| 759 // Create the GOT sections first. | 759 // Create the GOT sections first. |
| 760 this->got_section(symtab, layout); | 760 this->got_section(symtab, layout); |
| 761 | 761 |
| 762 this->plt_ = new Output_data_plt_i386(layout, this->got_plt_); | 762 this->plt_ = new Output_data_plt_i386(layout, this->got_plt_); |
| 763 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, | 763 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, |
| 764 (elfcpp::SHF_ALLOC | 764 (elfcpp::SHF_ALLOC |
| 765 | elfcpp::SHF_EXECINSTR), | 765 | elfcpp::SHF_EXECINSTR), |
| 766 » » » » this->plt_); | 766 » » » » this->plt_, false); |
| 767 } | 767 } |
| 768 | 768 |
| 769 this->plt_->add_entry(gsym); | 769 this->plt_->add_entry(gsym); |
| 770 } | 770 } |
| 771 | 771 |
| 772 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment. | 772 // Define the _TLS_MODULE_BASE_ symbol in the TLS segment. |
| 773 | 773 |
| 774 void | 774 void |
| 775 Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout) | 775 Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout) |
| 776 { | 776 { |
| (...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 | 1562 |
| 1563 // Finalize the sections. | 1563 // Finalize the sections. |
| 1564 | 1564 |
| 1565 void | 1565 void |
| 1566 Target_i386::do_finalize_sections(Layout* layout) | 1566 Target_i386::do_finalize_sections(Layout* layout) |
| 1567 { | 1567 { |
| 1568 // Fill in some more dynamic tags. | 1568 // Fill in some more dynamic tags. |
| 1569 Output_data_dynamic* const odyn = layout->dynamic_data(); | 1569 Output_data_dynamic* const odyn = layout->dynamic_data(); |
| 1570 if (odyn != NULL) | 1570 if (odyn != NULL) |
| 1571 { | 1571 { |
| 1572 if (this->got_plt_ != NULL) | 1572 if (this->got_plt_ != NULL |
| 1573 » && this->got_plt_->output_section() != NULL) |
| 1573 odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_); | 1574 odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_); |
| 1574 | 1575 |
| 1575 if (this->plt_ != NULL) | 1576 if (this->plt_ != NULL |
| 1577 » && this->plt_->output_section() != NULL) |
| 1576 { | 1578 { |
| 1577 const Output_data* od = this->plt_->rel_plt(); | 1579 const Output_data* od = this->plt_->rel_plt(); |
| 1578 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); | 1580 odyn->add_section_size(elfcpp::DT_PLTRELSZ, od); |
| 1579 odyn->add_section_address(elfcpp::DT_JMPREL, od); | 1581 odyn->add_section_address(elfcpp::DT_JMPREL, od); |
| 1580 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL); | 1582 odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL); |
| 1581 } | 1583 } |
| 1582 | 1584 |
| 1583 if (this->rel_dyn_ != NULL) | 1585 if (this->rel_dyn_ != NULL |
| 1586 » && this->rel_dyn_->output_section() != NULL) |
| 1584 { | 1587 { |
| 1585 const Output_data* od = this->rel_dyn_; | 1588 const Output_data* od = this->rel_dyn_; |
| 1586 odyn->add_section_address(elfcpp::DT_REL, od); | 1589 odyn->add_section_address(elfcpp::DT_REL, od); |
| 1587 odyn->add_section_size(elfcpp::DT_RELSZ, od); | 1590 odyn->add_section_size(elfcpp::DT_RELSZ, od); |
| 1588 odyn->add_constant(elfcpp::DT_RELENT, | 1591 odyn->add_constant(elfcpp::DT_RELENT, |
| 1589 elfcpp::Elf_sizes<32>::rel_size); | 1592 elfcpp::Elf_sizes<32>::rel_size); |
| 1590 } | 1593 } |
| 1591 | 1594 |
| 1592 if (!parameters->options().shared()) | 1595 if (!parameters->options().shared()) |
| 1593 { | 1596 { |
| (...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 { } | 2751 { } |
| 2749 | 2752 |
| 2750 Target* | 2753 Target* |
| 2751 do_instantiate_target() | 2754 do_instantiate_target() |
| 2752 { return new Target_i386(); } | 2755 { return new Target_i386(); } |
| 2753 }; | 2756 }; |
| 2754 | 2757 |
| 2755 Target_selector_i386 target_selector_i386; | 2758 Target_selector_i386 target_selector_i386; |
| 2756 | 2759 |
| 2757 } // End anonymous namespace. | 2760 } // End anonymous namespace. |
| OLD | NEW |