* incremental-dump.cc (find_input_containing_global): Replace
authorCary Coutant <ccoutant@google.com>
Tue, 24 Apr 2012 22:05:28 +0000 (22:05 +0000)
committerCary Coutant <ccoutant@google.com>
Tue, 24 Apr 2012 22:05:28 +0000 (22:05 +0000)
magic number with symbolic constant.
(dump_incremental_inputs): Update version number.
* incremental.cc (Output_section_incremental_inputs): Update version
number; import symbolic constants from Incremental_inputs_reader.
(Incremental_inputs::create_data_sections): Align relocations
section correctly for 64-bit targets.
(Output_section_incremental_inputs::set_final_data_size): Use symbolic
constants; add padding.
(Output_section_incremental_inputs::write_header): Add assert for
header_size.
(Output_section_incremental_inputs::write_input_files): Add assert
for input_entry_size.
(Output_section_incremental_inputs::write_info_blocks): Add padding;
add assert for object_info_size, input_section_entry_size,
global_sym_entry_size.
* incremental.h (Incremental_inputs_reader): Add symbolic constants
for data structure sizes; use them.
(Incremental_input_entry_reader): Import symbolic constants from
Incremental_inputs_reader; use them.

gold/ChangeLog
gold/incremental-dump.cc
gold/incremental.cc
gold/incremental.h

index e66b9fdf6a31318c64f4d40d61f3bf8d921e18c1..ea987881eb9a45c239ceaf46813666386cdae9da 100644 (file)
@@ -1,3 +1,26 @@
+2012-04-24  Cary Coutant  <ccoutant@google.com>
+
+       * incremental-dump.cc (find_input_containing_global): Replace
+       magic number with symbolic constant.
+       (dump_incremental_inputs): Update version number.
+       * incremental.cc (Output_section_incremental_inputs): Update version
+       number; import symbolic constants from Incremental_inputs_reader.
+       (Incremental_inputs::create_data_sections): Align relocations
+       section correctly for 64-bit targets.
+       (Output_section_incremental_inputs::set_final_data_size): Use symbolic
+       constants; add padding.
+       (Output_section_incremental_inputs::write_header): Add assert for
+       header_size.
+       (Output_section_incremental_inputs::write_input_files): Add assert
+       for input_entry_size.
+       (Output_section_incremental_inputs::write_info_blocks): Add padding;
+       add assert for object_info_size, input_section_entry_size,
+       global_sym_entry_size.
+       * incremental.h (Incremental_inputs_reader): Add symbolic constants
+       for data structure sizes; use them.
+       (Incremental_input_entry_reader): Import symbolic constants from
+       Incremental_inputs_reader; use them.
+
 2012-04-23  David S. Miller  <davem@davemloft.net>
 
        * sparc.cc (class Target_sparc): Add elf_machine_, elf_flags_,
