OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [parameters.cc] - Blame information for rev 163

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 khays
// parameters.cc -- general parameters for a link using gold
2
 
3 159 khays
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 27 khays
// 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 163 khays
   : errors_(NULL), timer_(NULL), options_(NULL), target_(NULL),
68 27 khays
     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 163 khays
Parameters::set_timer(Timer* timer)
83
{
84
  gold_assert(this->timer_ == NULL);
85
  this->timer_ = timer;
86
}
87
 
88
void
89 27 khays
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
  if (this->options_valid())
129
    this->check_target_endianness();
130
}
131
 
132
// Clear the target, for testing.
133
 
134
void
135
Parameters::clear_target()
136
{
137
  this->target_ = NULL;
138
  // We need a new Set_parameters_target_once so that we can set the
139
  // target again.
140
  this->set_parameters_target_once_ = new Set_parameters_target_once(this);
141
}
142
 
143
// Return whether TARGET is compatible with the target we are using.
144
 
145
bool
146
Parameters::is_compatible_target(const Target* target) const
147
{
148
  if (this->target_ == NULL)
149
    return true;
150
  return target == this->target_;
151
}
152
 
153
Parameters::Target_size_endianness
154
Parameters::size_and_endianness() const
155
{
156
  if (this->target().get_size() == 32)
157
    {
158
      if (!this->target().is_big_endian())
159
        {
160
#ifdef HAVE_TARGET_32_LITTLE
161
          return TARGET_32_LITTLE;
162
#else
163
          gold_unreachable();
164
#endif
165
        }
166
      else
167
        {
168
#ifdef HAVE_TARGET_32_BIG
169
          return TARGET_32_BIG;
170
#else
171
          gold_unreachable();
172
#endif
173
        }
174
    }
175
  else if (parameters->target().get_size() == 64)
176
    {
177
      if (!parameters->target().is_big_endian())
178
        {
179
#ifdef HAVE_TARGET_64_LITTLE
180
          return TARGET_64_LITTLE;
181
#else
182
          gold_unreachable();
183
#endif
184
        }
185
      else
186
        {
187
#ifdef HAVE_TARGET_64_BIG
188
          return TARGET_64_BIG;
189
#else
190
          gold_unreachable();
191
#endif
192
        }
193
    }
194
  else
195
    gold_unreachable();
196
}
197
 
198
// If output endianness is specified in command line, check that it does
199
// not conflict with the target.
200
 
201
void
202
Parameters::check_target_endianness()
203
{
204
  General_options::Endianness endianness = this->options().endianness();
205
  if (endianness != General_options::ENDIANNESS_NOT_SET)
206
    {
207
      bool big_endian;
208
      if (endianness == General_options::ENDIANNESS_BIG)
209
        big_endian = true;
210
      else
211
        {
212
          gold_assert(endianness == General_options::ENDIANNESS_LITTLE);
213
          big_endian = false;;
214
        }
215
 
216
      if (this->target().is_big_endian() != big_endian)
217
        gold_error(_("input file does not match -EB/EL option"));
218
    }
219
}
220
 
221
// Return the name of the entry symbol.
222
 
223
const char*
224
Parameters::entry() const
225
{
226
  const char* ret = this->options().entry();
227
  if (ret == NULL)
228
    {
229
      // FIXME: Need to support target specific entry symbol.
230
      ret = "_start";
231
    }
232
  return ret;
233
}
234
 
235
// Set the incremental linking mode to INCREMENTAL_FULL.  Used when
236
// the linker determines that an incremental update is not possible.
237
// Returns false if the incremental mode was INCREMENTAL_UPDATE,
238
// indicating that the linker should exit if an update is not possible.
239
 
240
bool
241
Parameters::set_incremental_full()
242
{
243
  gold_assert(this->incremental_mode_ != General_options::INCREMENTAL_OFF);
244
  if (this->incremental_mode_ == General_options::INCREMENTAL_UPDATE)
245
    return false;
246
  this->incremental_mode_ = General_options::INCREMENTAL_FULL;
247
  return true;
248
}
249
 
250
// Return true if we need to prepare incremental linking information.
251
 
