Fix issue where first reserved word of GOT is not initialized if there
authorCary Coutant <ccoutant@google.com>
Tue, 6 May 2014 18:40:04 +0000 (11:40 -0700)
committerCary Coutant <ccoutant@google.com>
Tue, 6 May 2014 21:29:42 +0000 (14:29 -0700)
is no PLT.

gold/
PR gold/16900
* i386.cc (Output_data_got_plt_i386): New class.
(Output_data_plt_i386::Output_data_plt_i386): Change type of got_plt
parameter. Change all callers.
(Output_data_plt_i386::layout_): Remove.
(Output_data_plt_i386::got_plt_): Change type.
(Target_i386::got_plt_): Change type. Change all references.
(Target_i386::got_section): Create instance of new class.
(Output_data_got_plt_i386::do_write): New function.
* x86_64.cc (Output_data_got_plt_x86_64): New class.
(Output_data_plt_x86_64::Output_data_plt_x86_64): Change type of got_plt
parameter. Change all callers.
(Output_data_plt_x86_64::layout_): Remove.
(Output_data_plt_x86_64::got_plt_): Change type.
(Target_x86_64::got_plt_): Change type. Change all references.
(Target_x86_64::got_section): Create instance of new class.
(Output_data_got_plt_x86_64::do_write): New function.
(Output_data_plt_x86_64::do_write): Don't write reserved words in GOT.
(Target_x86_64<size>::init_got_plt_for_update): Create instance of new
class.

gold/ChangeLog
gold/i386.cc
gold/x86_64.cc

index 52934f4..74a7512 100644 (file)
@@ -1,3 +1,26 @@
+2014-05-06  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/16900
+       * i386.cc (Output_data_got_plt_i386): New class.
+       (Output_data_plt_i386::Output_data_plt_i386): Change type of got_plt
+       parameter. Change all callers.
+       (Output_data_plt_i386::layout_): Remove.
+       (Output_data_plt_i386::got_plt_): Change type.
+       (Target_i386::got_plt_): Change type. Change all references.
+       (Target_i386::got_section): Create instance of new class.
+       (Output_data_got_plt_i386::do_write): New function.
+       * x86_64.cc (Output_data_got_plt_x86_64): New class.
+       (Output_data_plt_x86_64::Output_data_plt_x86_64): Change type of got_plt
+       parameter. Change all callers.
+       (Output_data_plt_x86_64::layout_): Remove.
+       (Output_data_plt_x86_64::got_plt_): Change type.
+       (Target_x86_64::got_plt_): Change type. Change all references.
+       (Target_x86_64::got_section): Create instance of new class.
+       (Output_data_got_plt_x86_64::do_write): New function.
+       (Output_data_plt_x86_64::do_write): Don't write reserved words in GOT.
+       (Target_x86_64<size>::init_got_plt_for_update): Create instance of new
+       class.
+
 2014-05-05  Cary Coutant  <ccoutant@google.com>
         
        * gdb-index.cc (Gdb_index_info_reader): Don't complain about language
index a2f7522..ed7f3f9 100644 (file)
@@ -47,6 +47,32 @@ namespace
 
 using namespace gold;
 
+// A class to handle the .got.plt section.
+
+class Output_data_got_plt_i386 : public Output_section_data_build
+{
+ public:
+  Output_data_got_plt_i386(Layout* layout)
+    : Output_section_data_build(4),
+      layout_(layout)
+  { }
+
+ protected:
+  // Write out the PLT data.
+  void
+  do_write(Output_file*);
+
+  // Write to a map file.
+  void
+  do_print_to_mapfile(Mapfile* mapfile) const
+  { mapfile->print_output_data(this, "** GOT PLT"); }
+
+ private:
+  // A pointer to the Layout class, so that we can find the .dynamic
+  // section when we write out the GOT PLT section.
+  Layout* layout_;
+};
+
 // A class to handle the PLT data.
 // This is an abstract base class that handles most of the linker details
 // but does not know the actual contents of PLT entries.  The derived
