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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [attributes.cc] - Blame information for rev 28

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 khays
// attributes.cc -- object attributes for gold
2
 
3
// Copyright 2009 Free Software Foundation, Inc.
4
// Written by Doug Kwan <dougkwan@google.com>.
5
// This file contains code adapted from BFD.
6
 
7
// This file is part of gold.
8
 
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 3 of the License, or
12
// (at your option) any later version.
13
 
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
 
19
// You should have received a copy of the GNU General Public License
20
// along with this program; if not, write to the Free Software
21
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
// MA 02110-1301, USA.
23
 
24
#include "gold.h"
25
 
26
#include <limits>
27
 
28
#include "attributes.h"
29
#include "elfcpp.h"
30
#include "target.h"
31
#include "parameters.h"
32
#include "int_encoding.h"
33
 
34
namespace gold
35
{
36
 
37
// Object_attribute methods.
38
 
39
// Return size of attribute encode in ULEB128.
40
 
41
size_t
42
Object_attribute::size(int tag) const
43
{
44
  // Attributes with default values are not written out.
45
  if (this->is_default_attribute())
46
    return 0;
47
 
48
  size_t size = get_length_as_unsigned_LEB_128(tag);
49
  if (Object_attribute::attribute_type_has_int_value(this->type_))
50
    size += get_length_as_unsigned_LEB_128(this->int_value_);
51
  if (Object_attribute::attribute_type_has_string_value(this->type_))
52
    size += this->string_value_.size() + 1;
53
  return size;
54
}
55
 
56
// Whether this has the default value (0/"").
57
 
58
bool
59
Object_attribute::is_default_attribute() const
60
{
61
  if (Object_attribute::attribute_type_has_int_value(this->type_)
62
      && this->int_value_ != 0)
63
    return false;
64
  if (Object_attribute::attribute_type_has_string_value(this->type_)
65
      && !this->string_value_.empty())
66
    return false;
67
  if (Object_attribute::attribute_type_has_no_default(this->type_))
68
    return false;
69
 
70
  return true;
71
}
72
 
73
// Whether this matches another Object_attribute OA in merging.
74
// Two Object_attributes match if they have the same values.
75
 
76
bool
77
Object_attribute::matches(const Object_attribute& oa) const
78
{
79
  return ((this->int_value_ != oa.int_value_)
80
          && (this->string_value_ == oa.string_value_));
81
}
82
 
83
// Write this with TAG to a BUFFER.
84
 
85
void
86
Object_attribute::write(
87
    int tag,
88
    std::vector<unsigned char>* buffer) const
89
{
90
  // No need to write default attributes.
91
  if (this->is_default_attribute())
92
    return;
93
 
94
  // Write tag.
95
  write_unsigned_LEB_128(buffer, convert_types<uint64_t, int>(tag));
96
 
97
  // Write integer value.
98
  if (Object_attribute::attribute_type_has_int_value(this->type_))
99
    write_unsigned_LEB_128(buffer,
100
                           convert_types<uint64_t, int>(this->int_value_));
101
 
102
  // Write string value.
103
  if (Object_attribute::attribute_type_has_string_value(this->type_))
104
    {
105
      const unsigned char* start =
106
        reinterpret_cast<const unsigned char*>(this->string_value_.c_str());
107
      const unsigned char* end = start + this->string_value_.size() + 1;
108
      buffer->insert(buffer->end(), start, end);
109
    }
110
}
111
 
112
// Vendor_object_attributes methods.
113
 
114
// Copying constructor.
115
 
116
Vendor_object_attributes::Vendor_object_attributes(
117
    const Vendor_object_attributes& voa)
118
{
119
  this->vendor_ = voa.vendor_;
120
 
121
  for (int i = 0; i < NUM_KNOWN_ATTRIBUTES; ++i)
122
    this->known_attributes_[i] = voa.known_attributes_[i];
123
 
124
  // We do not handle attribute deletion.  So this must be empty.
125
  gold_assert(this->other_attributes_.empty());
126
 
127
  for (Other_attributes::const_iterator p = voa.other_attributes_.begin();
128
       p != voa.other_attributes_.end();
129
       ++p)
130
    this->other_attributes_[p->first] = new Object_attribute(*(p->second));
131
}
132
 
133
// Size of this in number of bytes.
134
 
135
size_t
136
Vendor_object_attributes::size() const
137
{
138
  if (this->name() == NULL)
139
    return 0;
140
 
141
  size_t data_size = 0;
142
  for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
143
    data_size += this->known_attributes_[i].size(i);
144
 
145
  for (Other_attributes::const_iterator p = this->other_attributes_.begin();
146
       p != this->other_attributes_.end();
147
       ++p)
148
    data_size += p->second->size(p->first);
149
 
150
  // <size> <vendor_name> NUL 0x1 <size>
151
  return ((data_size != 0
152
           || this->vendor_ == Object_attribute::OBJ_ATTR_PROC)
153
          ? data_size + strlen(this->name()) + 2 + 2 * 4
154
          : 0);
155
}
156
 
157
// Return a new attribute associated with TAG.
158
 
159
Object_attribute*
160
Vendor_object_attributes::new_attribute(int tag)
161
{
162
  int type = Object_attribute::arg_type(this->vendor_, tag);
163
 
164
  if (tag < NUM_KNOWN_ATTRIBUTES)
165
    {
166
      this->known_attributes_[tag].set_type(type);
167
      return &this->known_attributes_[tag];
168
    }
169
  else
170
    {
171
      Object_attribute* attr = new Object_attribute();
172
 
173
      // This should be the first time we insert this.
174
      std::pair<Other_attributes::iterator, bool> ins =
175
        this->other_attributes_.insert(std::make_pair(tag, attr));
176
      gold_assert(ins.second);
177
 
178
      attr->set_type(type);
179
      return attr;
180
    }
181
}
182
 
183
// Return an attribute associated with TAG.
184
 
185
Object_attribute*
186
Vendor_object_attributes::get_attribute(int tag)
187
{
188
  if (tag < NUM_KNOWN_ATTRIBUTES)
189
    return &this->known_attributes_[tag];
190
  else
191
    {
192
      Other_attributes::iterator p =
193
        this->other_attributes_.find(tag);
194
      return p != this->other_attributes_.end() ? p->second : NULL;
195
    }
196
}
197
 
198
const Object_attribute*
199
Vendor_object_attributes::get_attribute(int tag) const
200
{
201
  if (tag < NUM_KNOWN_ATTRIBUTES)
202
    return &this->known_attributes_[tag];
203
  else
204
    {
205
      Other_attributes::const_iterator p =
206
        this->other_attributes_.find(tag);
207
      return p != this->other_attributes_.end() ? p->second : NULL;
208
    }
209
}
210
 
211
// Write attributes to BUFFER.
212
 
213
void
214
Vendor_object_attributes::write(std::vector<unsigned char>* buffer) const
215
{
216
  // Write subsection size.
217
  size_t voa_size = this->size();
218
  uint32_t voa_size_as_u32 = convert_types<uint32_t, size_t>(voa_size);
219
  insert_into_vector<32>(buffer, voa_size_as_u32);
220
 
221
  // Write vendor name.
222
  const unsigned char* vendor_start =
223
    reinterpret_cast<const unsigned char*>(this->name());
224
  size_t vendor_length = strlen(this->name()) + 1;
225
  const unsigned char* vendor_end = vendor_start + vendor_length;
226
  buffer->insert(buffer->end(), vendor_start, vendor_end);
227
 
228
  // Write file tag.
229
  buffer->push_back(Object_attribute::Tag_File);
230
 
231
  // Write attributes size.
232
  uint32_t attributes_size_as_u32 =
233
    convert_types<uint32_t, size_t>(voa_size - 4 - vendor_length);
234
  insert_into_vector<32>(buffer, attributes_size_as_u32);
235
 
236
  // Write known attributes, skipping any defaults.
237
  for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
238
    {
239
      // A target may write known attributes in a special order. 
240
      // Call target hook to remap tags.  Attributes_order is the identity
241
      // function if no re-ordering is required.
242
      int tag = parameters->target().attributes_order(i);
243
      this->known_attributes_[tag].write(tag, buffer);
244
    }
245
 
246
  // Write other attributes.
247
  for (Other_attributes::const_iterator q = this->other_attributes_.begin();
248
       q != this->other_attributes_.end();
249
       ++q)
250
    q->second->write(q->first, buffer);
251
}
252
 
253
// Attributes_section_data methods.
254
 
255
// Compute encoded size of this.
256
 
257
size_t
258
Attributes_section_data::size() const
259
{
260
  size_t data_size = 0;
261
  for(int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
262
    data_size += this->vendor_object_attributes_[vendor]->size();
263
 
264
  // 'A' <sections for each vendor>
265
  return data_size != 0 ? data_size + 1 : 0;
266
}
267
 
268
// Construct an Attributes_section_data object by parsing section contents
269
// specified by VIEW and SIZE.
270
 
271
Attributes_section_data::Attributes_section_data(
272
    const unsigned char* view,
273
    section_size_type size)
274
{
275
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
276
    this->vendor_object_attributes_[vendor] =
277
      new Vendor_object_attributes(vendor);
278
 
279
  const unsigned char* p = view;
280
  p = view;
281
  if (size > 0 && p != NULL && *(p++) == 'A')
282
    {
283
      size--;
284
      while (size > 0)
285
        {
286
          // Size of vendor attributes section.
287
          section_size_type section_size =
288
            convert_to_section_size_type(read_from_pointer<32>(&p));
289
 
290
          if (section_size > size)
291
            section_size = size;
292
          size -= section_size;
293
 
294
          const char* section_name = reinterpret_cast<const char*>(p);
295
          section_size_type section_name_size = strlen(section_name) + 1;
296
          section_size -= section_name_size + 4;
297
 
298
          int vendor;
299
          const char* std_section = parameters->target().attributes_vendor();
300
          if (std_section != NULL && strcmp(section_name, std_section) == 0)
301
            vendor = Object_attribute::OBJ_ATTR_PROC;
302
          else if (strcmp(section_name, "gnu") == 0)
303
            vendor = Object_attribute::OBJ_ATTR_GNU;
304
          else
305
            {
306
              // Other vendor section.  Ignore it.
307
              p += section_name_size + section_size;
308
              continue;
309
            }
310
          p += section_name_size;
311
 
312
          while (section_size > 0)
313
            {
314
              const unsigned char* subsection_start = p;
315
 
316
              // Read vendor subsection index and size.
317
              size_t uleb128_len;
318
              uint64_t val = read_unsigned_LEB_128(p, &uleb128_len);
319
              p += uleb128_len;
320
 
321
              int tag = convert_types<int, uint64_t>(val);
322
              section_size_type subsection_size =
323
                convert_to_section_size_type(read_from_pointer<32>(&p));
324
              section_size -= subsection_size;
325
              subsection_size -= (p - subsection_start);
326
 
327
              const unsigned char* end = p + subsection_size;
328
              switch (tag)
329
                {
330
                case Object_attribute::Tag_File:
331
                  while (p < end)
332
                    {
333
                      val = read_unsigned_LEB_128(p, &uleb128_len);
334
                      p += uleb128_len;
335
                      tag = convert_types<int, uint64_t>(val);
336
                      Vendor_object_attributes* pvoa =
337
                        this->vendor_object_attributes_[vendor];
338
                      Object_attribute* attr = pvoa->new_attribute(tag);
339
                      const char* string_arg;
340
                      unsigned int int_arg;
341
 
342
                      int type = Object_attribute::arg_type(vendor, tag);
343
                      switch (type
344
                              & (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
345
                                 | Object_attribute::ATTR_TYPE_FLAG_STR_VAL))
346
                        {
347
                        case (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
348
                              | Object_attribute::ATTR_TYPE_FLAG_STR_VAL):
349
                          val = read_unsigned_LEB_128(p, &uleb128_len);
350
                          p += uleb128_len;
351
                          int_arg = convert_types<unsigned int, uint64_t>(val);
352
                          string_arg = reinterpret_cast<const char *>(p);
353
                          attr->set_int_value(int_arg);
354
                          p += strlen(string_arg) + 1;
355
                          break;
356
                        case Object_attribute::ATTR_TYPE_FLAG_STR_VAL:
357
                          string_arg = reinterpret_cast<const char *>(p);
358
                          attr->set_string_value(string_arg);
359
                          p += strlen(string_arg) + 1;
360
                          break;
361
                        case Object_attribute::ATTR_TYPE_FLAG_INT_VAL:
362
                          val = read_unsigned_LEB_128(p, &uleb128_len);
363
                          p += uleb128_len;
364
                          int_arg = convert_types<unsigned int, uint64_t>(val);
365
                          attr->set_int_value(int_arg);
366
                          break;
367
                        default:
368
                          gold_unreachable();
369
                        }
370
                    }
371
                  break;
372
                case Object_attribute::Tag_Section:
373
                case Object_attribute::Tag_Symbol:
374
                  // Don't have anywhere convenient to attach these.
375
                  // Fall through for now.
376
                default:
377
                  // Ignore things we don't know about.
378
                  p += subsection_size;
379
                  subsection_size = 0;
380
                  break;
381
                }
382
            }
383
        }
384
    }
385
}
386
 
387
// Merge target-independent attributes from another Attribute_section_data
388
// ASD from an object called NAME into this.
389
 
390
void
391
Attributes_section_data::merge(
392
    const char* name,
393
    const Attributes_section_data* pasd)
394
{
395
  // The only common attribute is currently Tag_compatibility,
396
  // accepted in both processor and "gnu" sections.
397
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
398
    {
399
      // Handle Tag_compatibility.  The tags are only compatible if the flags
400
      // are identical and, if the flags are '1', the strings are identical.
401
      // If the flags are non-zero, then we can only use the string "gnu".
402
      const Object_attribute* in_attr =
403
        &pasd->known_attributes(vendor)[Object_attribute::Tag_compatibility];
404
      Object_attribute* out_attr =
405
        &this->known_attributes(vendor)[Object_attribute::Tag_compatibility];
406
 
407
      if (in_attr->int_value() > 0
408
          && in_attr->string_value() != "gnu")
409
        {
410
          gold_error(_("%s: must be processed by '%s' toolchain"),
411
                     name, in_attr->string_value().c_str());
412
          return;
413
        }
414
 
415
      if (in_attr->int_value() != out_attr->int_value()
416
          || in_attr->string_value() != out_attr->string_value())
417
        {
418
          gold_error(_("%s: object tag '%d, %s' is "
419
                       "incompatible with tag '%d, %s'"),
420
                     name, in_attr->int_value(),
421
                     in_attr->string_value().c_str(),
422
                     out_attr->int_value(),
423
                     out_attr->string_value().c_str());
424
        }
425
    }
426
}
427
 
428
// Write to a buffer.
429
 
430
void
431
Attributes_section_data::write(std::vector<unsigned char>* buffer) const
432
{
433
  buffer->push_back('A');
434
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
435
    if (this->vendor_object_attributes_[vendor]->size() != 0)
436
      this->vendor_object_attributes_[vendor]->write(buffer);
437
}
438
 
439
// Methods for Output_attributes_section_data.
440
 
441
// Write attributes section data to file OF.
442
 
443
void
444
Output_attributes_section_data::do_write(Output_file* of)
445
{
446
  off_t offset = this->offset();
447
  const section_size_type oview_size =
448
    convert_to_section_size_type(this->data_size());
449
  unsigned char* const oview = of->get_output_view(offset, oview_size);
450
 
451
  std::vector<unsigned char> buffer;
452
  this->attributes_section_data_.write(&buffer);
453
  gold_assert(convert_to_section_size_type(buffer.size()) == oview_size);
454
  memcpy(oview, &buffer.front(), buffer.size());
455
  of->write_output_view(this->offset(), oview_size, oview);
456
}
457
 
458
} // End namespace gold.

powered by: WebSVN 2.1.0

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