binutils-gold-i386-gnu-property-notes.patch 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. diff --git a/gold/i386.cc b/gold/i386.cc
  2. index bf209fe9a86..31161ff091c 100644
  3. --- a/gold/i386.cc
  4. +++ b/gold/i386.cc
  5. @@ -360,7 +360,11 @@ class Target_i386 : public Sized_target<32, false>
  6. got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
  7. got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL),
  8. rel_irelative_(NULL), copy_relocs_(elfcpp::R_386_COPY),
  9. - got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
  10. + got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
  11. + isa_1_used_(0), isa_1_needed_(0),
  12. + feature_1_(0), feature_2_used_(0), feature_2_needed_(0),
  13. + object_isa_1_used_(0), object_feature_1_(0),
  14. + object_feature_2_used_(0), seen_first_object_(false)
  15. { }
  16. // Process the relocations to determine unreferenced sections for
  17. @@ -859,6 +863,21 @@ class Target_i386 : public Sized_target<32, false>
  18. this->rel_dyn_section(layout));
  19. }
  20. + // Record a target-specific program property in the .note.gnu.property
  21. + // section.
  22. + void
  23. + record_gnu_property(unsigned int, unsigned int, size_t,
  24. + const unsigned char*, const Object*);
  25. +
  26. + // Merge the target-specific program properties from the current object.
  27. + void
  28. + merge_gnu_properties(const Object*);
  29. +
  30. + // Finalize the target-specific program properties and add them back to
  31. + // the layout.
  32. + void
  33. + do_finalize_gnu_properties(Layout*) const;
  34. +
  35. // Information about this specific target which we pass to the
  36. // general Target structure.
  37. static const Target::Target_info i386_info;
  38. @@ -898,6 +917,26 @@ class Target_i386 : public Sized_target<32, false>
  39. unsigned int got_mod_index_offset_;
  40. // True if the _TLS_MODULE_BASE_ symbol has been defined.
  41. bool tls_base_symbol_defined_;
  42. +
  43. + // Target-specific program properties, from .note.gnu.property section.
  44. + // Each bit represents a specific feature.
  45. + uint32_t isa_1_used_;
  46. + uint32_t isa_1_needed_;
  47. + uint32_t feature_1_;
  48. + uint32_t feature_2_used_;
  49. + uint32_t feature_2_needed_;
  50. + // Target-specific properties from the current object.
  51. + // These bits get ORed into ISA_1_USED_ after all properties for the object
  52. + // have been processed. But if either is all zeroes (as when the property
  53. + // is absent from an object), the result should be all zeroes.
  54. + // (See PR ld/23486.)
  55. + uint32_t object_isa_1_used_;
  56. + // These bits get ANDed into FEATURE_1_ after all properties for the object
  57. + // have been processed.
  58. + uint32_t object_feature_1_;
  59. + uint32_t object_feature_2_used_;
  60. + // Whether we have seen our first object, for use in initializing FEATURE_1_.
  61. + bool seen_first_object_;
  62. };
  63. const Target::Target_info Target_i386::i386_info =
  64. @@ -1042,6 +1081,126 @@ Target_i386::rel_irelative_section(Layout* layout)
  65. return this->rel_irelative_;
  66. }
  67. +// Record a target-specific program property from the .note.gnu.property
  68. +// section.
  69. +void
  70. +Target_i386::record_gnu_property(
  71. + unsigned int, unsigned int pr_type,
  72. + size_t pr_datasz, const unsigned char* pr_data,
  73. + const Object* object)
  74. +{
  75. + uint32_t val = 0;
  76. +
  77. + switch (pr_type)
  78. + {
  79. + case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
  80. + case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
  81. + case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
  82. + case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
  83. + case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
  84. + case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
  85. + case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
  86. + case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
  87. + case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
  88. + if (pr_datasz != 4)
  89. + {
  90. + gold_warning(_("%s: corrupt .note.gnu.property section "
  91. + "(pr_datasz for property %d is not 4)"),
  92. + object->name().c_str(), pr_type);
  93. + return;
  94. + }
  95. + val = elfcpp::Swap<32, false>::readval(pr_data);
  96. + break;
  97. + default:
  98. + gold_warning(_("%s: unknown program property type 0x%x "
  99. + "in .note.gnu.property section"),
  100. + object->name().c_str(), pr_type);
  101. + break;
  102. + }
  103. +
  104. + switch (pr_type)
  105. + {
  106. + case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
  107. + this->object_isa_1_used_ |= val;
  108. + break;
  109. + case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
  110. + this->isa_1_needed_ |= val;
  111. + break;
  112. + case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
  113. + // If we see multiple feature props in one object, OR them together.
  114. + this->object_feature_1_ |= val;
  115. + break;
  116. + case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
  117. + this->object_feature_2_used_ |= val;
  118. + break;
  119. + case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
  120. + this->feature_2_needed_ |= val;
  121. + break;
  122. + }
  123. +}
  124. +
  125. +// Merge the target-specific program properties from the current object.
  126. +void
  127. +Target_i386::merge_gnu_properties(const Object*)
  128. +{
  129. + if (this->seen_first_object_)
  130. + {
  131. + // If any object is missing the ISA_1_USED property, we must omit
  132. + // it from the output file.
  133. + if (this->object_isa_1_used_ == 0)
  134. + this->isa_1_used_ = 0;
  135. + else if (this->isa_1_used_ != 0)
  136. + this->isa_1_used_ |= this->object_isa_1_used_;
  137. + this->feature_1_ &= this->object_feature_1_;
  138. + // If any object is missing the FEATURE_2_USED property, we must
  139. + // omit it from the output file.
  140. + if (this->object_feature_2_used_ == 0)
  141. + this->feature_2_used_ = 0;
  142. + else if (this->feature_2_used_ != 0)
  143. + this->feature_2_used_ |= this->object_feature_2_used_;
  144. + }
  145. + else
  146. + {
  147. + this->isa_1_used_ = this->object_isa_1_used_;
  148. + this->feature_1_ = this->object_feature_1_;
  149. + this->feature_2_used_ = this->object_feature_2_used_;
  150. + this->seen_first_object_ = true;
  151. + }
  152. + this->object_isa_1_used_ = 0;
  153. + this->object_feature_1_ = 0;
  154. + this->object_feature_2_used_ = 0;
  155. +}
  156. +
  157. +static inline void
  158. +add_property(Layout* layout, unsigned int pr_type, uint32_t val)
  159. +{
  160. + unsigned char buf[4];
  161. + elfcpp::Swap<32, false>::writeval(buf, val);
  162. + layout->add_gnu_property(elfcpp::NT_GNU_PROPERTY_TYPE_0, pr_type, 4, buf);
  163. +}
  164. +
  165. +// Finalize the target-specific program properties and add them back to
  166. +// the layout.
  167. +void
  168. +Target_i386::do_finalize_gnu_properties(Layout* layout) const
  169. +{
  170. + if (this->isa_1_used_ != 0)
  171. + add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_USED,
  172. + this->isa_1_used_);
  173. + if (this->isa_1_needed_ != 0)
  174. + add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED,
  175. + this->isa_1_needed_);
  176. + if (this->feature_1_ != 0)
  177. + add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND,
  178. + this->feature_1_);
  179. + if (this->feature_2_used_ != 0)
  180. + add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED,
  181. + this->feature_2_used_);
  182. + if (this->feature_2_needed_ != 0)
  183. + add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED,
  184. + this->feature_2_needed_);
  185. +}
  186. +
  187. // Write the first three reserved words of the .got.plt section.
  188. // The remainder of the section is written while writing the PLT
  189. // in Output_data_plt_i386::do_write.