1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
|
// attributes.h -- object attributes for gold -*- C++ -*-
// Copyright (C) 2009-2020 Free Software Foundation, Inc.
// Written by Doug Kwan <dougkwan@google.com>.
// This file contains code adapted from BFD.
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
// Handle object attributes.
#ifndef GOLD_ATTRIBUTES_H
#define GOLD_ATTRIBUTES_H
#include <map>
#include "parameters.h"
#include "target.h"
#include "output.h"
#include "reduced_debug_output.h"
namespace gold
{
// Object attribute values. The attribute tag is not stored in this object.
class Object_attribute
{
public:
// The value of an object attribute. The type indicates whether the
// attribute holds and integer, a string, or both. It can also indicate that
// there can be no default (i.e. all values must be written to file, even
// zero).
enum
{
ATTR_TYPE_FLAG_INT_VAL = (1 << 0),
ATTR_TYPE_FLAG_STR_VAL = (1 << 1),
ATTR_TYPE_FLAG_NO_DEFAULT = (1 << 2)
};
// Object attributes may either be defined by the processor ABI, index
// OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
// (and possibly also processor-specific), index OBJ_ATTR_GNU.
enum
{
OBJ_ATTR_PROC,
OBJ_ATTR_GNU,
OBJ_ATTR_FIRST = OBJ_ATTR_PROC,
OBJ_ATTR_LAST = OBJ_ATTR_GNU
};
// The following object attribute tags are taken as generic, for all
// targets and for "gnu" where there is no target standard.
enum
{
Tag_NULL = 0,
Tag_File = 1,
Tag_Section = 2,
Tag_Symbol = 3,
Tag_compatibility = 32
};
Object_attribute()
: type_(0), int_value_(0), string_value_()
{ }
// Copying constructor. We need to implement this to copy the string value.
Object_attribute(const Object_attribute& oa)
: type_(oa.type_), int_value_(oa.int_value_), string_value_(oa.string_value_)
{ }
~Object_attribute()
{ }
// Assignment operator. We need to implement this to copy the string value.
Object_attribute&
operator=(const Object_attribute& source)
{
this->type_ = source.type_;
this->int_value_ = source.int_value_;
this->string_value_ = source.string_value_;
return *this;
}
// Return attribute type.
int
type() const
{ return this->type_; }
// Set attribute type.
void
set_type(int type)
{ this->type_ = type; }
// Return integer value.
unsigned int
int_value() const
{ return this->int_value_; }
// Set integer value.
void
set_int_value(unsigned int i)
{ this->int_value_ = i; }
// Return string value.
const std::string&
string_value() const
{ return this->string_value_; }
// Set string value.
void
set_string_value(const std::string& s)
{ this->string_value_ = s; }
void
set_string_value(const char* s)
{ this->string_value_ = s; }
// Whether attribute type has integer value.
static bool
attribute_type_has_int_value(int type)
{ return (type & ATTR_TYPE_FLAG_INT_VAL) != 0; }
// Whether attribute type has string value.
static bool
attribute_type_has_string_value(int type)
{ return (type & ATTR_TYPE_FLAG_STR_VAL) != 0; }
// Whether attribute type has no default value.
static bool
attribute_type_has_no_default(int type)
{ return (type & ATTR_TYPE_FLAG_NO_DEFAULT) != 0; }
// Whether this has default value (0/"").
bool
is_default_attribute() const;
// Return ULEB128 encoded size of tag and attribute.
size_t
size(int tag) const;
// Whether this matches another object attribute in merging.
bool
matches(const Object_attribute& oa) const;
// Write to attribute with tag to BUFFER.
void
write(int tag, std::vector<unsigned char>* buffer) const;
// Determine what arguments an attribute tag takes.
static int
arg_type(int vendor, int tag)
{
switch (vendor)
{
case OBJ_ATTR_PROC:
return parameters->target().attribute_arg_type(tag);
case OBJ_ATTR_GNU:
return Object_attribute::gnu_arg_type(tag);
default:
gold_unreachable();
}
}
private:
// Determine whether a GNU object attribute tag takes an integer, a
// string or both. */
static int
gnu_arg_type(int tag)
{
// Except for Tag_compatibility, for GNU attributes we follow the
// same rule ARM ones > 32 follow: odd-numbered tags take strings
// and even-numbered tags take integers. In addition, tag & 2 is
// nonzero for architecture-independent tags and zero for
// architecture-dependent ones.
if (tag == Object_attribute::Tag_compatibility)
return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
else
return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
}
// Attribute type.
int type_;
// Integer value.
int int_value_;
// String value.
std::string string_value_;
};
// This class contains attributes of a particular vendor.
class Vendor_object_attributes
{
public:
// The maximum number of known object attributes for any target.
static const int NUM_KNOWN_ATTRIBUTES = 71;
Vendor_object_attributes(int vendor)
: vendor_(vendor), other_attributes_()
{ }
// Copying constructor.
Vendor_object_attributes(const Vendor_object_attributes&);
~Vendor_object_attributes()
{
for (Other_attributes::iterator p = this->other_attributes_.begin();
p != this->other_attributes_.end();
++p)
delete p->second;
}
// Size of this in number of bytes.
size_t
size() const;
// Name of this written vendor subsection.
const char*
name() const
{
return (this->vendor_ == Object_attribute::OBJ_ATTR_PROC
? parameters->target().attributes_vendor()
: "gnu");
}
// Return an array of known attributes.
Object_attribute*
known_attributes()
{ return &this->known_attributes_[0]; }
const Object_attribute*
known_attributes() const
{ return &this->known_attributes_[0]; }
typedef std::map<int, Object_attribute*> Other_attributes;
// Return attributes other than the known ones.
Other_attributes*
other_attributes()
{ return &this->other_attributes_; }
const Other_attributes*
other_attributes() const
{ return &this->other_attributes_; }
// Return a new attribute associated with TAG.
Object_attribute*
new_attribute(int tag);
// Get an attribute
Object_attribute*
get_attribute(int tag);
const Object_attribute*
get_attribute(int tag) const;
// Write to BUFFER.
void
write(std::vector<unsigned char>* buffer) const;
private:
// Vendor of the object attributes.
int vendor_;
// Attributes with known tags. There are store in an array for fast
// access.
Object_attribute known_attributes_[NUM_KNOWN_ATTRIBUTES];
// Attributes with known tags. There are stored in a sorted container.
Other_attributes other_attributes_;
};
// This class contains contents of an attributes section.
class Attributes_section_data
{
public:
// Construct an Attributes_section_data object by parsing section contents
// in VIEW of SIZE.
Attributes_section_data(const unsigned char* view, section_size_type size);
// Copying constructor.
Attributes_section_data(const Attributes_section_data& asd)
{
for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
vendor <= Object_attribute::OBJ_ATTR_LAST;
++vendor)
this->vendor_object_attributes_[vendor] =
new Vendor_object_attributes(*asd.vendor_object_attributes_[vendor]);
}
~Attributes_section_data()
{
for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
vendor <= Object_attribute::OBJ_ATTR_LAST;
++vendor)
delete this->vendor_object_attributes_[vendor];
}
// Return the size of this as number of bytes.
size_t
size() const;
// Return an array of known attributes.
Object_attribute*
known_attributes(int vendor)
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->known_attributes();
}
const Object_attribute*
known_attributes(int vendor) const
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->known_attributes();
}
// Return the other attributes.
Vendor_object_attributes::Other_attributes*
other_attributes(int vendor)
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->other_attributes();
}
// Return the other attributes.
const Vendor_object_attributes::Other_attributes*
other_attributes(int vendor) const
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->other_attributes();
}
// Return an attribute.
Object_attribute*
get_attribute(int vendor, int tag)
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->get_attribute(tag);
}
const Object_attribute*
get_attribute(int vendor, int tag) const
{
gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
return this->vendor_object_attributes_[vendor]->get_attribute(tag);
}
// Merge target-independent attributes from another Attributes_section_data
// of an object called NAME.
void
merge(const char* name, const Attributes_section_data* pasd);
// Write to byte stream in an unsigned char vector.
void
write(std::vector<unsigned char>*) const;
private:
// For convenience.
static const int OBJ_ATTR_FIRST = Object_attribute::OBJ_ATTR_FIRST;
static const int OBJ_ATTR_LAST = Object_attribute::OBJ_ATTR_LAST;
// Vendor object attributes.
Vendor_object_attributes* vendor_object_attributes_[OBJ_ATTR_LAST+1];
};
// This class is used for writing out an Attribute_section_data.
class Output_attributes_section_data : public Output_section_data
{
public:
Output_attributes_section_data(const Attributes_section_data& asd)
: Output_section_data(1), attributes_section_data_(asd)
{ }
protected:
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** attributes")); }
// Write the data to the output file.
void
do_write(Output_file*);
// Set final data size.
void
set_final_data_size()
{ this->set_data_size(attributes_section_data_.size()); }
private:
// Attributes_section_data corresponding to this.
const Attributes_section_data& attributes_section_data_;
};
} // End namespace gold.
#endif // !defined(GOLD_ATTRIBUTES_H)
|