// target-reloc.h -- target specific relocation support -*- C++ -*-
-// Copyright (C) 2006-2017 Free Software Foundation, Inc.
+// Copyright (C) 2006-2020 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
CB_UNDETERMINED, // Not yet determined -- need to look at section name.
CB_PRETEND, // Attempt to map to the corresponding kept section.
CB_IGNORE, // Ignore the relocation.
- CB_WARNING // Print a warning.
+ CB_ERROR // Print an error.
};
class Default_comdat_behavior
if (strcmp(name, ".eh_frame") == 0
|| strcmp(name, ".gcc_except_table") == 0)
return CB_IGNORE;
- return CB_WARNING;
+ return CB_ERROR;
}
};
return true;
}
+template<int size, bool big_endian>
+inline void
+issue_discarded_error(
+ const Relocate_info<size, big_endian>* relinfo,
+ size_t shndx,
+ section_offset_type offset,
+ unsigned int r_sym,
+ const Symbol* gsym)
+{
+ Sized_relobj_file<size, big_endian>* object = relinfo->object;
+
+ if (gsym == NULL)
+ {
+ gold_error_at_location(
+ relinfo, shndx, offset,
+ _("relocation refers to local symbol \"%s\" [%u], "
+ "which is defined in a discarded section"),
+ object->get_symbol_name(r_sym), r_sym);
+ }
+ else
+ {
+ gold_error_at_location(
+ relinfo, shndx, offset,
+ _("relocation refers to global symbol \"%s\", "
+ "which is defined in a discarded section"),
+ gsym->demangled_name().c_str());
+ }
+
+ bool is_ordinary;
+ typename elfcpp::Elf_types<size>::Elf_Addr value;
+ unsigned int orig_shndx = object->symbol_section_and_value(r_sym, &value,
+ &is_ordinary);
+ if (orig_shndx != elfcpp::SHN_UNDEF)
+ {
+ unsigned int key_symndx;
+ Relobj* kept_obj = object->find_kept_section_object(orig_shndx,
+ &key_symndx);
+ if (key_symndx != 0)
+ gold_info(_(" section group signature: \"%s\""),
+ object->get_symbol_name(key_symndx));
+ if (kept_obj != NULL)
+ gold_info(_(" prevailing definition is from %s"),
+ kept_obj->name().c_str());
+ }
+}
+
// This function implements the generic part of relocation processing.
// The template parameter Relocate must be a class type which provides
// a single function, relocate(), which implements the machine
const Symbol_value<size> *psymval;
bool is_defined_in_discarded_section;
unsigned int shndx;
+ const Symbol* gsym = NULL;
if (r_sym < local_count
&& (reloc_symbol_changes == NULL
|| (*reloc_symbol_changes)[i] == NULL))
}
else
{
- const Symbol* gsym;
if (reloc_symbol_changes != NULL
&& (*reloc_symbol_changes)[i] != NULL)
gsym = (*reloc_symbol_changes)[i];
Symbol_value<size> symval2;
if (is_defined_in_discarded_section)
{
+ std::string name = object->section_name(relinfo->data_shndx);
+
if (comdat_behavior == CB_UNDETERMINED)
- {
- std::string name = object->section_name(relinfo->data_shndx);
comdat_behavior = relocate_comdat_behavior.get(name.c_str());
- }
+
if (comdat_behavior == CB_PRETEND)
{
// FIXME: This case does not work for global symbols.
// script.
bool found;
typename elfcpp::Elf_types<size>::Elf_Addr value =
- object->map_to_kept_section(shndx, &found);
+ object->map_to_kept_section(shndx, name, &found);
if (found)
symval2.set_output_value(value + psymval->input_value());
else
}
else
{
- if (comdat_behavior == CB_WARNING)
- gold_warning_at_location(relinfo, i, offset,
- _("relocation refers to discarded "
- "section"));
+ if (comdat_behavior == CB_ERROR)
+ issue_discarded_error(relinfo, i, offset, r_sym, gsym);
symval2.set_output_value(0);
}
symval2.set_no_output_symtab_entry();
unsigned char* pwrite = reloc_view;
+ const bool relocatable = parameters->options().relocatable();
+
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
{
Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i);
// In an object file, r_offset is an offset within the section.
// In an executable or dynamic object, generated by
// --emit-relocs, r_offset is an absolute address.
- if (!parameters->options().relocatable())
+ if (!relocatable)
{
new_offset += view_address;
if (offset_in_output_section != invalid_address)
{
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
{
- typename elfcpp::Elf_types<size>::Elf_Swxword addend;
- addend = Classify_reloc::get_r_addend(&reloc);
- gold_assert(os != NULL);
- addend = psymval->value(object, addend) - os->address();
+ typename elfcpp::Elf_types<size>::Elf_Swxword addend
+ = Classify_reloc::get_r_addend(&reloc);
+ addend = psymval->value(object, addend);
+ // In a relocatable link, the symbol value is relative to
+ // the start of the output section. For a non-relocatable
+ // link, we need to adjust the addend.
+ if (!relocatable)
+ {
+ gold_assert(os != NULL);
+ addend -= os->address();
+ }
Classify_reloc::put_r_addend(&reloc_write, addend);
}
break;