| 1 | // attributes.cc -- object attributes for gold |
| 2 | |
| 3 | // Copyright (C) 2009-2018 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. |