From 03ef7571fc6524b38bfbb99ffdfa72418d03d02c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 28 Jun 2011 23:12:31 +0000 Subject: [PATCH] PR gold/12934 * target-select.cc (Target_selector::Target_selector): Add emulation parameter. Change all callers. (select_target_by_bfd_name): Rename from select_target_by_name. Change all callers. (select_target_by_emulation): New function. (supported_emulation_names): New function. * target-select.h (class Target_selector): Add emulation_ field. Update declarations. (Target_selector::recognize_by_bfd_name): Rename from recognize_by_name. Change all callers. (Target_selector::supported_bfd_names): Rename from supported_names. Change all callers. (Target_selector::recognize_by_emulation): New function. (Target_selector::supported_emulations): New function. (Target_selector::emulation): New function. (Target_selector::do_recognize_by_bfd_name): Rename from do_recognize_by_name. Change all callers. (Target_selector::do_supported_bfd_names): Rename from do_supported_names. Change all callers. (Target_selector::do_recognize_by_emulation): New function. (Target_selector::do_supported_emulations): New function. (select_target_by_bfd_name): Change name in declaration. (select_target_by_emulation): Declare. (supported_emulation_names): Declare. * parameters.cc (parameters_force_valid_target): Try to find target based on emulation from -m option. * options.h (class General_options): Change doc string for -m. * options.cc (help): Print emulations. (General_options::parse_V): Likewise. * freebsd.h (Target_selector_freebsd::Target_selector_freebsd): Add emulation parameter. Change all callers. --- gold/ChangeLog | 35 +++++++++++++++++ gold/arm.cc | 3 +- gold/freebsd.h | 9 +++-- gold/i386.cc | 3 +- gold/options.cc | 20 +++++++++- gold/options.h | 2 +- gold/parameters.cc | 21 ++++++++-- gold/powerpc.cc | 9 +++-- gold/script.cc | 4 +- gold/sparc.cc | 3 +- gold/target-select.cc | 41 +++++++++++++++++--- gold/target-select.h | 78 +++++++++++++++++++++++++++++++------- gold/testsuite/testfile.cc | 2 +- gold/x86_64.cc | 2 +- 14 files changed, 192 insertions(+), 40 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 4ea905fe73e..f27f58e77cb 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,38 @@ +2011-06-28 Ian Lance Taylor + + PR gold/12934 + * target-select.cc (Target_selector::Target_selector): Add + emulation parameter. Change all callers. + (select_target_by_bfd_name): Rename from select_target_by_name. + Change all callers. + (select_target_by_emulation): New function. + (supported_emulation_names): New function. + * target-select.h (class Target_selector): Add emulation_ field. + Update declarations. + (Target_selector::recognize_by_bfd_name): Rename from + recognize_by_name. Change all callers. + (Target_selector::supported_bfd_names): Rename from + supported_names. Change all callers. + (Target_selector::recognize_by_emulation): New function. + (Target_selector::supported_emulations): New function. + (Target_selector::emulation): New function. + (Target_selector::do_recognize_by_bfd_name): Rename from + do_recognize_by_name. Change all callers. + (Target_selector::do_supported_bfd_names): Rename from + do_supported_names. Change all callers. + (Target_selector::do_recognize_by_emulation): New function. + (Target_selector::do_supported_emulations): New function. + (select_target_by_bfd_name): Change name in declaration. + (select_target_by_emulation): Declare. + (supported_emulation_names): Declare. + * parameters.cc (parameters_force_valid_target): Try to find + target based on emulation from -m option. + * options.h (class General_options): Change doc string for -m. + * options.cc (help): Print emulations. + (General_options::parse_V): Likewise. + * freebsd.h (Target_selector_freebsd::Target_selector_freebsd): + Add emulation parameter. Change all callers. + 2011-06-28 Ian Lance Taylor * target.h (class Target): Add osabi_ field. diff --git a/gold/arm.cc b/gold/arm.cc index bf41bc88792..8fd20be6b89 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -11904,7 +11904,8 @@ class Target_selector_arm : public Target_selector public: Target_selector_arm() : Target_selector(elfcpp::EM_ARM, 32, big_endian, - (big_endian ? "elf32-bigarm" : "elf32-littlearm")) + (big_endian ? "elf32-bigarm" : "elf32-littlearm"), + (big_endian ? "armelfb" : "armelf")) { } Target* diff --git a/gold/freebsd.h b/gold/freebsd.h index bb86432519f..8f0d46dfeff 100644 --- a/gold/freebsd.h +++ b/gold/freebsd.h @@ -38,8 +38,9 @@ class Target_selector_freebsd : public Target_selector public: Target_selector_freebsd(int machine, int size, bool is_big_endian, const char* bfd_name, - const char* freebsd_bfd_name) - : Target_selector(machine, size, is_big_endian, NULL), + const char* freebsd_bfd_name, + const char* emulation) + : Target_selector(machine, size, is_big_endian, NULL, emulation), bfd_name_(bfd_name), freebsd_bfd_name_(freebsd_bfd_name) { } @@ -57,7 +58,7 @@ class Target_selector_freebsd : public Target_selector // Recognize two names. virtual Target* - do_recognize_by_name(const char* name) + do_recognize_by_bfd_name(const char* name) { if (strcmp(name, this->bfd_name_) == 0) return this->instantiate_target(); @@ -73,7 +74,7 @@ class Target_selector_freebsd : public Target_selector // Print both names in --help output. virtual void - do_supported_names(std::vector* names) + do_supported_bfd_names(std::vector* names) { names->push_back(this->bfd_name_); names->push_back(this->freebsd_bfd_name_); diff --git a/gold/i386.cc b/gold/i386.cc index b158b1f6b7d..beec4a8e314 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -3284,7 +3284,8 @@ class Target_selector_i386 : public Target_selector_freebsd public: Target_selector_i386() : Target_selector_freebsd(elfcpp::EM_386, 32, false, - "elf32-i386", "elf32-i386-freebsd") + "elf32-i386", "elf32-i386-freebsd", + "elf_i386") { } Target* diff --git a/gold/options.cc b/gold/options.cc index 3ec76a8cae2..50fc557bee9 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1,6 +1,6 @@ // options.c -- handle command line options for gold -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -170,6 +170,15 @@ help() printf(" %s", *p); printf("\n"); + printf(_("%s: supported emulations:"), gold::program_name); + supported_names.clear(); + gold::supported_emulation_names(&supported_names); + for (std::vector::const_iterator p = supported_names.begin(); + p != supported_names.end(); + ++p) + printf(" %s", *p); + printf("\n"); + // REPORT_BUGS_TO is defined in bfd/bfdver.h. const char* report = REPORT_BUGS_TO; if (*report != '\0') @@ -300,6 +309,7 @@ General_options::parse_V(const char*, const char*, Command_line*) { gold::print_version(true); this->printed_version_ = true; + printf(_(" Supported targets:\n")); std::vector supported_names; gold::supported_target_names(&supported_names); @@ -307,6 +317,14 @@ General_options::parse_V(const char*, const char*, Command_line*) p != supported_names.end(); ++p) printf(" %s\n", *p); + + printf(_(" Supported emulations:\n")); + supported_names.clear(); + gold::supported_emulation_names(&supported_names); + for (std::vector::const_iterator p = supported_names.begin(); + p != supported_names.end(); + ++p) + printf(" %s\n", *p); } void diff --git a/gold/options.h b/gold/options.h index 9989badce53..da4b6cfa8a0 100644 --- a/gold/options.h +++ b/gold/options.h @@ -835,7 +835,7 @@ class General_options NULL); DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "", - N_("Ignored for compatibility"), N_("EMULATION")); + N_("Set GNU linker emulation; obsolete"), N_("EMULATION")); DEFINE_bool(print_map, options::TWO_DASHES, 'M', false, N_("Write map file on standard output"), NULL); diff --git a/gold/parameters.cc b/gold/parameters.cc index 194c81bd389..1b371d8e5bb 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -1,6 +1,6 @@ // parameters.cc -- general parameters for a link using gold -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -299,15 +299,28 @@ parameters_force_valid_target() gold_assert(parameters->options_valid()); if (parameters->options().user_set_oformat()) { - Target* target = select_target_by_name(parameters->options().oformat()); + const char* bfd_name = parameters->options().oformat(); + Target* target = select_target_by_bfd_name(bfd_name); if (target != NULL) { set_parameters_target(target); return; } - gold_error(_("unrecognized output format %s"), - parameters->options().oformat()); + gold_error(_("unrecognized output format %s"), bfd_name); + } + + if (parameters->options().user_set_m()) + { + const char* emulation = parameters->options().m(); + Target* target = select_target_by_emulation(emulation); + if (target != NULL) + { + set_parameters_target(target); + return; + } + + gold_error(_("unrecognized emulation %s"), emulation); } // The GOLD_DEFAULT_xx macros are defined by the configure script. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 78cda483458..45783c3933f 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -2124,9 +2124,12 @@ class Target_selector_powerpc : public Target_selector public: Target_selector_powerpc() : Target_selector(elfcpp::EM_NONE, size, big_endian, - (size == 64 ? - (big_endian ? "elf64-powerpc" : "elf64-powerpcle") : - (big_endian ? "elf32-powerpc" : "elf32-powerpcle"))) + (size == 64 + ? (big_endian ? "elf64-powerpc" : "elf64-powerpcle") + : (big_endian ? "elf32-powerpc" : "elf32-powerpcle")), + (size == 64 + ? (big_endian ? "elf64ppc" : "elf64lppc") + : (big_endian ? "elf32ppc" : "elf32lppc"))) { } Target* do_recognize(int machine, int, int) diff --git a/gold/script.cc b/gold/script.cc index 8f2170de337..33a89816b8d 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -1,6 +1,6 @@ // script.cc -- handle linker scripts for gold. -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -2804,7 +2804,7 @@ script_check_output_format(void* closurev, { Parser_closure* closure = static_cast(closurev); std::string name(default_name, default_length); - Target* target = select_target_by_name(name.c_str()); + Target* target = select_target_by_bfd_name(name.c_str()); if (target == NULL || !parameters->is_compatible_target(target)) { if (closure->skip_on_incompatible_target()) diff --git a/gold/sparc.cc b/gold/sparc.cc index 0ce96f7580c..9145fcb0ead 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -3481,7 +3481,8 @@ class Target_selector_sparc : public Target_selector public: Target_selector_sparc() : Target_selector(elfcpp::EM_NONE, size, big_endian, - (size == 64 ? "elf64-sparc" : "elf32-sparc")) + (size == 64 ? "elf64-sparc" : "elf32-sparc"), + (size == 64 ? "elf64_sparc" : "elf32_sparc")) { } Target* do_recognize(int machine, int, int) diff --git a/gold/target-select.cc b/gold/target-select.cc index 859bc3bd62c..b8a9f40d856 100644 --- a/gold/target-select.cc +++ b/gold/target-select.cc @@ -1,6 +1,6 @@ // target-select.cc -- select a target for an object file -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -52,9 +52,10 @@ Set_target_once::do_run_once(void*) // fast. Target_selector::Target_selector(int machine, int size, bool is_big_endian, - const char* bfd_name) + const char* bfd_name, const char* emulation) : machine_(machine), size_(size), is_big_endian_(is_big_endian), - bfd_name_(bfd_name), instantiated_target_(NULL), set_target_once_(this) + bfd_name_(bfd_name), emulation_(emulation), instantiated_target_(NULL), + set_target_once_(this) { this->next_ = target_selectors; target_selectors = this; @@ -104,14 +105,33 @@ select_target(int machine, int size, bool is_big_endian, int osabi, // --oformat option. Target* -select_target_by_name(const char* name) +select_target_by_bfd_name(const char* name) { for (Target_selector* p = target_selectors; p != NULL; p = p->next()) { const char* pname = p->bfd_name(); if (pname == NULL || strcmp(pname, name) == 0) { - Target* ret = p->recognize_by_name(name); + Target* ret = p->recognize_by_bfd_name(name); + if (ret != NULL) + return ret; + } + } + return NULL; +} + +// Find a target using a GNU linker emulation. This is used to +// support the -m option. + +Target* +select_target_by_emulation(const char* name) +{ + for (Target_selector* p = target_selectors; p != NULL; p = p->next()) + { + const char* pname = p->emulation(); + if (pname == NULL || strcmp(pname, name) == 0) + { + Target* ret = p->recognize_by_emulation(name); if (ret != NULL) return ret; } @@ -125,7 +145,16 @@ void supported_target_names(std::vector* names) { for (Target_selector* p = target_selectors; p != NULL; p = p->next()) - p->supported_names(names); + p->supported_bfd_names(names); +} + +// Push all the supported emulations onto a vector. + +void +supported_emulation_names(std::vector* names) +{ + for (Target_selector* p = target_selectors; p != NULL; p = p->next()) + p->supported_emulations(names); } } // End namespace gold. diff --git a/gold/target-select.h b/gold/target-select.h index 4e2ea922684..e16afd263f5 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, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -65,9 +65,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() { } @@ -81,14 +82,26 @@ class Target_selector // 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* @@ -114,12 +127,19 @@ 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_; } + protected: // Return an instance of the real target. This must be implemented // by the child class. @@ -141,19 +161,37 @@ 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_); + } + // Instantiate the target and return it. Target* instantiate_target(); @@ -173,6 +211,8 @@ 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 @@ -191,7 +231,12 @@ select_target(int machine, int size, bool big_endian, int osabi, // 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. @@ -199,6 +244,11 @@ 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*); + } // End namespace gold. #endif // !defined(GOLD_TARGET_SELECT_H) diff --git a/gold/testsuite/testfile.cc b/gold/testsuite/testfile.cc index 58433744a0a..93e716a7559 100644 --- a/gold/testsuite/testfile.cc +++ b/gold/testsuite/testfile.cc @@ -151,7 +151,7 @@ class Target_selector_test : public Target_selector { public: Target_selector_test() - : Target_selector(0xffff, size, big_endian, NULL) + : Target_selector(0xffff, size, big_endian, NULL, NULL) { } Target* diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 6d04dc7fa28..de39cb42887 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -3648,7 +3648,7 @@ class Target_selector_x86_64 : public Target_selector_freebsd public: Target_selector_x86_64() : Target_selector_freebsd(elfcpp::EM_X86_64, 64, false, "elf64-x86-64", - "elf64-x86-64-freebsd") + "elf64-x86-64-freebsd", "elf_x86_64") { } Target* -- 2.30.2