[BACK]Return to parameters.cc CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / gold

Annotation of src/external/gpl3/binutils.old/dist/gold/parameters.cc, Revision 1.5.2.1

1.1       christos    1: // parameters.cc -- general parameters for a link using gold
                      2:
1.5.2.1 ! martin      3: // Copyright (C) 2006-2018 Free Software Foundation, Inc.
1.1       christos    4: // Written by Ian Lance Taylor <iant@google.com>.
                      5:
                      6: // This file is part of gold.
                      7:
                      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
                     10: // the Free Software Foundation; either version 3 of the License, or
                     11: // (at your option) any later version.
                     12:
                     13: // This program is distributed in the hope that it will be useful,
                     14: // but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: // GNU General Public License for more details.
                     17:
                     18: // You should have received a copy of the GNU General Public License
                     19: // along with this program; if not, write to the Free Software
                     20: // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     21: // MA 02110-1301, USA.
                     22:
                     23: #include "gold.h"
                     24:
                     25: #include "debug.h"
                     26: #include "options.h"
                     27: #include "target.h"
                     28: #include "target-select.h"
                     29:
                     30: namespace gold
                     31: {
                     32:
                     33: // Our local version of the variable, which is not const.
                     34:
                     35: static Parameters static_parameters;
                     36:
                     37: // The global variable.
                     38:
                     39: const Parameters* parameters = &static_parameters;
                     40:
                     41: // A helper class to set the target once.
                     42:
                     43: class Set_parameters_target_once : public Once
                     44: {
                     45:  public:
                     46:   Set_parameters_target_once(Parameters* parameters)
                     47:     : parameters_(parameters)
                     48:   { }
                     49:
                     50:  protected:
                     51:   void
                     52:   do_run_once(void* arg)
                     53:   { this->parameters_->set_target_once(static_cast<Target*>(arg)); }
                     54:
                     55:  private:
                     56:   Parameters* parameters_;
                     57: };
                     58:
                     59: // We only need one Set_parameters_target_once.
                     60:
                     61: static
                     62: Set_parameters_target_once set_parameters_target_once(&static_parameters);
                     63:
                     64: // Class Parameters.
                     65:
                     66: Parameters::Parameters()
                     67:    : errors_(NULL), timer_(NULL), options_(NULL), target_(NULL),
                     68:      doing_static_link_valid_(false), doing_static_link_(false),
                     69:      debug_(0), incremental_mode_(General_options::INCREMENTAL_OFF),
                     70:      set_parameters_target_once_(&set_parameters_target_once)
                     71:  {
                     72:  }
                     73:
                     74: void
                     75: Parameters::set_errors(Errors* errors)
                     76: {
                     77:   gold_assert(this->errors_ == NULL);
                     78:   this->errors_ = errors;
                     79: }
                     80:
                     81: void
                     82: Parameters::set_timer(Timer* timer)
                     83: {
                     84:   gold_assert(this->timer_ == NULL);
                     85:   this->timer_ = timer;
                     86: }
                     87:
                     88: void
                     89: Parameters::set_options(const General_options* options)
                     90: {
                     91:   gold_assert(!this->options_valid());
                     92:   this->options_ = options;
                     93:   // For speed, we convert the options() debug var from a string to an
                     94:   // enum (from debug.h).
                     95:   this->debug_ = debug_string_to_enum(this->options().debug());
                     96:   // Set incremental_mode_ based on the value of the --incremental option.
                     97:   // We copy the mode into parameters because it can change based on inputs.
                     98:   this->incremental_mode_ = this->options().incremental_mode();
                     99:   // If --verbose is set, it acts as "--debug=files".
                    100:   if (options->verbose())
                    101:     this->debug_ |= DEBUG_FILES;
                    102:   if (this->target_valid())
                    103:     this->check_target_endianness();
                    104: }
                    105:
                    106: void
                    107: Parameters::set_doing_static_link(bool doing_static_link)
                    108: {
                    109:   gold_assert(!this->doing_static_link_valid_);
                    110:   this->doing_static_link_ = doing_static_link;
                    111:   this->doing_static_link_valid_ = true;
                    112: }
                    113:
                    114: void
                    115: Parameters::set_target(Target* target)
                    116: {
                    117:   this->set_parameters_target_once_->run_once(static_cast<void*>(target));
                    118:   gold_assert(target == this->target_);
                    119: }
                    120:
                    121: // This is called at most once.
                    122:
                    123: void
                    124: Parameters::set_target_once(Target* target)
                    125: {
                    126:   gold_assert(this->target_ == NULL);
                    127:   this->target_ = target;
1.3       christos  128:   target->select_as_default_target();
1.1       christos  129:   if (this->options_valid())
1.3       christos  130:     {
                    131:       this->check_target_endianness();
                    132:       this->check_rodata_segment();
                    133:     }
1.1       christos  134: }
                    135:
                    136: // Clear the target, for testing.
                    137:
                    138: void
                    139: Parameters::clear_target()
                    140: {
                    141:   this->target_ = NULL;
                    142:   // We need a new Set_parameters_target_once so that we can set the
                    143:   // target again.
                    144:   this->set_parameters_target_once_ = new Set_parameters_target_once(this);
                    145: }
                    146:
                    147: // Return whether TARGET is compatible with the target we are using.
                    148:
                    149: bool
                    150: Parameters::is_compatible_target(const Target* target) const
                    151: {
                    152:   if (this->target_ == NULL)
                    153:     return true;
                    154:   return target == this->target_;
                    155: }
                    156:
                    157: Parameters::Target_size_endianness
                    158: Parameters::size_and_endianness() const
                    159: {
                    160:   if (this->target().get_size() == 32)
                    161:     {
                    162:       if (!this->target().is_big_endian())
                    163:        {
                    164: #ifdef HAVE_TARGET_32_LITTLE
                    165:          return TARGET_32_LITTLE;
                    166: #else
                    167:          gold_unreachable();
                    168: #endif
                    169:        }
                    170:       else
                    171:        {
                    172: #ifdef HAVE_TARGET_32_BIG
                    173:          return TARGET_32_BIG;
                    174: #else
                    175:          gold_unreachable();
                    176: #endif
                    177:        }
                    178:     }
                    179:   else if (parameters->target().get_size() == 64)
                    180:     {
                    181:       if (!parameters->target().is_big_endian())
                    182:        {
                    183: #ifdef HAVE_TARGET_64_LITTLE
                    184:          return TARGET_64_LITTLE;
                    185: #else
                    186:          gold_unreachable();
                    187: #endif
                    188:        }
                    189:       else
                    190:        {
                    191: #ifdef HAVE_TARGET_64_BIG
                    192:          return TARGET_64_BIG;
                    193: #else
                    194:          gold_unreachable();
                    195: #endif
                    196:        }
                    197:     }
                    198:   else
                    199:     gold_unreachable();
                    200: }
                    201:
                    202: // If output endianness is specified in command line, check that it does
                    203: // not conflict with the target.
                    204:
                    205: void
                    206: Parameters::check_target_endianness()
                    207: {
                    208:   General_options::Endianness endianness = this->options().endianness();
                    209:   if (endianness != General_options::ENDIANNESS_NOT_SET)
                    210:     {
                    211:       bool big_endian;
                    212:       if (endianness == General_options::ENDIANNESS_BIG)
                    213:        big_endian = true;
                    214:       else
                    215:        {
                    216:          gold_assert(endianness == General_options::ENDIANNESS_LITTLE);
                    217:          big_endian = false;;
                    218:        }
                    219:
                    220:       if (this->target().is_big_endian() != big_endian)
                    221:        gold_error(_("input file does not match -EB/EL option"));
                    222:     }
                    223: }
                    224:
1.3       christos  225: void
                    226: Parameters::check_rodata_segment()
                    227: {
                    228:   if (this->options().user_set_Trodata_segment()
                    229:       && !this->options().rosegment()
                    230:       && !this->target().isolate_execinstr())
                    231:     gold_error(_("-Trodata-segment is meaningless without --rosegment"));
                    232: }
                    233:
1.1       christos  234: // Return the name of the entry symbol.
                    235:
                    236: const char*
                    237: Parameters::entry() const
                    238: {
                    239:   const char* ret = this->options().entry();
1.3       christos  240:   if (ret == NULL && parameters->target_valid())
                    241:     ret = parameters->target().entry_symbol_name();
1.1       christos  242:   return ret;
                    243: }
                    244:
                    245: // Set the incremental linking mode to INCREMENTAL_FULL.  Used when
                    246: // the linker determines that an incremental update is not possible.
                    247: // Returns false if the incremental mode was INCREMENTAL_UPDATE,
                    248: // indicating that the linker should exit if an update is not possible.
                    249:
                    250: bool
                    251: Parameters::set_incremental_full()
                    252: {
                    253:   gold_assert(this->incremental_mode_ != General_options::INCREMENTAL_OFF);
                    254:   if (this->incremental_mode_ == General_options::INCREMENTAL_UPDATE)
                    255:     return false;
                    256:   this->incremental_mode_ = General_options::INCREMENTAL_FULL;
                    257:   return true;
                    258: }
                    259:
                    260: // Return true if we need to prepare incremental linking information.
                    261:
                    262: bool
                    263: Parameters::incremental() const
                    264: {
                    265:   return this->incremental_mode_ != General_options::INCREMENTAL_OFF;
                    266: }
                    267:
                    268: // Return true if we are doing a full incremental link.
                    269:
                    270: bool
                    271: Parameters::incremental_full() const
                    272: {
                    273:   return this->incremental_mode_ == General_options::INCREMENTAL_FULL;
                    274: }
                    275:
                    276: // Return true if we are doing an incremental update.
                    277:
                    278: bool
                    279: Parameters::incremental_update() const
                    280: {
                    281:   return (this->incremental_mode_ == General_options::INCREMENTAL_UPDATE
                    282:          || this->incremental_mode_ == General_options::INCREMENTAL_AUTO);
                    283: }
                    284:
                    285: void
                    286: set_parameters_errors(Errors* errors)
                    287: { static_parameters.set_errors(errors); }
                    288:
                    289: void
                    290: set_parameters_timer(Timer* timer)
                    291: { static_parameters.set_timer(timer); }
                    292:
                    293: void
                    294: set_parameters_options(const General_options* options)
                    295: { static_parameters.set_options(options); }
                    296:
                    297: void
                    298: set_parameters_target(Target* target)
                    299: {
                    300:   static_parameters.set_target(target);
                    301: }
                    302:
                    303: void
                    304: set_parameters_doing_static_link(bool doing_static_link)
                    305: { static_parameters.set_doing_static_link(doing_static_link); }
                    306:
                    307: // Set the incremental linking mode to INCREMENTAL_FULL.  Used when
                    308: // the linker determines that an incremental update is not possible.
                    309: // Returns false if the incremental mode was INCREMENTAL_UPDATE,
                    310: // indicating that the linker should exit if an update is not possible.
                    311: bool
                    312: set_parameters_incremental_full()
                    313: { return static_parameters.set_incremental_full(); }
                    314:
                    315: // Force the target to be valid by using the default.  Use the
                    316: // --oformat option is set; this supports the x86_64 kernel build,
                    317: // which converts a binary file to an object file using -r --format
                    318: // binary --oformat elf32-i386 foo.o.  Otherwise use the configured
                    319: // default.
                    320:
                    321: void
                    322: parameters_force_valid_target()
                    323: {
                    324:   if (parameters->target_valid())
                    325:     return;
                    326:
                    327:   gold_assert(parameters->options_valid());
                    328:   if (parameters->options().user_set_oformat())
                    329:     {
                    330:       const char* bfd_name = parameters->options().oformat();
                    331:       Target* target = select_target_by_bfd_name(bfd_name);
                    332:       if (target != NULL)
                    333:        {
                    334:          set_parameters_target(target);
                    335:          return;
                    336:        }
                    337:
                    338:       gold_error(_("unrecognized output format %s"), bfd_name);
                    339:     }
                    340:
                    341:   if (parameters->options().user_set_m())
                    342:     {
                    343:       const char* emulation = parameters->options().m();
                    344:       Target* target = select_target_by_emulation(emulation);
                    345:       if (target != NULL)
                    346:        {
                    347:          set_parameters_target(target);
                    348:          return;
                    349:        }
                    350:
                    351:       gold_error(_("unrecognized emulation %s"), emulation);
                    352:     }
                    353:
                    354:   // The GOLD_DEFAULT_xx macros are defined by the configure script.
                    355:   bool is_big_endian;
                    356:   General_options::Endianness endianness = parameters->options().endianness();
                    357:   if (endianness == General_options::ENDIANNESS_BIG)
                    358:     is_big_endian = true;
                    359:   else if (endianness == General_options::ENDIANNESS_LITTLE)
                    360:     is_big_endian = false;
                    361:   else
                    362:     is_big_endian = GOLD_DEFAULT_BIG_ENDIAN;
                    363:
                    364:   Target* target = select_target(NULL, 0,
                    365:                                 elfcpp::GOLD_DEFAULT_MACHINE,
                    366:                                 GOLD_DEFAULT_SIZE,
                    367:                                 is_big_endian,
                    368:                                 elfcpp::GOLD_DEFAULT_OSABI,
                    369:                                 0);
                    370:
                    371:   if (target == NULL)
                    372:     {
                    373:       gold_assert(is_big_endian != GOLD_DEFAULT_BIG_ENDIAN);
                    374:       gold_fatal(_("no supported target for -EB/-EL option"));
                    375:     }
                    376:
                    377:   set_parameters_target(target);
                    378: }
                    379:
                    380: // Clear the current target, for testing.
                    381:
                    382: void
                    383: parameters_clear_target()
                    384: {
                    385:   static_parameters.clear_target();
                    386: }
                    387:
                    388: } // End namespace gold.

CVSweb <webmaster@jp.NetBSD.org>