index fb3d25f2813b7d6c66c03ff30c3a04f960f95191..53652655d04e9c3c3520b147b9c7c1a5d71e2a31 100644 (file)
@@ -52,6 +52,9 @@ find_input_containing_global(
     unsigned int* symndx)
 {
   typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
+  static const unsigned int global_sym_entry_size =
+      Incremental_inputs_reader<size, big_endian>::global_sym_entry_size;
+
   for (unsigned int i = 0; i < incremental_inputs.input_file_count(); ++i)
     {
       typename Inputs_reader::Incremental_input_entry_reader input_file =
@@ -63,7 +66,8 @@ find_input_containing_global(
       if (offset >= input_file.get_symbol_offset(0)
           && offset < input_file.get_symbol_offset(nsyms))
        {
-         *symndx = (offset - input_file.get_symbol_offset(0)) / 20;
+         *symndx = ((offset - input_file.get_symbol_offset(0))
+                    / global_sym_entry_size);
          return input_file;
        }
     }
@@ -92,7 +96,7 @@ dump_incremental_inputs(const char* argv0, const char* filename,
   Incremental_inputs_reader<size, big_endian>
       incremental_inputs(inc->inputs_reader());
 
-  if (incremental_inputs.version() != 1)
+  if (incremental_inputs.version() != 2)
     {
       fprintf(stderr, "%s: %s: unknown incremental version %d\n", argv0,
               filename, incremental_inputs.version());
index 60097a8ebc093b5214ec14405546bb0683b57581..6436a35e2ee7ca7f6dc239f08f7ec26995242d66 100644 (file)
 
 namespace gold {
 
-// Version information. Will change frequently during the development, later
-// we could think about backward (and forward?) compatibility.
-const unsigned int INCREMENTAL_LINK_VERSION = 1;
+// Version number for the .gnu_incremental_inputs section.
+// Version 1 was the initial checkin.
+// Version 2 adds some padding to ensure 8-byte alignment where necessary.
+const unsigned int INCREMENTAL_LINK_VERSION = 2;
 
 // This class manages the .gnu_incremental_inputs section, which holds
 // the header information, a directory of input files, and separate
@@ -112,8 +113,18 @@ class Output_section_incremental_inputs : public Output_section_data
 
   // Sizes of various structures.
   static const int sizeof_addr = size / 8;
-  static const int header_size = 16;
-  static const int input_entry_size = 24;
+  static const int header_size =
+      Incremental_inputs_reader<size, big_endian>::header_size;
+  static const int input_entry_size =
+      Incremental_inputs_reader<size, big_endian>::input_entry_size;
+  static const unsigned int object_info_size =
+      Incremental_inputs_reader<size, big_endian>::object_info_size;
+  static const unsigned int input_section_entry_size =
+      Incremental_inputs_reader<size, big_endian>::input_section_entry_size;
+  static const unsigned int global_sym_entry_size =
+      Incremental_inputs_reader<size, big_endian>::global_sym_entry_size;
+  static const unsigned int incr_reloc_size =
+      Incremental_relocs_reader<size, big_endian>::reloc_size;
 
   // The Incremental_inputs object.
   const Incremental_inputs* inputs_;
@@ -1193,37 +1204,44 @@ Incremental_inputs::finalize()
 void
 Incremental_inputs::create_data_sections(Symbol_table* symtab)
 {
+  int reloc_align = 4;
+
   switch (parameters->size_and_endianness())
     {
 #ifdef HAVE_TARGET_32_LITTLE
     case Parameters::TARGET_32_LITTLE:
       this->inputs_section_ =
           new Output_section_incremental_inputs<32, false>(this, symtab);
+      reloc_align = 4;
       break;
 #endif
 #ifdef HAVE_TARGET_32_BIG
     case Parameters::TARGET_32_BIG:
       this->inputs_section_ =
           new Output_section_incremental_inputs<32, true>(this, symtab);
+      reloc_align = 4;
       break;
 #endif
 #ifdef HAVE_TARGET_64_LITTLE
     case Parameters::TARGET_64_LITTLE:
       this->inputs_section_ =
           new Output_section_incremental_inputs<64, false>(this, symtab);
+      reloc_align = 8;
       break;
 #endif
 #ifdef HAVE_TARGET_64_BIG
     case Parameters::TARGET_64_BIG:
       this->inputs_section_ =
           new Output_section_incremental_inputs<64, true>(this, symtab);
+      reloc_align = 8;
       break;
 #endif
     default:
       gold_unreachable();
     }
   this->symtab_section_ = new Output_data_space(4, "** incremental_symtab");
-  this->relocs_section_ = new Output_data_space(4, "** incremental_relocs");
+  this->relocs_section_ = new Output_data_space(reloc_align,
+                                               "** incremental_relocs");
   this->got_plt_section_ = new Output_data_space(4, "** incremental_got_plt");
 }
 
@@ -1244,8 +1262,6 @@ void
 Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
 {
   const Incremental_inputs* inputs = this->inputs_;
-  const unsigned int sizeof_addr = size / 8;
-  const unsigned int rel_size = 8 + 2 * sizeof_addr;
 
   // Offset of each input entry.
   unsigned int input_offset = this->header_size;
@@ -1289,13 +1305,13 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
            // Input section count, global symbol count, local symbol offset,
            // local symbol count, first dynamic reloc, dynamic reloc count,
            // comdat group count.
-           info_offset += 28;
+           info_offset += this->object_info_size;
            // Each input section.
            info_offset += (entry->get_input_section_count()
-                           * (8 + 2 * sizeof_addr));
+                           * this->input_section_entry_size);
            // Each global symbol.
            const Object::Symbols* syms = entry->object()->get_global_symbols();
-           info_offset += syms->size() * 20;
+           info_offset += syms->size() * this->global_sym_entry_size;
            // Each comdat group.
            info_offset += entry->get_comdat_group_count() * 4;
          }
@@ -1341,7 +1357,11 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
        default:
          gold_unreachable();
        }
-    }
+
+     // Pad so each supplemental info block begins at an 8-byte boundary.
+     if (info_offset & 4)
+       info_offset += 4;
+   }
 
   this->set_data_size(info_offset);
 
@@ -1351,7 +1371,7 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
 
   // Set the size of the .gnu_incremental_relocs section.
   inputs->relocs_section()->set_current_data_size(inputs->get_reloc_count()
-                                                 * rel_size);
+                                                 * this->incr_reloc_size);
 
   // Set the size of the .gnu_incremental_got_plt section.
   Sized_target<size, big_endian>* target =