252
bool
253
Parameters::incremental() const
254
{
255
  return this->incremental_mode_ != General_options::INCREMENTAL_OFF;
256
}
257
 
258 159 khays
// Return true if we are doing a full incremental link.
259
 
260
bool
261
Parameters::incremental_full() const
262
{
263
  return this->incremental_mode_ == General_options::INCREMENTAL_FULL;
264
}
265
 
266 27 khays
// Return true if we are doing an incremental update.
267
 
268
bool
269
Parameters::incremental_update() const
270
{
271
  return (this->incremental_mode_ == General_options::INCREMENTAL_UPDATE
272
          || this->incremental_mode_ == General_options::INCREMENTAL_AUTO);
273
}
274
 
275
void
276
set_parameters_errors(Errors* errors)
277
{ static_parameters.set_errors(errors); }
278
 
279
void
280 163 khays
set_parameters_timer(Timer* timer)
281
{ static_parameters.set_timer(timer); }
282
 
283
void
284 27 khays
set_parameters_options(const General_options* options)
285
{ static_parameters.set_options(options); }
286
 
287
void
288
set_parameters_target(Target* target)
289
{
290
  static_parameters.set_target(target);
291
  target->select_as_default_target();
292
}
293
 
294
void
295
set_parameters_doing_static_link(bool doing_static_link)
296
{ static_parameters.set_doing_static_link(doing_static_link); }
297
 
298
// Set the incremental linking mode to INCREMENTAL_FULL.  Used when
299
// the linker determines that an incremental update is not possible.
300
// Returns false if the incremental mode was INCREMENTAL_UPDATE,
301
// indicating that the linker should exit if an update is not possible.
302
bool
303
set_parameters_incremental_full()
304
{ return static_parameters.set_incremental_full(); }
305
 
306
// Force the target to be valid by using the default.  Use the
307
// --oformat option is set; this supports the x86_64 kernel build,
308
// which converts a binary file to an object file using -r --format
309
// binary --oformat elf32-i386 foo.o.  Otherwise use the configured
310
// default.
311
 
312
void
313
parameters_force_valid_target()
314
{
315
  if (parameters->target_valid())
316
    return;
317
 
318
  gold_assert(parameters->options_valid());
319
  if (parameters->options().user_set_oformat())
320
    {
321 159 khays
      const char* bfd_name = parameters->options().oformat();
322
      Target* target = select_target_by_bfd_name(bfd_name);
323 27 khays
      if (target != NULL)
324
        {
325
          set_parameters_target(target);
326
          return;
327
        }
328
 
329 159 khays
      gold_error(_("unrecognized output format %s"), bfd_name);
330 27 khays
    }
331
 
332 159 khays
  if (parameters->options().user_set_m())
333
    {
334
      const char* emulation = parameters->options().m();
335
      Target* target = select_target_by_emulation(emulation);
336
      if (target != NULL)
337
        {
338
          set_parameters_target(target);
339
          return;
340
        }
341
 
342
      gold_error(_("unrecognized emulation %s"), emulation);
343
    }
344
 
345 27 khays
  // The GOLD_DEFAULT_xx macros are defined by the configure script.
346
  bool is_big_endian;
347
  General_options::Endianness endianness = parameters->options().endianness();
348
  if (endianness == General_options::ENDIANNESS_BIG)
349
    is_big_endian = true;
350
  else if (endianness == General_options::ENDIANNESS_LITTLE)
351
    is_big_endian = false;
352
  else
353
    is_big_endian = GOLD_DEFAULT_BIG_ENDIAN;
354
 
355
  Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE,
356
                                 GOLD_DEFAULT_SIZE,
357
                                 is_big_endian,
358
                                 elfcpp::GOLD_DEFAULT_OSABI,
359
                                 0);
360 159 khays
 
361
  if (target == NULL)
362
    {
363
      gold_assert(is_big_endian != GOLD_DEFAULT_BIG_ENDIAN);
364
      gold_fatal(_("no supported target for -EB/-EL option"));
365
    }
366
 
367 27 khays
  set_parameters_target(target);
368
}
369
 
370
// Clear the current target, for testing.
371
 
372
void
373
parameters_clear_target()
374
{
375
  static_parameters.clear_target();
376
}
377
 
378
} // End namespace gold.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.