@@ -58,7 +84,7 @@ class Output_data_plt_i386 : public Output_section_data
   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, false> Reloc_section;
 
   Output_data_plt_i386(Layout*, uint64_t addralign,
-                      Output_data_space*, Output_data_space*);
+                      Output_data_got_plt_i386*, Output_data_space*);
 
   // Add an entry to the PLT.
   void
@@ -201,9 +227,6 @@ class Output_data_plt_i386 : public Output_section_data
     unsigned int got_offset;
   };
 
-  // A pointer to the Layout class, so that we can find the .dynamic
-  // section when we write out the GOT PLT section.
-  Layout* layout_;
   // The reloc section.
   Reloc_section* rel_;
   // The TLS_DESC relocations, if necessary.  These must follow the
@@ -213,7 +236,7 @@ class Output_data_plt_i386 : public Output_section_data
   // regular relocatoins and the TLS_DESC relocations.
   Reloc_section* irelative_rel_;
   // The .got.plt section.
-  Output_data_space* got_plt_;
+  Output_data_got_plt_i386* got_plt_;
   // The part of the .got.plt section used for IRELATIVE relocs.
   Output_data_space* got_irelative_;
   // The number of PLT entries.
@@ -236,7 +259,7 @@ class Output_data_plt_i386_standard : public Output_data_plt_i386
 {
  public:
   Output_data_plt_i386_standard(Layout* layout,
-                               Output_data_space* got_plt,
+                               Output_data_got_plt_i386* got_plt,
                                Output_data_space* got_irelative)
     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
   { }
@@ -267,7 +290,7 @@ class Output_data_plt_i386_exec : public Output_data_plt_i386_standard
 {
 public:
   Output_data_plt_i386_exec(Layout* layout,
-                           Output_data_space* got_plt,
+                           Output_data_got_plt_i386* got_plt,
                            Output_data_space* got_irelative)
     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
   { }
@@ -298,7 +321,7 @@ class Output_data_plt_i386_dyn : public Output_data_plt_i386_standard
 {
  public:
   Output_data_plt_i386_dyn(Layout* layout,
-                          Output_data_space* got_plt,
+                          Output_data_got_plt_i386* got_plt,
                           Output_data_space* got_irelative)
     : Output_data_plt_i386_standard(layout, got_plt, got_irelative)
   { }
@@ -506,14 +529,14 @@ class Target_i386 : public Sized_target<32, false>
   // This chooses the right PLT flavor for an executable or a shared object.
   Output_data_plt_i386*
   make_data_plt(Layout* layout,
-               Output_data_space* got_plt,
+               Output_data_got_plt_i386* got_plt,
                Output_data_space* got_irelative,
                bool dyn)
   { return this->do_make_data_plt(layout, got_plt, got_irelative, dyn); }
 
   virtual Output_data_plt_i386*
   do_make_data_plt(Layout* layout,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_i386* got_plt,
                   Output_data_space* got_irelative,
                   bool dyn)
   {
@@ -720,7 +743,7 @@ class Target_i386 : public Sized_target<32, false>
   got_section(Symbol_table*, Layout*);
 
   // Get the GOT PLT section.
-  Output_data_space*
+  Output_data_got_plt_i386*
   got_plt_section() const
   {
     gold_assert(this->got_plt_ != NULL);
@@ -813,7 +836,7 @@ class Target_i386 : public Sized_target<32, false>
   // The PLT section.
   Output_data_plt_i386* plt_;
   // The GOT PLT section.
-  Output_data_space* got_plt_;
+  Output_data_got_plt_i386* got_plt_;
   // The GOT section for IRELATIVE relocations.
   Output_data_space* got_irelative_;
   // The GOT section for TLSDESC relocations.
@@ -885,7 +908,7 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout)
                                       | elfcpp::SHF_WRITE),
                                      this->got_, got_order, true);
 
-      this->got_plt_ = new Output_data_space(4, "** GOT PLT");
+      this->got_plt_ = new Output_data_got_plt_i386(layout);
       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_WRITE),
@@ -972,18 +995,39 @@ Target_i386::rel_irelative_section(Layout* layout)
   return this->rel_irelative_;
 }
 
