* symtab.h (class Symbol): Remove fields is_target_special_ and
	has_plt_offset_.  Add field is_defined_in_discarded_section_.
	(Symbol::is_defined_in_discarded_section): New function.
	(Symbol::set_is_defined_in_discarded_section): New function.
	(Symbol::has_plt_offset): Rewrite.
	(Symbol::set_plt_offset): Verify that new offset is not -1U.
	* symtab.cc (Symbol::init_fields): Initialize plt_offset_ to -1U.
	Don't initialize is_target_special_ or has_plt_offset_.
	Initialize is_defined_in_discarded_section_.
	(Symbol_table::add_from_relobj): If appropriate, set
	is_defined_in_discarded_section.
	* resolve.cc (Symbol::override_base_with_special): Don't test
	is_target_special_.  Change has_plt_offset_ to has_plt_offset().
	* target-reloc.h (relocate_section): Do special handling for
	symbols defined in discarded sections for global symbols as well
	as local symbols.
This commit is contained in:
Ian Lance Taylor 2010-01-09 00:13:48 +00:00
parent ab42223304
commit 880cd20d40
5 changed files with 117 additions and 67 deletions

View File

@ -1,3 +1,23 @@
2010-01-08 Ian Lance Taylor <iant@google.com>
PR 11108
* symtab.h (class Symbol): Remove fields is_target_special_ and
has_plt_offset_. Add field is_defined_in_discarded_section_.
(Symbol::is_defined_in_discarded_section): New function.
(Symbol::set_is_defined_in_discarded_section): New function.
(Symbol::has_plt_offset): Rewrite.
(Symbol::set_plt_offset): Verify that new offset is not -1U.
* symtab.cc (Symbol::init_fields): Initialize plt_offset_ to -1U.
Don't initialize is_target_special_ or has_plt_offset_.
Initialize is_defined_in_discarded_section_.
(Symbol_table::add_from_relobj): If appropriate, set
is_defined_in_discarded_section.
* resolve.cc (Symbol::override_base_with_special): Don't test
is_target_special_. Change has_plt_offset_ to has_plt_offset().
* target-reloc.h (relocate_section): Do special handling for
symbols defined in discarded sections for global symbols as well
as local symbols.
2010-01-08 Ian Lance Taylor <iant@google.com>
* dynobj.cc (big_endian>::find_dynsym_sections): Set pi to NULL in

View File

@ -859,9 +859,8 @@ Symbol::override_base_with_special(const Symbol* from)
// We shouldn't see these flags. If we do, we need to handle them
// somehow.
gold_assert(!from->is_target_special_ || this->is_target_special_);
gold_assert(!from->is_forwarder_);
gold_assert(!from->has_plt_offset_);
gold_assert(!from->has_plt_offset());
gold_assert(!from->has_warning_);
gold_assert(!from->is_copied_from_dynobj_);
gold_assert(!from->is_forced_local_);

View File

@ -59,24 +59,23 @@ Symbol::init_fields(const char* name, const char* version,
this->symtab_index_ = 0;
this->dynsym_index_ = 0;
this->got_offsets_.init();
this->plt_offset_ = 0;
this->plt_offset_ = -1U;
this->type_ = type;
this->binding_ = binding;
this->visibility_ = visibility;
this->nonvis_ = nonvis;
this->is_target_special_ = false;
this->is_def_ = false;
this->is_forwarder_ = false;
this->has_alias_ = false;
this->needs_dynsym_entry_ = false;
this->in_reg_ = false;
this->in_dyn_ = false;
this->has_plt_offset_ = false;
this->has_warning_ = false;
this->is_copied_from_dynobj_ = false;
this->is_forced_local_ = false;
this->is_ordinary_shndx_ = false;
this->in_real_elf_ = false;
this->is_defined_in_discarded_section_ = false;
}
// Return the demangled version of the symbol's name, but only
@ -1070,10 +1069,14 @@ Symbol_table::add_from_relobj(
// A symbol defined in a section which we are not including must
// be treated as an undefined symbol.
bool is_defined_in_discarded_section = false;
if (st_shndx != elfcpp::SHN_UNDEF
&& is_ordinary
&& !relobj->is_section_included(st_shndx))
st_shndx = elfcpp::SHN_UNDEF;
{
st_shndx = elfcpp::SHN_UNDEF;
is_defined_in_discarded_section = true;
}
// In an object file, an '@' in the name separates the symbol
// name from the version name. If there are two '@' characters,
@ -1190,6 +1193,9 @@ Symbol_table::add_from_relobj(
if (is_forced_local)
this->force_local(res);
if (is_defined_in_discarded_section)
res->set_is_defined_in_discarded_section();
(*sympointers)[i] = res;
}
}

