This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: gold incremental file format on 64-bit
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);