summaryrefslogtreecommitdiff
path: root/gold/target-reloc.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2010-01-09 00:13:48 +0000
committerIan Lance Taylor <ian@airs.com>2010-01-09 00:13:48 +0000
commit880cd20d40938ea13ff9d5dbb9393f80cfb98b75 (patch)
tree380dae82534c746a53caf0d5d08d89ff6242a524 /gold/target-reloc.h
parentab422233046f4f06532d5a1d6ca0574d711164c5 (diff)
downloadbinutils-gdb-880cd20d40938ea13ff9d5dbb9393f80cfb98b75.tar.gz
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.
Diffstat (limited to 'gold/target-reloc.h')
-rw-r--r--gold/target-reloc.h83
1 files changed, 50 insertions, 33 deletions
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 25b3ac43532..06597e2124f 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -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