gold incremental file format on 64-bit

David Miller davem@davemloft.net
Sun Apr 22 05:39:00 GMT 2012


From: David Miller <davem@davemloft.net>
Date: Fri, 20 Apr 2012 20:47:33 -0400 (EDT)

> From: Cary Coutant <ccoutant@google.com>
> Date: Fri, 20 Apr 2012 17:36:40 -0700
> 
>> It would be reasonable to do align info_offset inside the loop after
>> the switch statement in
>> Output_section_incremental_inputs::set_final_data_size.  Then in
>> Output_section_incremental_inputs::write_info_blocks, we'd have to
>> fill the padding with zeroes. I can make this and the
>> .gnu_incremental_relocs alignment fix next week, unless you want to
>> submit a patch yourself.
> 
> I plan to take care of this tonight if not over the weekend, besides
> I have the crummy cpu by which one can test this fully. :-)

Ok, here's what I came up with.  Tested on sparc, sparc64, and
x86-64.

2012-04-21  David S. Miller  <davem@davemloft.net>

	* incremental.cc (Incremental_inputs::create_data_sections): Align
	incremental reloc section to 8 bytes.
	(Output_section_incremental_inputs::set_final_data_size): Pad out
	offsets to ensure necessary 8-byte alignment.
	(Output_section_incremental_inputs::write_info_block): Likewise.
	* incremental.h (Incremental_inputs_reader::get_symbol_offset):
	Adjust offset calculation.
	(Incremental_inputs_reader::get_input_section): Likewise.
	(Incremental_inputs_reader::get_global_symbol_reader): Likewise.
	(Incremental_inputs_reader::get_comdat_group_signature): Likewise.

diff --git a/gold/incremental.cc b/gold/incremental.cc
index 60097a8..1d2bbf1 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -1223,7 +1223,7 @@ Incremental_inputs::create_data_sections(Symbol_table* symtab)
       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(8, "** incremental_relocs");
   this->got_plt_section_ = new Output_data_space(4, "** incremental_got_plt");
 }
 
@@ -1289,7 +1289,7 @@ 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 += 32;
 	    // Each input section.
 	    info_offset += (entry->get_input_section_count()
 			    * (8 + 2 * sizeof_addr));
@@ -1341,6 +1341,10 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
 	default:
 	  gold_unreachable();
 	}
+
+      // Padding to get 8-byte alignment
+      if (info_offset & 4)
+	info_offset += 4;
     }
 
   this->set_data_size(info_offset);
@@ -1549,7 +1553,8 @@ 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);
+	    pov += 32;
 
 	    // Build a temporary array to map input section indexes
 	    // from the original object file index to the index in the
@@ -1745,6 +1750,13 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
 	default:
 	  gold_unreachable();
 	}
+
+      // Add padding word if necessary.
+      if (static_cast<unsigned int>(pov - oview) & 4)
+	{
+	  Swap32::writeval(pov, 0);
+	  pov += 4;
+	}
     }
   return pov;
 }
diff --git a/gold/incremental.h b/gold/incremental.h
index b631ae2..1c3a833 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -866,7 +866,7 @@ class Incremental_inputs_reader
 		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
 
       unsigned int section_count = this->get_input_section_count();
-      return (this->info_offset_ + 28
+      return (this->info_offset_ + 32
 	      + section_count * input_section_entry_size
 	      + symndx * 20);
     }
@@ -1001,7 +1001,7 @@ class Incremental_inputs_reader
     {
       Input_section_info info;
       const unsigned char* p = (this->inputs_->p_
-				+ this->info_offset_ + 28
+				+ this->info_offset_ + 32
 				+ n * input_section_entry_size);
       unsigned int name_offset = Swap32::readval(p);
       info.name = this->inputs_->get_string(name_offset);
@@ -1019,7 +1019,7 @@ 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
+				+ this->info_offset_ + 32
 				+ section_count * input_section_entry_size
 				+ n * 20);
       return Incremental_global_symbol_reader<big_endian>(p);
@@ -1032,7 +1032,7 @@ 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
+				+ this->info_offset_ + 32
 				+ section_count * input_section_entry_size
 				+ symbol_count * 20
 				+ n * 4);



More information about the Binutils mailing list