@@ -1442,6 +1462,7 @@ Output_section_incremental_inputs<size, big_endian>::write_header(
   Swap32::writeval(pov + 4, input_file_count);
   Swap32::writeval(pov + 8, command_line_offset);
   Swap32::writeval(pov + 12, 0);
+  gold_assert(this->header_size == 16);
   return pov + this->header_size;
 }
 
@@ -1476,6 +1497,7 @@ Output_section_incremental_inputs<size, big_endian>::write_input_files(
       Swap32::writeval(pov + 16, mtime.nanoseconds);
       Swap16::writeval(pov + 20, flags);
       Swap16::writeval(pov + 22, (*p)->arg_serial());
+      gold_assert(this->input_entry_size == 24);
       pov += this->input_entry_size;
     }
   return pov;
@@ -1549,7 +1571,9 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
            Swap32::writeval(pov + 16, first_dynrel);
            Swap32::writeval(pov + 20, ndynrel);
            Swap32::writeval(pov + 24, ncomdat);
-           pov += 28;
+           Swap32::writeval(pov + 28, 0);
+           gold_assert(this->object_info_size == 32);
+           pov += this->object_info_size;
 
            // Build a temporary array to map input section indexes
            // from the original object file index to the index in the
@@ -1581,7 +1605,9 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
                Swap32::writeval(pov + 4, out_shndx);
                Swap::writeval(pov + 8, out_offset);
                Swap::writeval(pov + 8 + sizeof_addr, sh_size);
-               pov += 8 + 2 * sizeof_addr;
+               gold_assert(this->input_section_entry_size
+                           == 8 + 2 * sizeof_addr);
+               pov += this->input_section_entry_size;
              }
 
            // For each global symbol, write its associated relocations,
@@ -1634,7 +1660,8 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
                Swap32::writeval(pov + 12, nrelocs);
                Swap32::writeval(pov + 16,
                                 first_reloc * (8 + 2 * sizeof_addr));
-               pov += 20;
+               gold_assert(this->global_sym_entry_size == 20);
+               pov += this->global_sym_entry_size;
              }
 
            // For each kept COMDAT group, write the group signature.
@@ -1745,6 +1772,13 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
        default:
          gold_unreachable();
        }
+
+     // Pad the info block to a multiple of 8 bytes.
+     if (static_cast<unsigned int>(pov - oview) & 4)
+      {
+       Swap32::writeval(pov, 0);
+       pov += 4;
+      }
     }
   return pov;
 }
index b631ae225f6a6a2f8b553ba3d3acfb6eca1ae9f1..20ae772886763496a6b306bfef367f4541a88582 100644 (file)
@@ -758,6 +758,23 @@ class Incremental_inputs_reader
   typedef elfcpp::Swap<64, big_endian> Swap64;
 
  public:
+  // Size of the .gnu_incremental_inputs header.
+  // (3 x 4-byte fields, plus 4 bytes padding.)
+  static const unsigned int header_size = 16;
+  // Size of an input file entry.
+  // (2 x 4-byte fields, 1 x 12-byte field, 2 x 2-byte fields.)
+  static const unsigned int input_entry_size = 24;
+  // Size of the first part of the supplemental info block for
+  // relocatable objects and archive members.
+  // (7 x 4-byte fields, plus 4 bytes padding.)
+  static const unsigned int object_info_size = 32;
+  // Size of an input section entry.
+  // (2 x 4-byte fields, 2 x address-sized fields.)
+  static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
+  // Size of a global symbol entry in the supplemental info block.
+  // (5 x 4-byte fields.)
+  static const unsigned int global_sym_entry_size = 20;
+
   Incremental_inputs_reader()
     : p_(NULL), strtab_(NULL, 0), input_file_count_(0)
   { }