+// 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.
+
+void
+Output_data_got_plt_i386::do_write(Output_file* of)
+{
+  // The first entry in the GOT is the address of the .dynamic section
+  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
+  // We saved space for them when we created the section in
+  // Target_i386::got_section.
+  const off_t got_file_offset = this->offset();
+  gold_assert(this->data_size() >= 12);
+  unsigned char* const got_view = of->get_output_view(got_file_offset, 12);
+  Output_section* dynamic = this->layout_->dynamic_section();
+  uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
+  elfcpp::Swap<32, false>::writeval(got_view, dynamic_addr);
+  memset(got_view + 4, 0, 8);
+  of->write_output_view(got_file_offset, 12, got_view);
+}
+
 // Create the PLT section.  The ordinary .got section is an argument,
 // since we need to refer to the start.  We also create our own .got
 // section just for PLT entries.
 
 Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
                                           uint64_t addralign,
-                                          Output_data_space* got_plt,
+                                          Output_data_got_plt_i386* got_plt,
                                           Output_data_space* got_irelative)
   : Output_section_data(addralign),
-    layout_(layout), tls_desc_rel_(NULL),
-    irelative_rel_(NULL), got_plt_(got_plt), got_irelative_(got_irelative),
-    count_(0), irelative_count_(0), global_ifuncs_(), local_ifuncs_()
+    tls_desc_rel_(NULL), irelative_rel_(NULL), got_plt_(got_plt),
+    got_irelative_(got_irelative), count_(0), irelative_count_(0),
+    global_ifuncs_(), local_ifuncs_()
 {
   this->rel_ = new Reloc_section(false);
   layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
@@ -1323,6 +1367,7 @@ Output_data_plt_i386::do_write(Output_file* of)
   const section_size_type got_size =
     convert_to_section_size_type(this->got_plt_->data_size()
                                 + this->got_irelative_->data_size());
+
   unsigned char* const got_view = of->get_output_view(got_file_offset,
                                                      got_size);
 
@@ -1334,18 +1379,9 @@ Output_data_plt_i386::do_write(Output_file* of)
   this->fill_first_plt_entry(pov, got_address);
   pov += this->get_plt_entry_size();
 
-  unsigned char* got_pov = got_view;
-
-  // The first entry in the GOT is the address of the .dynamic section
-  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
-  // We saved space for them when we created the section in
-  // Target_i386::got_section.
-  Output_section* dynamic = this->layout_->dynamic_section();
-  uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
-  elfcpp::Swap<32, false>::writeval(got_pov, dynamic_addr);
-  got_pov += 4;
-  memset(got_pov, 0, 8);
-  got_pov += 8;
+  // The first three entries in the GOT are reserved, and are written
+  // by Output_data_got_plt_i386::do_write.
+  unsigned char* got_pov = got_view + 12;
 
   const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
 
@@ -3834,7 +3870,7 @@ class Output_data_plt_i386_nacl : public Output_data_plt_i386
 {
  public:
   Output_data_plt_i386_nacl(Layout* layout,
-                           Output_data_space* got_plt,
+                           Output_data_got_plt_i386* got_plt,
                            Output_data_space* got_irelative)
     : Output_data_plt_i386(layout, plt_entry_size, got_plt, got_irelative)
   { }
@@ -3863,7 +3899,7 @@ class Output_data_plt_i386_nacl_exec : public Output_data_plt_i386_nacl
 {
 public:
   Output_data_plt_i386_nacl_exec(Layout* layout,
-                                Output_data_space* got_plt,
+                                Output_data_got_plt_i386* got_plt,
                                 Output_data_space* got_irelative)
     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
   { }
@@ -3892,7 +3928,7 @@ class Output_data_plt_i386_nacl_dyn : public Output_data_plt_i386_nacl
 {
  public:
   Output_data_plt_i386_nacl_dyn(Layout* layout,
-                               Output_data_space* got_plt,
+                               Output_data_got_plt_i386* got_plt,
                                Output_data_space* got_irelative)
     : Output_data_plt_i386_nacl(layout, got_plt, got_irelative)
   { }
@@ -3926,7 +3962,7 @@ class Target_i386_nacl : public Target_i386
  protected:
   virtual Output_data_plt_i386*
   do_make_data_plt(Layout* layout,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_i386* got_plt,
                   Output_data_space* got_irelative,
                   bool dyn)
   {
index aa9e5b4..255ebb9 100644 (file)
@@ -48,6 +48,37 @@ namespace
 
 using namespace gold;
 
+// A class to handle the .got.plt section.
+
+class Output_data_got_plt_x86_64 : public Output_section_data_build
+{
+ public:
+  Output_data_got_plt_x86_64(Layout* layout)
+    : Output_section_data_build(8),
+      layout_(layout)
+  { }
+
+  Output_data_got_plt_x86_64(Layout* layout, off_t data_size)
+    : Output_section_data_build(data_size, 8),
+      layout_(layout)
+  { }
+
+ protected:
+  // Write out the PLT data.
+  void
+  do_write(Output_file*);
+
+  // Write to a map file.
+  void
+  do_print_to_mapfile(Mapfile* mapfile) const
+  { mapfile->print_output_data(this, "** GOT PLT"); }
+
+ private:
+  // A pointer to the Layout class, so that we can find the .dynamic
+  // section when we write out the GOT PLT section.
+  Layout* layout_;
+};
+
 // A class to handle the PLT data.
 // This is an abstract base class that handles most of the linker details
 // but does not know the actual contents of PLT entries.  The derived
@@ -61,9 +92,9 @@ class Output_data_plt_x86_64 : public Output_section_data
 
   Output_data_plt_x86_64(Layout* layout, uint64_t addralign,
                         Output_data_got<64, false>* got,
-                        Output_data_space* got_plt,
+                        Output_data_got_plt_x86_64* got_plt,
                         Output_data_space* got_irelative)
-    : Output_section_data(addralign), layout_(layout), tlsdesc_rel_(NULL),
+    : Output_section_data(addralign), tlsdesc_rel_(NULL),
       irelative_rel_(NULL), got_(got), got_plt_(got_plt),
       got_irelative_(got_irelative), count_(0), irelative_count_(0),
       tlsdesc_got_offset_(-1U), free_list_()
@@ -71,12 +102,12 @@ class Output_data_plt_x86_64 : public Output_section_data
 
   Output_data_plt_x86_64(Layout* layout, uint64_t plt_entry_size,
                         Output_data_got<64, false>* got,
-                        Output_data_space* got_plt,
+                        Output_data_got_plt_x86_64* got_plt,
                         Output_data_space* got_irelative,
                         unsigned int plt_count)
     : Output_section_data((plt_count + 1) * plt_entry_size,
                          plt_entry_size, false),
-      layout_(layout), tlsdesc_rel_(NULL), irelative_rel_(NULL), got_(got),
+      tlsdesc_rel_(NULL), irelative_rel_(NULL), got_(got),
       got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
       irelative_count_(0), tlsdesc_got_offset_(-1U), free_list_()
   {
@@ -268,9 +299,6 @@ class Output_data_plt_x86_64 : public Output_section_data
   void
   do_write(Output_file*);
 
-  // A pointer to the Layout class, so that we can find the .dynamic
-  // section when we write out the GOT PLT section.
-  Layout* layout_;
   // The reloc section.
   Reloc_section* rel_;
   // The TLSDESC relocs, if necessary.  These must follow the regular
@@ -282,7 +310,7 @@ class Output_data_plt_x86_64 : public Output_section_data
   // The .got section.
   Output_data_got<64, false>* got_;
   // The .got.plt section.
-  Output_data_space* got_plt_;
+  Output_data_got_plt_x86_64* got_plt_;
   // The part of the .got.plt section used for IRELATIVE relocs.
   Output_data_space* got_irelative_;
   // The number of PLT entries.
@@ -303,7 +331,7 @@ class Output_data_plt_x86_64_standard : public Output_data_plt_x86_64<size>
  public:
   Output_data_plt_x86_64_standard(Layout* layout,
                                  Output_data_got<64, false>* got,
-                                 Output_data_space* got_plt,
+                                 Output_data_got_plt_x86_64* got_plt,
                                  Output_data_space* got_irelative)
     : Output_data_plt_x86_64<size>(layout, plt_entry_size,
                                   got, got_plt, got_irelative)
@@ -311,7 +339,7 @@ class Output_data_plt_x86_64_standard : public Output_data_plt_x86_64<size>
 
   Output_data_plt_x86_64_standard(Layout* layout,
                                  Output_data_got<64, false>* got,
-                                 Output_data_space* got_plt,
+                                 Output_data_got_plt_x86_64* got_plt,
                                  Output_data_space* got_irelative,
                                  unsigned int plt_count)
     : Output_data_plt_x86_64<size>(layout, plt_entry_size,
@@ -618,7 +646,7 @@ class Target_x86_64 : public Sized_target<size, false>
   Output_data_plt_x86_64<size>*
   make_data_plt(Layout* layout,
                Output_data_got<64, false>* got,
-               Output_data_space* got_plt,
+               Output_data_got_plt_x86_64* got_plt,
                Output_data_space* got_irelative)
   {
     return this->do_make_data_plt(layout, got, got_plt, got_irelative);
@@ -627,7 +655,7 @@ class Target_x86_64 : public Sized_target<size, false>
   Output_data_plt_x86_64<size>*
   make_data_plt(Layout* layout,
                Output_data_got<64, false>* got,
-               Output_data_space* got_plt,
+               Output_data_got_plt_x86_64* got_plt,
                Output_data_space* got_irelative,
                unsigned int plt_count)
   {
@@ -638,7 +666,7 @@ class Target_x86_64 : public Sized_target<size, false>
   virtual Output_data_plt_x86_64<size>*
   do_make_data_plt(Layout* layout,
                   Output_data_got<64, false>* got,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_x86_64* got_plt,
                   Output_data_space* got_irelative)
   {
     return new Output_data_plt_x86_64_standard<size>(layout, got, got_plt,
@@ -648,7 +676,7 @@ class Target_x86_64 : public Sized_target<size, false>
   virtual Output_data_plt_x86_64<size>*
   do_make_data_plt(Layout* layout,
                   Output_data_got<64, false>* got,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_x86_64* got_plt,
                   Output_data_space* got_irelative,
                   unsigned int plt_count)
   {
@@ -847,7 +875,7 @@ class Target_x86_64 : public Sized_target<size, false>
   got_section(Symbol_table*, Layout*);
 
   // Get the GOT PLT section.
-  Output_data_space*
+  Output_data_got_plt_x86_64*
   got_plt_section() const
   {
     gold_assert(this->got_plt_ != NULL);
@@ -958,7 +986,7 @@ class Target_x86_64 : public Sized_target<size, false>
   // The PLT section.
   Output_data_plt_x86_64<size>* plt_;
   // The GOT PLT section.
-  Output_data_space* got_plt_;
+  Output_data_got_plt_x86_64* got_plt_;
   // The GOT section for IRELATIVE relocations.
   Output_data_space* got_irelative_;
   // The GOT section for TLSDESC relocations.
@@ -1074,7 +1102,7 @@ Target_x86_64<size>::got_section(Symbol_table* symtab, Layout* layout)
                                       | elfcpp::SHF_WRITE),
                                      this->got_, got_order, true);
 
-      this->got_plt_ = new Output_data_space(8, "** GOT PLT");
+      this->got_plt_ = new Output_data_got_plt_x86_64(layout);
       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_WRITE),
@@ -1163,6 +1191,27 @@ Target_x86_64<size>::rela_irelative_section(Layout* layout)
   return this->rela_irelative_;
 }
 
+// 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.
+
+void
+Output_data_got_plt_x86_64::do_write(Output_file* of)
+{
+  // The first entry in the GOT is the address of the .dynamic section
+  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
+  // We saved space for them when we created the section in
+  // Target_x86_64::got_section.
+  const off_t got_file_offset = this->offset();
+  gold_assert(this->data_size() >= 24);
+  unsigned char* const got_view = of->get_output_view(got_file_offset, 24);
+  Output_section* dynamic = this->layout_->dynamic_section();
+  uint64_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
+  elfcpp::Swap<64, false>::writeval(got_view, dynamic_addr);
+  memset(got_view + 8, 0, 16);
+  of->write_output_view(got_file_offset, 24, got_view);
+}
+
 // Initialize the PLT section.
 
 template<int size>
@@ -1198,7 +1247,7 @@ Output_data_plt_x86_64<size>::add_entry(Symbol_table* symtab, Layout* layout,
   unsigned int* pcount;
   unsigned int offset;
   unsigned int reserved;
-  Output_data_space* got;
+  Output_section_data_build* got;
   if (gsym->type() == elfcpp::STT_GNU_IFUNC
       && gsym->can_use_relative_reloc(false))
     {
@@ -1605,18 +1654,9 @@ Output_data_plt_x86_64<size>::do_write(Output_file* of)
   this->fill_first_plt_entry(pov, got_address, plt_address);
   pov += this->get_plt_entry_size();
 
-  unsigned char* got_pov = got_view;
-
-  // The first entry in the GOT is the address of the .dynamic section
-  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
-  // We saved space for them when we created the section in
-  // Target_x86_64::got_section.
-  Output_section* dynamic = this->layout_->dynamic_section();
-  uint32_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
-  elfcpp::Swap<64, false>::writeval(got_pov, dynamic_addr);
-  got_pov += 8;
-  memset(got_pov, 0, 16);
-  got_pov += 16;
+  // The first three entries in the GOT are reserved, and are written
+  // by Output_data_got_plt_x86_64::do_write.
+  unsigned char* got_pov = got_view + 24;
 
   unsigned int plt_offset = this->get_plt_entry_size();
   unsigned int got_offset = 24;
@@ -1777,7 +1817,7 @@ Target_x86_64<size>::init_got_plt_for_update(Symbol_table* symtab,
                                  true);
 
   // Add the three reserved entries.
-  this->got_plt_ = new Output_data_space((plt_count + 3) * 8, 8, "** GOT PLT");
+  this->got_plt_ = new Output_data_got_plt_x86_64(layout, (plt_count + 3) * 8);
   layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
                                  (elfcpp::SHF_ALLOC
                                   | elfcpp::SHF_WRITE),
@@ -4500,7 +4540,7 @@ class Output_data_plt_x86_64_nacl : public Output_data_plt_x86_64<size>
  public:
   Output_data_plt_x86_64_nacl(Layout* layout,
                              Output_data_got<64, false>* got,
-                             Output_data_space* got_plt,
+                             Output_data_got_plt_x86_64* got_plt,
                              Output_data_space* got_irelative)
     : Output_data_plt_x86_64<size>(layout, plt_entry_size,
                                   got, got_plt, got_irelative)
@@ -4508,7 +4548,7 @@ class Output_data_plt_x86_64_nacl : public Output_data_plt_x86_64<size>
 
   Output_data_plt_x86_64_nacl(Layout* layout,
                              Output_data_got<64, false>* got,
-                             Output_data_space* got_plt,
+                             Output_data_got_plt_x86_64* got_plt,
                              Output_data_space* got_irelative,
                              unsigned int plt_count)
     : Output_data_plt_x86_64<size>(layout, plt_entry_size,
@@ -4581,7 +4621,7 @@ class Target_x86_64_nacl : public Target_x86_64<size>
   virtual Output_data_plt_x86_64<size>*
   do_make_data_plt(Layout* layout,
                   Output_data_got<64, false>* got,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_x86_64* got_plt,
                   Output_data_space* got_irelative)
   {
     return new Output_data_plt_x86_64_nacl<size>(layout, got, got_plt,
@@ -4591,7 +4631,7 @@ class Target_x86_64_nacl : public Target_x86_64<size>
   virtual Output_data_plt_x86_64<size>*
   do_make_data_plt(Layout* layout,
                   Output_data_got<64, false>* got,
-                  Output_data_space* got_plt,
+                  Output_data_got_plt_x86_64* got_plt,
                   Output_data_space* got_irelative,
                   unsigned int plt_count)
   {