* incremental-dump.cc (dump_incremental_inputs): Print local

symbol info for each input file.
	* incremental.cc
	(Output_section_incremental_inputs::set_final_data_size): Add local
	symbol info to input file entries in incremental info.
	(Output_section_incremental_inputs::write_info_blocks): Likewise.
	(Sized_incr_relobj::Sized_incr_relobj): Initialize new data members.
	(Sized_incr_relobj::do_add_symbols): Cosmetic change.
	(Sized_incr_relobj::do_count_local_symbols): Replace stub with
	implementation.
	(Sized_incr_relobj::do_finalize_local_symbols): Likewise.
	(Sized_incr_relobj::do_relocate): Write the local symbols.
	(Sized_incr_dynobj::do_add_symbols): Cosmetic change.
	* incremental.h (Incremental_inputs_reader::get_symbol_offset):
	Adjust size of input file header.
	(Incremental_inputs_reader::get_local_symbol_offset): New function.
	(Incremental_inputs_reader::get_local_symbol_count): New function.
	(Incremental_inputs_reader::get_input_section): Adjust size of input
	file header.
	(Incremental_inputs_reader::get_global_symbol_reader): Likewise.
	(Sized_incr_relobj::This): New typedef.
	(Sized_incr_relobj::sym_size): New const data member.
	(Sized_incr_relobj::Local_symbol): New struct.
	(Sized_incr_relobj::do_output_local_symbol_count): New function.
	(Sized_incr_relobj::do_local_symbol_offset): New function.
	(Sized_incr_relobj::local_symbol_count_): New data member.
	(Sized_incr_relobj::output_local_dynsym_count_): New data member.
	(Sized_incr_relobj::local_symbol_index_): New data member.
	(Sized_incr_relobj::local_symbol_offset_): New data member.
	(Sized_incr_relobj::local_dynsym_offset_): New data member.
	(Sized_incr_relobj::local_symbols_): New data member.
	* object.h (Relobj::output_local_symbol_count): New function.
	(Relobj::local_symbol_offset): New function.
	(Relobj::do_output_local_symbol_count): New function.
	(Relobj::do_local_symbol_offset): New function.
	(Sized_relobj::do_output_local_symbol_count): New function.
	(Sized_relobj::do_local_symbol_offset): New function.
This commit is contained in:
Cary Coutant 2011-04-25 20:28:48 +00:00
parent 3e03848b6c
commit f0f9babffe
5 changed files with 288 additions and 23 deletions

View File

@ -1,3 +1,43 @@
2011-04-25 Cary Coutant <ccoutant@google.com>
* incremental-dump.cc (dump_incremental_inputs): Print local
symbol info for each input file.
* incremental.cc
(Output_section_incremental_inputs::set_final_data_size): Add local
symbol info to input file entries in incremental info.
(Output_section_incremental_inputs::write_info_blocks): Likewise.
(Sized_incr_relobj::Sized_incr_relobj): Initialize new data members.
(Sized_incr_relobj::do_add_symbols): Cosmetic change.
(Sized_incr_relobj::do_count_local_symbols): Replace stub with
implementation.
(Sized_incr_relobj::do_finalize_local_symbols): Likewise.
(Sized_incr_relobj::do_relocate): Write the local symbols.
(Sized_incr_dynobj::do_add_symbols): Cosmetic change.
* incremental.h (Incremental_inputs_reader::get_symbol_offset):
Adjust size of input file header.
(Incremental_inputs_reader::get_local_symbol_offset): New function.
(Incremental_inputs_reader::get_local_symbol_count): New function.
(Incremental_inputs_reader::get_input_section): Adjust size of input
file header.
(Incremental_inputs_reader::get_global_symbol_reader): Likewise.
(Sized_incr_relobj::This): New typedef.
(Sized_incr_relobj::sym_size): New const data member.
(Sized_incr_relobj::Local_symbol): New struct.
(Sized_incr_relobj::do_output_local_symbol_count): New function.
(Sized_incr_relobj::do_local_symbol_offset): New function.
(Sized_incr_relobj::local_symbol_count_): New data member.
(Sized_incr_relobj::output_local_dynsym_count_): New data member.
(Sized_incr_relobj::local_symbol_index_): New data member.
(Sized_incr_relobj::local_symbol_offset_): New data member.
(Sized_incr_relobj::local_dynsym_offset_): New data member.
(Sized_incr_relobj::local_symbols_): New data member.
* object.h (Relobj::output_local_symbol_count): New function.
(Relobj::local_symbol_offset): New function.
(Relobj::do_output_local_symbol_count): New function.
(Relobj::do_local_symbol_offset): New function.
(Sized_relobj::do_output_local_symbol_count): New function.
(Sized_relobj::do_local_symbol_offset): New function.
2011-04-22 Vladimir Simonov <sv@sw.ru>
* descriptors.cc (set_close_on_exec): New function.