@@ -788,6 +805,14 @@ class Incremental_inputs_reader
   // Reader class for an input file entry and its supplemental info.
   class Incremental_input_entry_reader
   {
+   private:
+    static const unsigned int object_info_size =
+       Incremental_inputs_reader<size, big_endian>::object_info_size;
+    static const unsigned int input_section_entry_size =
+       Incremental_inputs_reader<size, big_endian>::input_section_entry_size;
+    static const unsigned int global_sym_entry_size =
+       Incremental_inputs_reader<size, big_endian>::global_sym_entry_size;
+
    public:
     Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
                                   unsigned int offset)
@@ -866,9 +891,10 @@ class Incremental_inputs_reader
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
 
       unsigned int section_count = this->get_input_section_count();
-      return (this->info_offset_ + 28
-             + section_count * input_section_entry_size
-             + symndx * 20);
+      return (this->info_offset_
+             + this->object_info_size
+             + section_count * this->input_section_entry_size
+             + symndx * this->global_sym_entry_size);
     }
 
     // Return the global symbol count -- for objects & shared libraries only.
@@ -1001,8 +1027,9 @@ class Incremental_inputs_reader
     {
       Input_section_info info;
       const unsigned char* p = (this->inputs_->p_
-                               + this->info_offset_ + 28
-                               + n * input_section_entry_size);
+                               + this->info_offset_
+                               + this->object_info_size
+                               + n * this->input_section_entry_size);
       unsigned int name_offset = Swap32::readval(p);
       info.name = this->inputs_->get_string(name_offset);
       info.output_shndx = Swap32::readval(p + 4);
@@ -1019,9 +1046,10 @@ class Incremental_inputs_reader
                  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
       unsigned int section_count = this->get_input_section_count();
       const unsigned char* p = (this->inputs_->p_
-                               + this->info_offset_ + 28
-                               + section_count * input_section_entry_size
-                               + n * 20);
+                               + this->info_offset_
+                               + this->object_info_size
+                               + section_count * this->input_section_entry_size
+                               + n * this->global_sym_entry_size);
       return Incremental_global_symbol_reader<big_endian>(p);
     }
 
@@ -1032,9 +1060,10 @@ class Incremental_inputs_reader
       unsigned int section_count = this->get_input_section_count();
       unsigned int symbol_count = this->get_global_symbol_count();
       const unsigned char* p = (this->inputs_->p_
-                               + this->info_offset_ + 28
-                               + section_count * input_section_entry_size
-                               + symbol_count * 20
+                               + this->info_offset_
+                               + this->object_info_size
+                               + section_count * this->input_section_entry_size
+                               + symbol_count * this->global_sym_entry_size
                                + n * 4);
       unsigned int name_offset = Swap32::readval(p);
       return this->inputs_->get_string(name_offset);
@@ -1072,8 +1101,6 @@ class Incremental_inputs_reader
     }
 
    private:
-    // Size of an input section entry.
-    static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
     // The reader instance for the containing section.
     const Incremental_inputs_reader* inputs_;
     // The flags, including the type of input file.
@@ -1089,14 +1116,14 @@ class Incremental_inputs_reader
   input_file_offset(unsigned int n) const
   {
     gold_assert(n < this->input_file_count_);
-    return 16 + n * 24;
+    return this->header_size + n * this->input_entry_size;
   }
 
   // Return the index of an input file entry given its OFFSET.
   unsigned int
   input_file_index(unsigned int offset) const
   {
-    int n = (offset - 16) / 24;
+    int n = ((offset - this->header_size) / this->input_entry_size);
     gold_assert(input_file_offset(n) == offset);
     return n;
   }
@@ -1110,7 +1137,8 @@ class Incremental_inputs_reader
   Incremental_input_entry_reader
   input_file_at_offset(unsigned int offset) const
   {
-    gold_assert(offset < 16 + this->input_file_count_ * 24);
+    gold_assert(offset < (this->header_size
+                         + this->input_file_count_ * this->input_entry_size));
     return Incremental_input_entry_reader(this, offset);
   }