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