attributes.cc 13 KB

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