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 159

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

powered by: WebSVN 2.1.0

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