Blame SOURCES/binutils-gold-i386-gnu-property-notes.patch

0c89c8
diff -rupN --no-dereference binutils-2.37/gold/i386.cc binutils-2.37-new/gold/i386.cc
0c89c8
--- binutils-2.37/gold/i386.cc	2021-07-08 13:37:20.000000000 +0200
0c89c8
+++ binutils-2.37-new/gold/i386.cc	2021-07-24 21:59:31.051686692 +0200
0c89c8
@@ -360,7 +360,11 @@ class Target_i386 : public Sized_target<
0c89c8
       got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
0c89c8
       got_tlsdesc_(NULL), global_offset_table_(NULL), rel_dyn_(NULL),
0c89c8
       rel_irelative_(NULL), copy_relocs_(elfcpp::R_386_COPY),
0c89c8
-      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
0c89c8
+      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
0c89c8
+      isa_1_used_(0), isa_1_needed_(0),
0c89c8
+      feature_1_(0), feature_2_used_(0), feature_2_needed_(0),
0c89c8
+      object_isa_1_used_(0), object_feature_1_(0),
0c89c8
+      object_feature_2_used_(0), seen_first_object_(false)
0c89c8
   { }
0c89c8
 
0c89c8
   // Process the relocations to determine unreferenced sections for
0c89c8
@@ -859,6 +863,21 @@ class Target_i386 : public Sized_target<
0c89c8
 				  this->rel_dyn_section(layout));
0c89c8
   }
0c89c8
 
0c89c8
+  // Record a target-specific program property in the .note.gnu.property
0c89c8
+  // section.
0c89c8
+  void
0c89c8
+  record_gnu_property(unsigned int, unsigned int, size_t,
0c89c8
+		      const unsigned char*, const Object*);
0c89c8
+
0c89c8
+  // Merge the target-specific program properties from the current object.
0c89c8
+  void
0c89c8
+  merge_gnu_properties(const Object*);
0c89c8
+
0c89c8
+  // Finalize the target-specific program properties and add them back to
0c89c8
+  // the layout.
0c89c8
+  void
0c89c8
+  do_finalize_gnu_properties(Layout*) const;
0c89c8
+
0c89c8
   // Information about this specific target which we pass to the
0c89c8
   // general Target structure.
0c89c8
   static const Target::Target_info i386_info;
0c89c8
@@ -898,6 +917,26 @@ class Target_i386 : public Sized_target<
0c89c8
   unsigned int got_mod_index_offset_;
0c89c8
   // True if the _TLS_MODULE_BASE_ symbol has been defined.
0c89c8
   bool tls_base_symbol_defined_;
0c89c8
+
0c89c8
+  // Target-specific program properties, from .note.gnu.property section.
0c89c8
+  // Each bit represents a specific feature.
0c89c8
+  uint32_t isa_1_used_;
0c89c8
+  uint32_t isa_1_needed_;
0c89c8
+  uint32_t feature_1_;
0c89c8
+  uint32_t feature_2_used_;
0c89c8
+  uint32_t feature_2_needed_;
0c89c8
+  // Target-specific properties from the current object.
0c89c8
+  // These bits get ORed into ISA_1_USED_ after all properties for the object
0c89c8
+  // have been processed. But if either is all zeroes (as when the property
0c89c8
+  // is absent from an object), the result should be all zeroes.
0c89c8
+  // (See PR ld/23486.)
0c89c8
+  uint32_t object_isa_1_used_;
0c89c8
+  // These bits get ANDed into FEATURE_1_ after all properties for the object
0c89c8
+  // have been processed.
0c89c8
+  uint32_t object_feature_1_;
0c89c8
+  uint32_t object_feature_2_used_;
0c89c8
+  // Whether we have seen our first object, for use in initializing FEATURE_1_.
0c89c8
+  bool seen_first_object_;
0c89c8
 };
0c89c8
 
0c89c8
 const Target::Target_info Target_i386::i386_info =
0c89c8
@@ -1042,6 +1081,126 @@ Target_i386::rel_irelative_section(Layou
0c89c8
   return this->rel_irelative_;
0c89c8
 }
0c89c8
 
