1 // parameters.cc -- general parameters for a link using gold 2 3 // Copyright (C) 2006-2016 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 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; 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 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 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 234 // Return the name of the entry symbol. 235 236 const char* 237 Parameters::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 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. 389