123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- 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.
|