0c89c8
+// Record a target-specific program property from the .note.gnu.property
0c89c8
+// section.
0c89c8
+void
0c89c8
+Target_i386::record_gnu_property(
0c89c8
+    unsigned int, unsigned int pr_type,
0c89c8
+    size_t pr_datasz, const unsigned char* pr_data,
0c89c8
+    const Object* object)
0c89c8
+{
0c89c8
+  uint32_t val = 0;
0c89c8
+
0c89c8
+  switch (pr_type)
0c89c8
+    {
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
0c89c8
+      if (pr_datasz != 4)
0c89c8
+	{
0c89c8
+	  gold_warning(_("%s: corrupt .note.gnu.property section "
0c89c8
+			 "(pr_datasz for property %d is not 4)"),
0c89c8
+		       object->name().c_str(), pr_type);
0c89c8
+	  return;
0c89c8
+	}
0c89c8
+      val = elfcpp::Swap<32, false>::readval(pr_data);
0c89c8
+      break;
0c89c8
+    default:
0c89c8
+      gold_warning(_("%s: unknown program property type 0x%x "
0c89c8
+		     "in .note.gnu.property section"),
0c89c8
+		   object->name().c_str(), pr_type);
0c89c8
+      break;
0c89c8
+    }
0c89c8
+
0c89c8
+  switch (pr_type)
0c89c8
+    {
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_ISA_1_USED:
0c89c8
+      this->object_isa_1_used_ |= val;
0c89c8
+      break;
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED:
0c89c8
+      this->isa_1_needed_ |= val;
0c89c8
+      break;
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND:
0c89c8
+      // If we see multiple feature props in one object, OR them together.
0c89c8
+      this->object_feature_1_ |= val;
0c89c8
+      break;
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED:
0c89c8
+      this->object_feature_2_used_ |= val;
0c89c8
+      break;
0c89c8
+    case elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED:
0c89c8
+      this->feature_2_needed_ |= val;
0c89c8
+      break;
0c89c8
+    }
0c89c8
+}
0c89c8
+
0c89c8
+// Merge the target-specific program properties from the current object.
0c89c8
+void
0c89c8
+Target_i386::merge_gnu_properties(const Object*)
0c89c8
+{
0c89c8
+  if (this->seen_first_object_)
0c89c8
+    {
0c89c8
+      // If any object is missing the ISA_1_USED property, we must omit
0c89c8
+      // it from the output file.
0c89c8
+      if (this->object_isa_1_used_ == 0)
0c89c8
+	this->isa_1_used_ = 0;
0c89c8
+      else if (this->isa_1_used_ != 0)
0c89c8
+	this->isa_1_used_ |= this->object_isa_1_used_;
0c89c8
+      this->feature_1_ &= this->object_feature_1_;
0c89c8
+      // If any object is missing the FEATURE_2_USED property, we must
0c89c8
+      // omit it from the output file.
0c89c8
+      if (this->object_feature_2_used_ == 0)
0c89c8
+	this->feature_2_used_ = 0;
0c89c8
+      else if (this->feature_2_used_ != 0)
0c89c8
+	this->feature_2_used_ |= this->object_feature_2_used_;
0c89c8
+    }
0c89c8
+  else
0c89c8
+    {
0c89c8
+      this->isa_1_used_ = this->object_isa_1_used_;
0c89c8
+      this->feature_1_ = this->object_feature_1_;
0c89c8
+      this->feature_2_used_ = this->object_feature_2_used_;
0c89c8
+      this->seen_first_object_ = true;
0c89c8
+    }
0c89c8
+  this->object_isa_1_used_ = 0;
0c89c8
+  this->object_feature_1_ = 0;
0c89c8
+  this->object_feature_2_used_ = 0;
0c89c8
+}
0c89c8
+
0c89c8
+static inline void
0c89c8
+add_property(Layout* layout, unsigned int pr_type, uint32_t val)
0c89c8
+{
0c89c8
+  unsigned char buf[4];
0c89c8
+  elfcpp::Swap<32, false>::writeval(buf, val);
0c89c8
+  layout->add_gnu_property(elfcpp::NT_GNU_PROPERTY_TYPE_0, pr_type, 4, buf);
0c89c8
+}
0c89c8
+
0c89c8
+// Finalize the target-specific program properties and add them back to
0c89c8
+// the layout.
0c89c8
+void
0c89c8
+Target_i386::do_finalize_gnu_properties(Layout* layout) const
0c89c8
+{
0c89c8
+  if (this->isa_1_used_ != 0)
0c89c8
+    add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_USED,
0c89c8
+		 this->isa_1_used_);
0c89c8
+  if (this->isa_1_needed_ != 0)
0c89c8
+    add_property(layout, elfcpp::GNU_PROPERTY_X86_ISA_1_NEEDED,
0c89c8
+		 this->isa_1_needed_);
0c89c8
+  if (this->feature_1_ != 0)
0c89c8
+    add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_1_AND,
0c89c8
+		 this->feature_1_);
0c89c8
+  if (this->feature_2_used_ != 0)
0c89c8
+    add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_USED,
0c89c8
+		 this->feature_2_used_);
0c89c8
+  if (this->feature_2_needed_ != 0)
0c89c8
+    add_property(layout, elfcpp::GNU_PROPERTY_X86_FEATURE_2_NEEDED,
0c89c8
+		 this->feature_2_needed_);
0c89c8
+}
0c89c8
+
0c89c8
 // Write the first three reserved words of the .got.plt section.
0c89c8
 // The remainder of the section is written while writing the PLT
0c89c8
 // in Output_data_plt_i386::do_write.