Index: freebsd.h =================================================================== RCS file: /cvs/src/src/gold/freebsd.h,v retrieving revision 1.6 diff -u -p -r1.6 freebsd.h --- freebsd.h 28 Jun 2011 23:12:31 -0000 1.6 +++ freebsd.h 15 Jul 2011 21:42:05 -0000 @@ -80,6 +80,17 @@ class Target_selector_freebsd : public T names->push_back(this->freebsd_bfd_name_); } + // Return appropriate BFD name. + virtual const char* + do_target_bfd_name(const Target* target) + { + if (!this->is_our_target(target)) + return NULL; + return (target->osabi() == elfcpp::ELFOSABI_FREEBSD + ? this->freebsd_bfd_name_ + : this->bfd_name_); + } + private: // The BFD name for the non-Freebsd target. const char* bfd_name_; Index: gold.cc =================================================================== RCS file: /cvs/src/src/gold/gold.cc,v retrieving revision 1.93 diff -u -p -r1.93 gold.cc --- gold.cc 9 Jun 2011 18:18:44 -0000 1.93 +++ gold.cc 15 Jul 2011 21:42:05 -0000 @@ -1,6 +1,6 @@ // gold.cc -- main linker functions -// 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. @@ -30,6 +30,7 @@ #include "libiberty.h" #include "options.h" +#include "target-select.h" #include "debug.h" #include "workqueue.h" #include "dirsearch.h" @@ -175,7 +176,15 @@ queue_initial_tasks(const General_option { if (cmdline.begin() == cmdline.end()) { + bool is_ok = false; if (options.printed_version()) + is_ok = true; + if (options.print_output_format()) + { + print_output_format(); + is_ok = true; + } + if (is_ok) gold_exit(GOLD_OK); gold_fatal(_("no input files")); } Index: main.cc =================================================================== RCS file: /cvs/src/src/gold/main.cc,v retrieving revision 1.45 diff -u -p -r1.45 main.cc --- main.cc 14 Jul 2011 00:55:17 -0000 1.45 +++ main.cc 15 Jul 2011 21:42:05 -0000 @@ -1,6 +1,6 @@ // main.cc -- gold main function. -// 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. @@ -33,6 +33,7 @@ #include "script.h" #include "options.h" +#include "target-select.h" #include "parameters.h" #include "errors.h" #include "mapfile.h" @@ -246,6 +247,9 @@ main(int argc, char** argv) // Run the main task processing loop. workqueue.process(0); + if (command_line.options().print_output_format()) + print_output_format(); + if (command_line.options().stats()) { Timer::TimeStats elapsed = timer.get_elapsed_time(); Index: options.h =================================================================== RCS file: /cvs/src/src/gold/options.h,v retrieving revision 1.168 diff -u -p -r1.168 options.h --- options.h 11 Jul 2011 16:19:51 -0000 1.168 +++ options.h 15 Jul 2011 21:42:05 -0000 @@ -742,12 +742,12 @@ class General_options DEFINE_special(EB, options::ONE_DASH, '\0', N_("Link big-endian objects."), NULL); - DEFINE_bool(eh_frame_hdr, options::TWO_DASHES, '\0', false, - N_("Create exception frame header"), NULL); - DEFINE_special(EL, options::ONE_DASH, '\0', N_("Link little-endian objects."), NULL); + DEFINE_bool(eh_frame_hdr, options::TWO_DASHES, '\0', false, + N_("Create exception frame header"), NULL); + DEFINE_bool(enum_size_warning, options::TWO_DASHES, '\0', true, NULL, N_("(ARM only) Do not warn about objects with incompatible " "enum sizes")); @@ -927,6 +927,9 @@ class General_options DEFINE_bool(preread_archive_symbols, options::TWO_DASHES, '\0', false, N_("Preread archive symbols when multi-threaded"), NULL); + DEFINE_bool(print_output_format, options::TWO_DASHES, '\0', false, + N_("Print default output format"), NULL); + DEFINE_string(print_symbol_counts, options::TWO_DASHES, '\0', NULL, N_("Print symbols defined and used for each input"), N_("FILENAME")); Index: parameters.cc =================================================================== RCS file: /cvs/src/src/gold/parameters.cc,v retrieving revision 1.37 diff -u -p -r1.37 parameters.cc --- parameters.cc 6 Jul 2011 21:19:32 -0000 1.37 +++ parameters.cc 15 Jul 2011 21:42:05 -0000 @@ -346,7 +346,13 @@ parameters_force_valid_target() is_big_endian, elfcpp::GOLD_DEFAULT_OSABI, 0); - gold_assert(target != NULL); + + if (target == NULL) + { + gold_assert(is_big_endian != GOLD_DEFAULT_BIG_ENDIAN); + gold_fatal(_("no supported target for -EB/-EL option")); + } + set_parameters_target(target); } Index: target-select.cc =================================================================== RCS file: /cvs/src/src/gold/target-select.cc,v retrieving revision 1.14 diff -u -p -r1.14 target-select.cc --- target-select.cc 28 Jun 2011 23:12:31 -0000 1.14 +++ target-select.cc 15 Jul 2011 21:42:05 -0000 @@ -22,9 +22,12 @@ #include "gold.h" +#include #include #include "elfcpp.h" +#include "options.h" +#include "parameters.h" #include "target-select.h" namespace @@ -80,6 +83,18 @@ Target_selector::set_target() this->instantiated_target_ = this->do_instantiate_target(); } +// If we instantiated TARGET, return the corresponding BFD name. + +const char* +Target_selector::do_target_bfd_name(const Target* target) +{ + if (!this->is_our_target(target)) + return NULL; + const char* my_bfd_name = this->bfd_name(); + gold_assert(my_bfd_name != NULL); + return my_bfd_name; +} + // Find the target for an ELF file. Target* @@ -157,4 +172,46 @@ supported_emulation_names(std::vectorsupported_emulations(names); } +// Implement the --print-output-format option. + +void +print_output_format() +{ + if (!parameters->target_valid()) + { + // This case arises when --print-output-format is used with no + // input files. We need to come up with the right string to + // print based on the other options. If the user specified the + // format using a --oformat option, use that. That saves each + // target from having to remember the name that was used to + // select it. In other cases, we will just have to ask the + // target. + if (parameters->options().user_set_oformat()) + { + const char* bfd_name = parameters->options().oformat(); + Target* target = select_target_by_bfd_name(bfd_name); + if (target != NULL) + printf("%s\n", bfd_name); + else + gold_error(_("unrecognized output format %s"), bfd_name); + return; + } + + parameters_force_valid_target(); + } + + const Target* target = ¶meters->target(); + for (Target_selector* p = target_selectors; p != NULL; p = p->next()) + { + const char* bfd_name = p->target_bfd_name(target); + if (bfd_name != NULL) + { + printf("%s\n", bfd_name); + return; + } + } + + gold_unreachable(); +} + } // End namespace gold. Index: target-select.h =================================================================== RCS file: /cvs/src/src/gold/target-select.h,v retrieving revision 1.13 diff -u -p -r1.13 target-select.h --- target-select.h 28 Jun 2011 23:12:31 -0000 1.13 +++ target-select.h 15 Jul 2011 21:42:05 -0000 @@ -140,6 +140,13 @@ class Target_selector 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. @@ -192,10 +199,19 @@ class Target_selector 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 @@ -249,6 +265,11 @@ supported_target_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)