X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Ftarget-select.h;h=df6829f27d5a81bbdbe582e8cfe7ba6c80497e01;hb=73b9be8b5301c4ac056e10c38a47414867ee892a;hp=c5f469b36363f21e0bbf5b1997362fc8c075f4d6;hpb=91d6fa6a035cc7d0b7be5c99c194a64cb80924b0;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/target-select.h b/gold/target-select.h index c5f469b363..df6829f27d 100644 --- a/gold/target-select.h +++ b/gold/target-select.h @@ -1,6 +1,6 @@ // target-select.h -- select a target for an object file -*- C++ -*- -// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2006-2017 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -30,7 +30,26 @@ namespace gold { +class Input_file; class Target; +class Target_selector; + +// Used to set the target only once. + +class Set_target_once : public Once +{ + public: + Set_target_once(Target_selector* target_selector) + : target_selector_(target_selector) + { } + + protected: + void + do_run_once(void*); + + private: + Target_selector* target_selector_; +}; // We want to avoid a master list of targets, which implies using a // global constructor. And we also want the program to start up as @@ -47,9 +66,10 @@ class Target_selector // or 64), and endianness. The machine number can be EM_NONE to // test for any machine number. BFD_NAME is the name of the target // used by the GNU linker, for backward compatibility; it may be - // NULL. + // NULL. EMULATION is the name of the emulation used by the GNU + // linker; it is similar to BFD_NAME. Target_selector(int machine, int size, bool is_big_endian, - const char* bfd_name); + const char* bfd_name, const char* emulation); virtual ~Target_selector() { } @@ -57,20 +77,33 @@ class Target_selector // If we can handle this target, return a pointer to a target // structure. The size and endianness are known. Target* - recognize(int mach, int osabi, int abiversion) - { return this->do_recognize(mach, osabi, abiversion); } + recognize(Input_file* input_file, off_t offset, + int machine, int osabi, int abiversion) + { return this->do_recognize(input_file, offset, machine, osabi, abiversion); } // If NAME matches the target, return a pointer to a target // structure. Target* - recognize_by_name(const char* name) - { return this->do_recognize_by_name(name); } + recognize_by_bfd_name(const char* name) + { return this->do_recognize_by_bfd_name(name); } - // Push all supported names onto the vector. This is only used for - // help output. + // Push all supported BFD names onto the vector. This is only used + // for help output. void - supported_names(std::vector* names) - { this->do_supported_names(names); } + supported_bfd_names(std::vector* names) + { this->do_supported_bfd_names(names); } + + // If NAME matches the target emulation, return a pointer to a + // target structure. + Target* + recognize_by_emulation(const char* name) + { return this->do_recognize_by_emulation(name); } + + // Push all supported emulations onto the vector. This is only used + // for help output. + void + supported_emulations(std::vector* names) + { this->do_supported_emulations(names); } // Return the next Target_selector in the linked list. Target_selector* @@ -96,12 +129,26 @@ class Target_selector { return this->is_big_endian_; } // Return the BFD name. This may return NULL, in which case the - // do_recognize_by_name hook will be responsible for matching the - // BFD name. + // do_recognize_by_bfd_name hook will be responsible for matching + // the BFD name. const char* bfd_name() const { return this->bfd_name_; } + // Return the emulation. This may return NULL, in which case the + // do_recognize_by_emulation hook will be responsible for matching + // the emulation. + const char* + emulation() const + { return this->emulation_; } + + // The reverse mapping, for --print-output-format: if we + // instantiated TARGET, return our BFD_NAME. If we did not + // instantiate it, return NULL. + const char* + target_bfd_name(const Target* target) + { return this->do_target_bfd_name(target); } + protected: // Return an instance of the real target. This must be implemented // by the child class. @@ -115,7 +162,7 @@ class Target_selector // checks, or to check for multiple machine codes if the machine_ // field is EM_NONE. virtual Target* - do_recognize(int, int, int) + do_recognize(Input_file*, off_t, int, int, int) { return this->instantiate_target(); } // Recognize a target by name. When this is called we already know @@ -123,24 +170,57 @@ class Target_selector // child class may implement a different version of this to // recognize more than one name. virtual Target* - do_recognize_by_name(const char*) + do_recognize_by_bfd_name(const char*) { return this->instantiate_target(); } // Return a list of supported BFD names. The child class may // implement a different version of this to handle more than one // name. virtual void - do_supported_names(std::vector* names) + do_supported_bfd_names(std::vector* names) { gold_assert(this->bfd_name_ != NULL); names->push_back(this->bfd_name_); } + // Recognize a target by emulation. When this is called we already + // know that the name matches (or that the emulation_ field is + // NULL). The child class may implement a different version of this + // to recognize more than one emulation. + virtual Target* + do_recognize_by_emulation(const char*) + { return this->instantiate_target(); } + + // Return a list of supported emulations. The child class may + // implement a different version of this to handle more than one + // emulation. + virtual void + do_supported_emulations(std::vector* emulations) + { + gold_assert(this->emulation_ != NULL); + emulations->push_back(this->emulation_); + } + + // Map from target to BFD name. + virtual const char* + do_target_bfd_name(const Target*); + // Instantiate the target and return it. Target* instantiate_target(); + // Return whether TARGET is the target we instantiated. + bool + is_our_target(const Target* target) + { return target == this->instantiated_target_; } + private: + // Set the target. + void + set_target(); + + friend class Set_target_once; + // ELF machine code. const int machine_; // Target size--32 or 64. @@ -149,28 +229,33 @@ class Target_selector const bool is_big_endian_; // BFD name of target, for compatibility. const char* const bfd_name_; + // GNU linker emulation for this target, for compatibility. + const char* const emulation_; // Next entry in list built at global constructor time. Target_selector* next_; // The singleton Target structure--this points to an instance of the // real implementation. Target* instantiated_target_; - // Lock to make sure that we don't instantiate the target more than - // once. - Lock* lock_; - // We only want to initialize the lock_ pointer once. - Initialize_lock initialize_lock_; + // Used to set the target only once. + Set_target_once set_target_once_; }; // Select the target for an ELF file. extern Target* -select_target(int machine, int size, bool big_endian, int osabi, +select_target(Input_file*, off_t, + int machine, int size, bool big_endian, int osabi, int abiversion); // Select a target using a BFD name. extern Target* -select_target_by_name(const char* name); +select_target_by_bfd_name(const char* name); + +// Select a target using a GNU linker emulation. + +extern Target* +select_target_by_emulation(const char* name); // Fill in a vector with the list of supported targets. This returns // a list of BFD names. @@ -178,6 +263,16 @@ select_target_by_name(const char* name); extern void supported_target_names(std::vector*); +// Fill in a vector with the list of supported emulations. + +extern void +supported_emulation_names(std::vector*); + +// Print the output format, for the --print-output-format option. + +extern void +print_output_format(); + } // End namespace gold. #endif // !defined(GOLD_TARGET_SELECT_H)