+// A class to handle the PLT data.
+
+class Output_data_plt_x86_64 : public Output_section_data
+{
+ public:
+ typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section;
+
+ Output_data_plt_x86_64(Symbol_table*, Layout*, Output_data_got<64, false>*,
+ Output_data_space*);
+
+ // Add an entry to the PLT.
+ void
+ add_entry(Symbol* gsym);
+
+ // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
+ unsigned int
+ add_local_ifunc_entry(Sized_relobj<64, false>* relobj,
+ unsigned int local_sym_index);
+
+ // Add the reserved TLSDESC_PLT entry to the PLT.
+ void
+ reserve_tlsdesc_entry(unsigned int got_offset)
+ { this->tlsdesc_got_offset_ = got_offset; }
+
+ // Return true if a TLSDESC_PLT entry has been reserved.
+ bool
+ has_tlsdesc_entry() const
+ { return this->tlsdesc_got_offset_ != -1U; }
+
+ // Return the GOT offset for the reserved TLSDESC_PLT entry.
+ unsigned int
+ get_tlsdesc_got_offset() const
+ { return this->tlsdesc_got_offset_; }
+
+ // Return the offset of the reserved TLSDESC_PLT entry.
+ unsigned int
+ get_tlsdesc_plt_offset() const
+ { return (this->count_ + 1) * plt_entry_size; }
+
+ // Return the .rela.plt section data.
+ Reloc_section*
+ rela_plt()
+ { return this->rel_; }
+
+ // Return where the TLSDESC relocations should go.
+ Reloc_section*
+ rela_tlsdesc(Layout*);
+
+ // Return the number of PLT entries.
+ unsigned int
+ entry_count() const
+ { return this->count_; }
+
+ // Return the offset of the first non-reserved PLT entry.
+ static unsigned int
+ first_plt_entry_offset()
+ { return plt_entry_size; }
+
+ // Return the size of a PLT entry.
+ static unsigned int
+ get_plt_entry_size()
+ { return plt_entry_size; }
+
+ protected:
+ void
+ do_adjust_output_section(Output_section* os);
+
+ // Write to a map file.
+ void
+ do_print_to_mapfile(Mapfile* mapfile) const
+ { mapfile->print_output_data(this, _("** PLT")); }
+
+ private:
+ // The size of an entry in the PLT.
+ static const int plt_entry_size = 16;
+
+ // The first entry in the PLT.
+ // From the AMD64 ABI: "Unlike Intel386 ABI, this ABI uses the same
+ // procedure linkage table for both programs and shared objects."
+ static unsigned char first_plt_entry[plt_entry_size];
+
+ // Other entries in the PLT for an executable.
+ static unsigned char plt_entry[plt_entry_size];
+
+ // The reserved TLSDESC entry in the PLT for an executable.
+ static unsigned char tlsdesc_plt_entry[plt_entry_size];
+
+ // Set the final size.
+ void
+ set_final_data_size();
+
+ // Write out the PLT data.
+ void
+ do_write(Output_file*);
+
+ // The reloc section.
+ Reloc_section* rel_;
+ // The TLSDESC relocs, if necessary. These must follow the regular
+ // PLT relocs.
+ Reloc_section* tlsdesc_rel_;
+ // The .got section.
+ Output_data_got<64, false>* got_;
+ // The .got.plt section.
+ Output_data_space* got_plt_;
+ // The number of PLT entries.
+ unsigned int count_;
+ // Offset of the reserved TLSDESC_GOT entry when needed.
+ unsigned int tlsdesc_got_offset_;
+};