View File

@ -1,6 +1,6 @@
// symtab.h -- the gold symbol table -*- C++ -*-
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@ -308,6 +308,18 @@ class Symbol
set_in_real_elf()
{ this->in_real_elf_ = true; }
// Return whether this symbol was defined in a section that was
// discarded from the link. This is used to control some error
// reporting.
bool
is_defined_in_discarded_section() const
{ return this->is_defined_in_discarded_section_; }
// Mark this symbol as having been defined in a discarded section.
void
set_is_defined_in_discarded_section()
{ this->is_defined_in_discarded_section_ = true; }
// Return the index of this symbol in the output file symbol table.
// A value of -1U means that this symbol is not going into the
// output file. This starts out as zero, and is set to a non-zero
@ -383,7 +395,7 @@ class Symbol
// Return whether this symbol has an entry in the PLT section.
bool
has_plt_offset() const
{ return this->has_plt_offset_; }
{ return this->plt_offset_ != -1U; }
// Return the offset into the PLT section of this symbol.
unsigned int
@ -397,7 +409,7 @@ class Symbol
void
set_plt_offset(unsigned int plt_offset)
{
this->has_plt_offset_ = true;
gold_assert(plt_offset != -1U);
this->plt_offset_ = plt_offset;
}
@ -870,16 +882,14 @@ class Symbol
// non-zero value during Layout::finalize.
unsigned int dynsym_index_;
// If this symbol has an entry in the GOT section (has_got_offset_
// is true), this holds the offset from the start of the GOT section.
// A symbol may have more than one GOT offset (e.g., when mixing
// modules compiled with two different TLS models), but will usually
// have at most one.
// The GOT section entries for this symbol. A symbol may have more
// than one GOT offset (e.g., when mixing modules compiled with two
// different TLS models), but will usually have at most one.
Got_offset_list got_offsets_;
// If this symbol has an entry in the PLT section (has_plt_offset_
// is true), then this is the offset from the start of the PLT
// section.
// If this symbol has an entry in the PLT section, then this is the
// offset from the start of the PLT section. This is -1U if there
// is no PLT entry.
unsigned int plt_offset_;
// Symbol type (bits 0 to 3).
@ -892,10 +902,7 @@ class Symbol
unsigned int nonvis_ : 6;
// The type of symbol (bits 16 to 18).
Source source_ : 3;
// True if this symbol always requires special target-specific
// handling (bit 19).
bool is_target_special_ : 1;
// True if this is the default version of the symbol (bit 20).
// True if this is the default version of the symbol (bit 19).
bool is_def_ : 1;
// True if this symbol really forwards to another symbol. This is
// used when we discover after the fact that two different entries
@ -903,37 +910,38 @@ class Symbol
// never be set for a symbol found in the hash table, but may be set
// for a symbol found in the list of symbols attached to an Object.
// It forwards to the symbol found in the forwarders_ map of
// Symbol_table (bit 21).
// Symbol_table (bit 20).
bool is_forwarder_ : 1;
// True if the symbol has an alias in the weak_aliases table in
// Symbol_table (bit 22).
// Symbol_table (bit 21).
bool has_alias_ : 1;
// True if this symbol needs to be in the dynamic symbol table (bit
// 23).
// 22).
bool needs_dynsym_entry_ : 1;
// True if we've seen this symbol in a regular object (bit 24).
// True if we've seen this symbol in a regular object (bit 23).
bool in_reg_ : 1;
// True if we've seen this symbol in a dynamic object (bit 25).
// True if we've seen this symbol in a dynamic object (bit 24).
bool in_dyn_ : 1;
// True if the symbol has an entry in the PLT section (bit 26).
bool has_plt_offset_ : 1;
// True if this is a dynamic symbol which needs a special value in
// the dynamic symbol table (bit 27).
// the dynamic symbol table (bit 25).
bool needs_dynsym_value_ : 1;
// True if there is a warning for this symbol (bit 28).
// True if there is a warning for this symbol (bit 26).
bool has_warning_ : 1;
// True if we are using a COPY reloc for this symbol, so that the
// real definition lives in a dynamic object (bit 29).
// real definition lives in a dynamic object (bit 27).
bool is_copied_from_dynobj_ : 1;
// True if this symbol was forced to local visibility by a version
// script (bit 30).
// script (bit 28).
bool is_forced_local_ : 1;
// True if the field u_.from_object.shndx is an ordinary section
// index, not one of the special codes from SHN_LORESERVE to
// SHN_HIRESERVE (bit 31).
// SHN_HIRESERVE (bit 29).
bool is_ordinary_shndx_ : 1;
// True if we've seen this symbol in a real ELF object.
// True if we've seen this symbol in a real ELF object (bit 30).
bool in_real_elf_ : 1;
// True if this symbol is defined in a section which was discarded
// (bit 31).
bool is_defined_in_discarded_section_ : 1;
};
// The parts of a symbol which are size specific. Using a template

