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