diff options
-rw-r--r-- | gold/ChangeLog | 19 | ||||
-rw-r--r-- | gold/freebsd.h | 87 | ||||
-rw-r--r-- | gold/i386.cc | 4 | ||||
-rw-r--r-- | gold/target.cc | 49 | ||||
-rw-r--r-- | gold/target.h | 27 | ||||
-rw-r--r-- | gold/x86_64.cc | 4 |
6 files changed, 98 insertions, 92 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 57fbfea..4ea905f 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,24 @@ 2011-06-28 Ian Lance Taylor <iant@google.com> + * target.h (class Target): Add osabi_ field. + (Target::osabi): New function. + (Target::set_osabi): New function. + (Target::Target): Initialize osabi_. + (Target::do_adjust_elf_header): Make pure virtual. + (Sized_target::do_adjust_elf_header): Declare. + * target.cc (Sized_target::do_adjust_elf_header): New function. + (class Sized_target): Instantiate all versions. + * freebsd.h (class Target_freebsd): Remove. + (Target_selector_freebsd::do_recognize): Call set_osabi on + Target. + (Target_selector_freebsd::do_recognize_by_name): Likewise. + (Target_selector_freebsd::set_osabi): Remove. + * i386.cc (class Target_i386): Inherit from Sized_target rather + than Target_freebsd. + * x86_64.cc (class Target_x86_64): Likewise. + +2011-06-28 Ian Lance Taylor <iant@google.com> + * target.h (Target::can_check_for_function_pointers): Rewrite. Make non-virtual. (Target::can_icf_inline_merge_sections): Likewise. diff --git a/gold/freebsd.h b/gold/freebsd.h index de69735..bb86432 100644 --- a/gold/freebsd.h +++ b/gold/freebsd.h @@ -1,6 +1,6 @@ // freebsd.h -- FreeBSD support for gold -*- C++ -*- -// Copyright 2009 Free Software Foundation, Inc. +// Copyright 2009, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor <iant@google.com>. // This file is part of gold. @@ -30,59 +30,8 @@ namespace gold { // FreeBSD 4.1 and later wants the EI_OSABI field in the ELF header to -// be set to ELFOSABI_FREEBSD. This is a subclass of Sized_target -// which supports that. The real target would be a subclass of this -// one. We permit combining FreeBSD and non-FreeBSD object files. -// The effect of this target is to set the code in the output file. - -template<int size, bool big_endian> -class Target_freebsd : public Sized_target<size, big_endian> -{ - public: - // Set the value to use for the EI_OSABI field in the ELF header. - void - set_osabi(elfcpp::ELFOSABI osabi) - { this->osabi_ = osabi; } - - protected: - Target_freebsd(const Target::Target_info* pti) - : Sized_target<size, big_endian>(pti), - osabi_(elfcpp::ELFOSABI_NONE) - { } - - virtual void - do_adjust_elf_header(unsigned char* view, int len) const; - - private: - // Value to store in the EI_OSABI field of the ELF file header. - elfcpp::ELFOSABI osabi_; -}; - -// Adjust the ELF file header by storing the requested value in the -// OSABI field. This is for FreeBSD support. - -template<int size, bool big_endian> -inline void -Target_freebsd<size, big_endian>::do_adjust_elf_header(unsigned char* view, - int len) const -{ - if (this->osabi_ != elfcpp::ELFOSABI_NONE) - { - gold_assert(len == elfcpp::Elf_sizes<size>::ehdr_size); - - elfcpp::Ehdr<size, false> ehdr(view); - unsigned char e_ident[elfcpp::EI_NIDENT]; - memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT); - - e_ident[elfcpp::EI_OSABI] = this->osabi_; - - elfcpp::Ehdr_write<size, false> oehdr(view); - oehdr.put_e_ident(e_ident); - } -} - -// A target selector for targets which permit combining both FreeBSD -// and non-FreeBSD object files. +// be set to ELFOSABI_FREEBSD. This is a target selector for targets +// which permit combining both FreeBSD and non-FreeBSD object files. class Target_selector_freebsd : public Target_selector { @@ -102,7 +51,7 @@ class Target_selector_freebsd : public Target_selector { Target* ret = this->instantiate_target(); if (osabi == elfcpp::ELFOSABI_FREEBSD) - this->set_osabi(ret); + ret->set_osabi(static_cast<elfcpp::ELFOSABI>(osabi)); return ret; } @@ -115,7 +64,7 @@ class Target_selector_freebsd : public Target_selector else if (strcmp(name, this->freebsd_bfd_name_) == 0) { Target* ret = this->instantiate_target(); - this->set_osabi(ret); + ret->set_osabi(elfcpp::ELFOSABI_FREEBSD); return ret; } else @@ -131,32 +80,6 @@ class Target_selector_freebsd : public Target_selector } private: - // Set the OSABI field. This is quite ugly. - void - set_osabi(Target* target) - { - if (this->get_size() == 32) - { - if (this->is_big_endian()) - static_cast<Target_freebsd<32, true>*>(target)-> - set_osabi(elfcpp::ELFOSABI_FREEBSD); - else - static_cast<Target_freebsd<32, false>*>(target)-> - set_osabi(elfcpp::ELFOSABI_FREEBSD); - } - else if (this->get_size() == 64) - { - if (this->is_big_endian()) - static_cast<Target_freebsd<64, true>*>(target)-> - set_osabi(elfcpp::ELFOSABI_FREEBSD); - else - static_cast<Target_freebsd<64, false>*>(target)-> - set_osabi(elfcpp::ELFOSABI_FREEBSD); - } - else - gold_unreachable(); - } - // The BFD name for the non-Freebsd target. const char* bfd_name_; // The BFD name for the Freebsd target. diff --git a/gold/i386.cc b/gold/i386.cc index bd5eaaf..b158b1f 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -158,13 +158,13 @@ class Output_data_plt_i386 : public Output_section_data // http://people.redhat.com/drepper/tls.pdf // http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt -class Target_i386 : public Target_freebsd<32, false> +class Target_i386 : public Sized_target<32, false> { public: typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section; Target_i386() - : Target_freebsd<32, false>(&i386_info), + : Sized_target<32, false>(&i386_info), got_(NULL), plt_(NULL), got_plt_(NULL), got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL), copy_relocs_(elfcpp::R_386_COPY), dynbss_(NULL), diff --git a/gold/target.cc b/gold/target.cc index 0e329cd..4a7af83 100644 --- a/gold/target.cc +++ b/gold/target.cc @@ -1,6 +1,6 @@ -// target.cc +// target.cc -- target support for gold. -// Copyright 2009, 2010 Free Software Foundation, Inc. +// Copyright 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Doug Kwan <dougkwan@google.com>. // This file is part of gold. @@ -200,4 +200,49 @@ Target::set_view_to_nop(unsigned char* view, section_size_type view_size, } } +// Class Sized_target. + +// Set the EI_OSABI field of the ELF header if requested. + +template<int size, bool big_endian> +void +Sized_target<size, big_endian>::do_adjust_elf_header(unsigned char* view, + int len) const +{ + elfcpp::ELFOSABI osabi = this->osabi(); + if (osabi != elfcpp::ELFOSABI_NONE) + { + gold_assert(len == elfcpp::Elf_sizes<size>::ehdr_size); + + elfcpp::Ehdr<size, false> ehdr(view); + unsigned char e_ident[elfcpp::EI_NIDENT]; + memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT); + + e_ident[elfcpp::EI_OSABI] = osabi; + + elfcpp::Ehdr_write<size, false> oehdr(view); + oehdr.put_e_ident(e_ident); + } +} + +#ifdef HAVE_TARGET_32_LITTLE +template +class Sized_target<32, false>; +#endif + +#ifdef HAVE_TARGET_32_BIG +template +class Sized_target<32, true>; +#endif + +#ifdef HAVE_TARGET_64_LITTLE +template +class Sized_target<64, false>; +#endif + +#ifdef HAVE_TARGET_64_BIG +template +class Sized_target<64, true>; +#endif + } // End namespace gold. diff --git a/gold/target.h b/gold/target.h index 1d523b8..f9b8c04 100644 --- a/gold/target.h +++ b/gold/target.h @@ -375,6 +375,17 @@ class Target select_as_default_target() { this->do_select_as_default_target(); } + // Return the value to store in the EI_OSABI field in the ELF + // header. + elfcpp::ELFOSABI + osabi() const + { return this->osabi_; } + + // Set the value to store in the EI_OSABI field in the ELF header. + void + set_osabi(elfcpp::ELFOSABI osabi) + { this->osabi_ = osabi; } + protected: // This struct holds the constant information for a child class. We // use a struct to avoid the overhead of virtual function calls for @@ -427,7 +438,7 @@ class Target Target(const Target_info* pti) : pti_(pti), processor_specific_flags_(0), - are_processor_specific_flags_set_(false) + are_processor_specific_flags_set_(false), osabi_(elfcpp::ELFOSABI_NONE) { } // Virtual function which may be implemented by the child class. @@ -459,10 +470,10 @@ class Target // Adjust the output file header before it is written out. VIEW // points to the header in external form. LEN is the length, and // will be one of the values of elfcpp::Elf_sizes<size>::ehdr_size. - // By default, we do nothing. + // By default, we set the EI_OSABI field if requested (in + // Sized_target). virtual void - do_adjust_elf_header(unsigned char*, int) const - { } + do_adjust_elf_header(unsigned char*, int) const = 0; // Virtual function which may be overridden by the child class. virtual bool @@ -622,6 +633,10 @@ class Target elfcpp::Elf_Word processor_specific_flags_; // Whether the processor-specific flags are set at least once. bool are_processor_specific_flags_set_; + // If not ELFOSABI_NONE, the value to put in the EI_OSABI field of + // the ELF header. This is handled at this level because it is + // OS-specific rather than processor-specific. + elfcpp::ELFOSABI osabi_; }; // The abstract class for a specific size and endianness of target. @@ -873,6 +888,10 @@ class Sized_target : public Target gold_assert(pti->size == size); gold_assert(pti->is_big_endian ? big_endian : !big_endian); } + + // Set the EI_OSABI field if requested. + virtual void + do_adjust_elf_header(unsigned char*, int) const; }; } // End namespace gold. diff --git a/gold/x86_64.cc b/gold/x86_64.cc index a6e9ddd..6d04dc7 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -201,7 +201,7 @@ class Output_data_plt_x86_64 : public Output_section_data // http://people.redhat.com/drepper/tls.pdf // http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt -class Target_x86_64 : public Target_freebsd<64, false> +class Target_x86_64 : public Sized_target<64, false> { public: // In the x86_64 ABI (p 68), it says "The AMD64 ABI architectures @@ -209,7 +209,7 @@ class Target_x86_64 : public Target_freebsd<64, false> typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section; Target_x86_64() - : Target_freebsd<64, false>(&x86_64_info), + : Sized_target<64, false>(&x86_64_info), got_(NULL), plt_(NULL), got_plt_(NULL), got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL), copy_relocs_(elfcpp::R_X86_64_COPY), dynbss_(NULL), |