View File

@ -1,6 +1,6 @@
// target-reloc.h -- target specific relocation support -*- C++ -*-
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
@ -217,6 +217,8 @@ relocate_section(
Symbol_value<size> symval;
const Symbol_value<size> *psymval;
bool is_defined_in_discarded_section;
unsigned int shndx;
if (r_sym < local_count
&& (reloc_symbol_changes == NULL
|| (*reloc_symbol_changes)[i] == NULL))
@ -230,38 +232,12 @@ relocate_section(
// counterpart in the kept section. The symbol must not
// correspond to a section we are folding.
bool is_ordinary;
unsigned int shndx = psymval->input_shndx(&is_ordinary);
if (is_ordinary
&& shndx != elfcpp::SHN_UNDEF
&& !object->is_section_included(shndx)
&& !(relinfo->symtab->is_section_folded(object, shndx)))
{
if (comdat_behavior == CB_UNDETERMINED)
{
std::string name = object->section_name(relinfo->data_shndx);
comdat_behavior = get_comdat_behavior(name.c_str());
}
if (comdat_behavior == CB_PRETEND)
{
bool found;
typename elfcpp::Elf_types<size>::Elf_Addr value =
object->map_to_kept_section(shndx, &found);
if (found)
symval.set_output_value(value + psymval->input_value());
else
symval.set_output_value(0);
}
else
{
if (comdat_behavior == CB_WARNING)
gold_warning_at_location(relinfo, i, offset,
_("relocation refers to discarded "
"comdat section"));
symval.set_output_value(0);
}
symval.set_no_output_symtab_entry();
psymval = &symval;
}
shndx = psymval->input_shndx(&is_ordinary);
is_defined_in_discarded_section =
(is_ordinary
&& shndx != elfcpp::SHN_UNDEF
&& !object->is_section_included(shndx)
&& !relinfo->symtab->is_section_folded(object, shndx));
}
else
{
@ -284,6 +260,46 @@ relocate_section(
symval.set_no_output_symtab_entry();
symval.set_output_value(sym->value());
psymval = &symval;
is_defined_in_discarded_section =
(gsym->is_defined_in_discarded_section()
&& gsym->is_undefined());
shndx = 0;
}
Symbol_value<size> symval2;
if (is_defined_in_discarded_section)
{
if (comdat_behavior == CB_UNDETERMINED)
{
std::string name = object->section_name(relinfo->data_shndx);
comdat_behavior = get_comdat_behavior(name.c_str());
}
if (comdat_behavior == CB_PRETEND)
{
// FIXME: This case does not work for global symbols.
// We have no place to store the original section index.
// Fortunately this does not matter for comdat sections,
// only for sections explicitly discarded by a linker
// script.
bool found;
typename elfcpp::Elf_types<size>::Elf_Addr value =
object->map_to_kept_section(shndx, &found);
if (found)
symval2.set_output_value(value + psymval->input_value());
else
symval2.set_output_value(0);
}
else
{
if (comdat_behavior == CB_WARNING)
gold_warning_at_location(relinfo, i, offset,
_("relocation refers to discarded "
"section"));
symval2.set_output_value(0);
}
symval2.set_no_output_symtab_entry();
psymval = &symval2;
}
if (!relocate.relocate(relinfo, target, output_section, i, reloc,
@ -302,6 +318,7 @@ relocate_section(
if (sym != NULL
&& sym->is_undefined()
&& sym->binding() != elfcpp::STB_WEAK
&& !is_defined_in_discarded_section
&& !target->is_defined_by_abi(sym)
&& (!parameters->options().shared() // -shared
|| parameters->options().defs())) // -z defs