* 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.
This commit is contained in:
parent
6321c22a8c
commit
f038d49652
@ -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_,
|
||||
|
@ -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());
|
||||
|
@ -41,9 +41,10 @@
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user