1// parameters.cc -- general parameters for a link using gold 2 3// Copyright (C) 2006-2017 Free Software Foundation, Inc. 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 30namespace gold 31{ 32 33// Our local version of the variable, which is not const. 34 35static Parameters static_parameters; 36 37// The global variable. 38 39const Parameters* parameters = &static_parameters; 40 41// A helper class to set the target once. 42 43class 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 61static 62Set_parameters_target_once set_parameters_target_once(&static_parameters); 63 64// Class Parameters. 65 66Parameters::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 74void 75Parameters::set_errors(Errors* errors) 76{ 77 gold_assert(this->errors_ == NULL); 78 this->errors_ = errors; 79} 80 81void 82Parameters::set_timer(Timer* timer) 83{ 84 gold_assert(this->timer_ == NULL); 85 this->timer_ = timer; 86} 87 88void 89Parameters::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 106void 107Parameters::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 114void 115Parameters::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 123void 124Parameters::set_target_once(Target* target) 125{ 126 gold_assert(this->target_ == NULL); 127 this->target_ = target; 128 target->select_as_default_target(); 129 if (this->options_valid()) 130 { 131 this->check_target_endianness(); 132 this->check_rodata_segment(); 133 } 134} 135 136// Clear the target, for testing. 137 138void 139Parameters::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 149bool 150Parameters::is_compatible_target(const Target* target) const 151{ 152 if (this->target_ == NULL) 153 return true; 154 return target == this->target_; 155} 156 157Parameters::Target_size_endianness 158Parameters::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 205void 206Parameters::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 225void 226Parameters::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 234// Return the name of the entry symbol. 235 236const char* 237Parameters::entry() const 238{ 239 const char* ret = this->options().entry(); 240 if (ret == NULL && parameters->target_valid()) 241 ret = parameters->target().entry_symbol_name(); 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 250bool 251Parameters::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 262bool 263Parameters::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 270bool 271Parameters::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 278bool 279Parameters::incremental_update() const 280{ 281 return (this->incremental_mode_ == General_options::INCREMENTAL_UPDATE 282 || this->incremental_mode_ == General_options::INCREMENTAL_AUTO); 283} 284 285void 286set_parameters_errors(Errors* errors) 287{ static_parameters.set_errors(errors); } 288 289void 290set_parameters_timer(Timer* timer) 291{ static_parameters.set_timer(timer); } 292 293void 294set_parameters_options(const General_options* options) 295{ static_parameters.set_options(options); } 296 297void 298set_parameters_target(Target* target) 299{ 300 static_parameters.set_target(target); 301} 302 303void 304set_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. 311bool 312set_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 321void 322parameters_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 382void 383parameters_clear_target() 384{ 385 static_parameters.clear_target(); 386} 387 388} // End namespace gold. 389