View File

@ -138,18 +138,17 @@ dump_incremental_inputs(const char* argv0, const char* filename,
switch (input_type)
{
case INCREMENTAL_INPUT_OBJECT:
printf("Object\n");
printf(" Input section count: %d\n",
input_file.get_input_section_count());
printf(" Symbol count: %d\n",
input_file.get_global_symbol_count());
break;
case INCREMENTAL_INPUT_ARCHIVE_MEMBER:
printf("Archive member\n");
printf("%s\n", (input_type == INCREMENTAL_INPUT_OBJECT
? "Object" : "Archive member"));
printf(" Input section count: %d\n",
input_file.get_input_section_count());
printf(" Symbol count: %d\n",
printf(" Global symbol count: %d\n",
input_file.get_global_symbol_count());
printf(" Local symbol offset: %d\n",
input_file.get_local_symbol_offset());
printf(" Local symbol count: %d\n",
input_file.get_local_symbol_count());
break;
case INCREMENTAL_INPUT_ARCHIVE:
printf("Archive\n");

View File

@ -1055,8 +1055,9 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size()
Incremental_object_entry* entry = (*p)->object_entry();
gold_assert(entry != NULL);
(*p)->set_info_offset(info_offset);
// Input section count + global symbol count.
info_offset += 8;
// Input section count, global symbol count, local symbol offset,
// local symbol count.
info_offset += 16;
// Each input section.
info_offset += (entry->get_input_section_count()
* (8 + 2 * sizeof_addr));
@ -1295,13 +1296,18 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks(
Incremental_object_entry* entry = (*p)->object_entry();
gold_assert(entry != NULL);
const Object* obj = entry->object();
const Relobj* relobj = static_cast<const Relobj*>(obj);
const Object::Symbols* syms = obj->get_global_symbols();
// Write the input section count and global symbol count.
unsigned int nsections = entry->get_input_section_count();
unsigned int nsyms = syms->size();
off_t locals_offset = relobj->local_symbol_offset();
unsigned int nlocals = relobj->output_local_symbol_count();
Swap32::writeval(pov, nsections);
Swap32::writeval(pov + 4, nsyms);
pov += 8;
Swap32::writeval(pov + 8, static_cast<unsigned int>(locals_offset));
Swap32::writeval(pov + 12, nlocals);
pov += 16;
// Build a temporary array to map input section indexes
// from the original object file index to the index in the
@ -1671,8 +1677,11 @@ Sized_incr_relobj<size, big_endian>::Sized_incr_relobj(
: Sized_relobj_base<size, big_endian>(name, NULL), ibase_(ibase),
input_file_index_(input_file_index),
input_reader_(ibase->inputs_reader().input_file(input_file_index)),
local_symbol_count_(0), output_local_dynsym_count_(0),
local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
symbols_(), section_offsets_(), incr_reloc_offset_(-1U),
incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL)
incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL),
local_symbols_()
{
if (this->input_reader_.is_in_system_directory())
this->set_is_in_system_directory();
@ -1756,7 +1765,7 @@ Sized_incr_relobj<size, big_endian>::do_add_symbols(
unsigned int isym_count = isymtab.symbol_count();
unsigned int first_global = symtab_count - isym_count;
unsigned const char* sym_p;
const unsigned char* sym_p;
for (unsigned int i = 0; i < nsyms; ++i)
{
Incremental_global_symbol_reader<big_endian> info =
@ -2027,10 +2036,40 @@ Sized_incr_relobj<size, big_endian>::do_scan_relocs(Symbol_table*,
template<int size, bool big_endian>
void
Sized_incr_relobj<size, big_endian>::do_count_local_symbols(
Stringpool_template<char>*,
Stringpool_template<char>* pool,
Stringpool_template<char>*)
{
// FIXME: Count local symbols.
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
// Set the count of local symbols based on the incremental info.
unsigned int nlocals = this->input_reader_.get_local_symbol_count();
this->local_symbol_count_ = nlocals;
this->local_symbols_.reserve(nlocals);
// Get views of the base file's symbol table and string table.
Incremental_binary::View symtab_view(NULL);
unsigned int symtab_count;
elfcpp::Elf_strtab strtab(NULL, 0);
this->ibase_->get_symtab_view(&symtab_view, &symtab_count, &strtab);
// Read the local symbols from the base file's symbol table.
off_t off = this->input_reader_.get_local_symbol_offset();
const unsigned char* symp = symtab_view.data() + off;
for (unsigned int i = 0; i < nlocals; ++i, symp += sym_size)
{
elfcpp::Sym<size, big_endian> sym(symp);
const char* name;
if (!strtab.get_c_string(sym.get_st_name(), &name))
name = "";
gold_debug(DEBUG_INCREMENTAL, "Local symbol %d: %s", i, name);
name = pool->add(name, true, NULL);
this->local_symbols_.push_back(Local_symbol(name,
sym.get_st_value(),
sym.get_st_size(),
sym.get_st_shndx(),
sym.get_st_type(),
false));
}
}
// Finalize the local symbols.
@ -2039,11 +2078,12 @@ template<int size, bool big_endian>
unsigned int
Sized_incr_relobj<size, big_endian>::do_finalize_local_symbols(
unsigned int index,
off_t,
off_t off,
Symbol_table*)
{
// FIXME: Finalize local symbols.
return index;
this->local_symbol_index_ = index;
this->local_symbol_offset_ = off;
return index + this->local_symbol_count_;
}
// Set the offset where local dynamic symbol information will be stored.
@ -2109,6 +2149,91 @@ Sized_incr_relobj<size, big_endian>::do_relocate(const Symbol_table*,
}
of->write_output_view(off, len, view);
// Get views into the output file for the portions of the symbol table
// and the dynamic symbol table that we will be writing.
off_t symtab_off = layout->symtab_section()->offset();
off_t output_size = this->local_symbol_count_ * This::sym_size;
unsigned char* oview = NULL;
if (output_size > 0)
oview = of->get_output_view(symtab_off + this->local_symbol_offset_,
output_size);
off_t dyn_output_size = this->output_local_dynsym_count_ * sym_size;
unsigned char* dyn_oview = NULL;
if (dyn_output_size > 0)
dyn_oview = of->get_output_view(this->local_dynsym_offset_,
dyn_output_size);
// Write the local symbols.
unsigned char* ov = oview;
unsigned char* dyn_ov = dyn_oview;
const Stringpool* sympool = layout->sympool();
const Stringpool* dynpool = layout->dynpool();
Output_symtab_xindex* symtab_xindex = layout->symtab_xindex();
Output_symtab_xindex* dynsym_xindex = layout->dynsym_xindex();
for (unsigned int i = 0; i < this->local_symbol_count_; ++i)
{
Local_symbol& lsym(this->local_symbols_[i]);
bool is_ordinary;
unsigned int st_shndx = this->adjust_sym_shndx(i, lsym.st_shndx,
&is_ordinary);
if (is_ordinary)
{
Output_section* os = this->ibase_->output_section(st_shndx);
st_shndx = os->out_shndx();
if (st_shndx >= elfcpp::SHN_LORESERVE)
{
symtab_xindex->add(this->local_symbol_index_ + i, st_shndx);
if (lsym.needs_dynsym_entry)
dynsym_xindex->add(lsym.output_dynsym_index, st_shndx);
st_shndx = elfcpp::SHN_XINDEX;
}
}
// Write the symbol to the output symbol table.
{
elfcpp::Sym_write<size, big_endian> osym(ov);
osym.put_st_name(sympool->get_offset(lsym.name));
osym.put_st_value(lsym.st_value);
osym.put_st_size(lsym.st_size);
osym.put_st_info(elfcpp::STB_LOCAL,
static_cast<elfcpp::STT>(lsym.st_type));
osym.put_st_other(0);
osym.put_st_shndx(st_shndx);
ov += sym_size;
}
// Write the symbol to the output dynamic symbol table.
if (lsym.needs_dynsym_entry)
{
gold_assert(dyn_ov < dyn_oview + dyn_output_size);
elfcpp::Sym_write<size, big_endian> osym(dyn_ov);
osym.put_st_name(dynpool->get_offset(lsym.name));
osym.put_st_value(lsym.st_value);
osym.put_st_size(lsym.st_size);
osym.put_st_info(elfcpp::STB_LOCAL,
static_cast<elfcpp::STT>(lsym.st_type));
osym.put_st_other(0);
osym.put_st_shndx(st_shndx);
dyn_ov += sym_size;
}
}
if (output_size > 0)
{
gold_assert(ov - oview == output_size);
of->write_output_view(symtab_off + this->local_symbol_offset_,
output_size, oview);
}
if (dyn_output_size > 0)
{
gold_assert(dyn_ov - dyn_oview == dyn_output_size);
of->write_output_view(this->local_dynsym_offset_, dyn_output_size,
dyn_oview);
}
}
// Set the offset of a section.
@ -2187,7 +2312,7 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
unsigned int isym_count = isymtab.symbol_count();
unsigned int first_global = symtab_count - isym_count;
unsigned const char* sym_p;
const unsigned char* sym_p;
for (unsigned int i = 0; i < nsyms; ++i)
{
bool is_def;

View File

@ -725,7 +725,7 @@ class Incremental_inputs_reader
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
unsigned int section_count = this->get_input_section_count();
return (this->info_offset_ + 8
return (this->info_offset_ + 16
+ section_count * input_section_entry_size
+ symndx * 20);
}
@ -746,6 +746,26 @@ class Incremental_inputs_reader
}
}
// Return the offset of the first local symbol -- for objects only.
unsigned int
get_local_symbol_offset() const
{
gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 8);
}
// Return the local symbol count -- for objects only.
unsigned int
get_local_symbol_count() const
{
gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 12);
}
// Return the object count -- for scripts only.
unsigned int
get_object_count() const
@ -816,7 +836,7 @@ class Incremental_inputs_reader
{
Input_section_info info;
const unsigned char* p = (this->inputs_->p_
+ this->info_offset_ + 8
+ this->info_offset_ + 16
+ n * input_section_entry_size);
unsigned int name_offset = Swap32::readval(p);
info.name = this->inputs_->get_string(name_offset);
@ -834,7 +854,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_ + 8
+ this->info_offset_ + 16
+ section_count * input_section_entry_size
+ n * 20);
return Incremental_global_symbol_reader<big_endian>(p);
@ -1522,12 +1542,42 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian>
}
private:
// For convenience.
typedef Sized_incr_relobj<size, big_endian> This;
static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
typedef typename Sized_relobj_base<size, big_endian>::Output_sections
Output_sections;
typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
typedef typename Inputs_reader::Incremental_input_entry_reader
Input_entry_reader;
// A local symbol.
struct Local_symbol
{
Local_symbol(const char* name_, Address value_, unsigned int size_,
unsigned int shndx_, unsigned int type_,
bool needs_dynsym_entry_)
: st_value(value_), name(name_), st_size(size_), st_shndx(shndx_),
st_type(type_), output_dynsym_index(0),
needs_dynsym_entry(needs_dynsym_entry_)
{ }
// The symbol value.
Address st_value;
// The symbol name. This points to the stringpool entry.
const char* name;
// The symbol size.
unsigned int st_size;
// The output section index.
unsigned int st_shndx : 28;
// The symbol type.
unsigned int st_type : 4;
// The index of the symbol in the output dynamic symbol table.
unsigned int output_dynsym_index : 31;
// TRUE if the symbol needs to appear in the dynamic symbol table.
unsigned int needs_dynsym_entry : 1;
};
// Return TRUE if this is an incremental (unchanged) input file.
bool
do_is_incremental() const
@ -1625,7 +1675,17 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian>
// Return the number of local symbols.
unsigned int
do_local_symbol_count() const
{ return 0; }
{ return this->local_symbol_count_; }
// Return the number of local symbols in the output symbol table.
unsigned int
do_output_local_symbol_count() const
{ return this->local_symbol_count_; }
// Return the file offset for local symbols in the output symbol table.
off_t
do_local_symbol_offset() const
{ return this->local_symbol_offset_; }
// Read the relocs.
void
@ -1671,6 +1731,17 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian>
unsigned int input_file_index_;
// The reader for the input file.
Input_entry_reader input_reader_;
// The number of local symbols.
unsigned int local_symbol_count_;
// The number of local symbols which go into the output file's dynamic
// symbol table.
unsigned int output_local_dynsym_count_;
// This starting symbol index in the output symbol table.
unsigned int local_symbol_index_;
// The file offset for local symbols in the output symbol table.
unsigned int local_symbol_offset_;
// The file offset for local symbols in the output symbol table.
unsigned int local_dynsym_offset_;
// The entries in the symbol table for the external symbols.
Symbols symbols_;
// For each input section, the offset of the input section in its
@ -1686,6 +1757,8 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian>
unsigned int incr_reloc_output_index_;
// A copy of the incremental relocations from this object.
unsigned char* incr_relocs_;
// The local symbols.
std::vector<Local_symbol> local_symbols_;
};
// An incremental Dynobj. This class represents a shared object that has

View File

@ -987,6 +987,16 @@ class Relobj : public Object
local_symbol_count() const
{ return this->do_local_symbol_count(); }
// The number of local symbols in the output symbol table.
virtual unsigned int
output_local_symbol_count() const
{ return this->do_output_local_symbol_count(); }
// The file offset for local symbols in the output symbol table.
virtual off_t
local_symbol_offset() const
{ return this->do_local_symbol_offset(); }
// Initial local symbol processing: count the number of local symbols
// in the output symbol table and dynamic symbol table; add local symbol
// names to *POOL and *DYNPOOL.
@ -1115,6 +1125,14 @@ class Relobj : public Object
virtual unsigned int
do_local_symbol_count() const = 0;
// Return the number of output local symbols--implemented by child class.
virtual unsigned int
do_output_local_symbol_count() const = 0;
// Return the file offset for local symbols--implemented by child class.
virtual off_t
do_local_symbol_offset() const = 0;
// Count local symbols--implemented by child class.
virtual void
do_count_local_symbols(Stringpool_template<char>*,
@ -1911,6 +1929,16 @@ class Sized_relobj : public Sized_relobj_base<size, big_endian>
do_local_symbol_count() const
{ return this->local_symbol_count_; }
// Return the number of local symbols in the output symbol table.
unsigned int
do_output_local_symbol_count() const
{ return this->output_local_symbol_count_; }
// Return the number of local symbols in the output symbol table.
off_t
do_local_symbol_offset() const
{ return this->local_symbol_offset_; }
// Lay out the input sections.
void
do_layout(Symbol_table*, Layout*, Read_symbols_data*);