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 |