Fix problem where mixed section types can cause internal error during a -r link.
During a -r (or --emit-relocs) link, if two sections had the same name but different section types, gold would put relocations for both sections into the same relocation section even though the data sections remained separate. For .eh_frame sections, when one section is PROGBITS and another is X86_64_UNWIND, we really should be using the UNWIND section type and combining the sections anyway. For other sections, we should be creating one relocation section for each output data section. gold/ PR gold/23016 * incremental.cc (can_incremental_update): Check for unwind section type. * layout.h (Layout::layout): Add sh_type parameter. * layout.cc (Layout::layout): Likewise. (Layout::layout_reloc): Create new output reloc section if data section does not already have one. (Layout::layout_eh_frame): Check for unwind section type. (Layout::make_eh_frame_section): Use unwind section type for .eh_frame and .eh_frame_hdr. * object.h (Sized_relobj_file::Shdr_write): New typedef. (Sized_relobj_file::layout_section): Add sh_type parameter. (Sized_relobj_file::Deferred_layout::Deferred_layout): Add sh_type parameter. * object.cc (Sized_relobj_file::check_eh_frame_flags): Check for unwind section type. (Sized_relobj_file::layout_section): Add sh_type parameter; pass it to Layout::layout. (Sized_relobj_file::do_layout): Make local copy of sh_type. Force .eh_frame sections to unwind section type. Pass sh_type to layout_section. (Sized_relobj_file<size, big_endian>::do_layout_deferred_sections): Pass sh_type to layout_section. * output.cc (Output_section::Output_section): Initialize reloc_section_. * output.h (Output_section::reloc_section): New method. (Output_section::set_reloc_section): New method. (Output_section::reloc_section_): New data member. * target.h (Target::unwind_section_type): New method. (Target::Target_info::unwind_section_type): New data member. * aarch64.cc (aarch64_info): Add unwind_section_type. * arm.cc (arm_info, arm_nacl_info): Likewise. * i386.cc (i386_info, i386_nacl_info, iamcu_info): Likewise. * mips.cc (mips_info, mips_nacl_info): Likewise. * powerpc.cc (powerpc_info): Likewise. * s390.cc (s390_info): Likewise. * sparc.cc (sparc_info): Likewise. * tilegx.cc (tilegx_info): Likewise. * x86_64.cc (x86_64_info, x86_64_nacl_info): Likewise. * testsuite/Makefile.am (pr23016_1, pr23016_2): New test cases. * testsuite/Makefile.in: Regenerate. * testsuite/testfile.cc: Add unwind_section_type. * testsuite/pr23016_1.sh: New test script. * testsuite/pr23016_1a.s: New source file. * testsuite/pr23016_1b.s: New source file. * testsuite/pr23016_2.sh: New test script. * testsuite/pr23016_2a.s: New source file. * testsuite/pr23016_2b.s: New source file.
This commit is contained in:
parent
8849a5e9ed
commit
bce5a025d2
@ -1,3 +1,55 @@
|
||||
2018-04-02 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/23016
|
||||
* incremental.cc (can_incremental_update): Check for unwind section
|
||||
type.
|
||||
* layout.h (Layout::layout): Add sh_type parameter.
|
||||
* layout.cc (Layout::layout): Likewise.
|
||||
(Layout::layout_reloc): Create new output reloc section if data
|
||||
section does not already have one.
|
||||
(Layout::layout_eh_frame): Check for unwind section type.
|
||||
(Layout::make_eh_frame_section): Use unwind section type for .eh_frame
|
||||
and .eh_frame_hdr.
|
||||
* object.h (Sized_relobj_file::Shdr_write): New typedef.
|
||||
(Sized_relobj_file::layout_section): Add sh_type parameter.
|
||||
(Sized_relobj_file::Deferred_layout::Deferred_layout): Add sh_type
|
||||
parameter.
|
||||
* object.cc (Sized_relobj_file::check_eh_frame_flags): Check for
|
||||
unwind section type.
|
||||
(Sized_relobj_file::layout_section): Add sh_type parameter; pass it
|
||||
to Layout::layout.
|
||||
(Sized_relobj_file::do_layout): Make local copy of sh_type.
|
||||
Force .eh_frame sections to unwind section type.
|
||||
Pass sh_type to layout_section.
|
||||
(Sized_relobj_file<size, big_endian>::do_layout_deferred_sections):
|
||||
Pass sh_type to layout_section.
|
||||
* output.cc (Output_section::Output_section): Initialize reloc_section_.
|
||||
* output.h (Output_section::reloc_section): New method.
|
||||
(Output_section::set_reloc_section): New method.
|
||||
(Output_section::reloc_section_): New data member.
|
||||
* target.h (Target::unwind_section_type): New method.
|
||||
(Target::Target_info::unwind_section_type): New data member.
|
||||
|
||||
* aarch64.cc (aarch64_info): Add unwind_section_type.
|
||||
* arm.cc (arm_info, arm_nacl_info): Likewise.
|
||||
* i386.cc (i386_info, i386_nacl_info, iamcu_info): Likewise.
|
||||
* mips.cc (mips_info, mips_nacl_info): Likewise.
|
||||
* powerpc.cc (powerpc_info): Likewise.
|
||||
* s390.cc (s390_info): Likewise.
|
||||
* sparc.cc (sparc_info): Likewise.
|
||||
* tilegx.cc (tilegx_info): Likewise.
|
||||
* x86_64.cc (x86_64_info, x86_64_nacl_info): Likewise.
|
||||
|
||||
* testsuite/Makefile.am (pr23016_1, pr23016_2): New test cases.
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
* testsuite/testfile.cc: Add unwind_section_type.
|
||||
* testsuite/pr23016_1.sh: New test script.
|
||||
* testsuite/pr23016_1a.s: New source file.
|
||||
* testsuite/pr23016_1b.s: New source file.
|
||||
* testsuite/pr23016_2.sh: New test script.
|
||||
* testsuite/pr23016_2a.s: New source file.
|
||||
* testsuite/pr23016_2b.s: New source file.
|
||||
|
||||
2018-03-28 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/21423
|
||||
|
@ -3565,6 +3565,7 @@ const Target::Target_info Target_aarch64<64, false>::aarch64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -3593,6 +3594,7 @@ const Target::Target_info Target_aarch64<32, false>::aarch64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -3621,6 +3623,7 @@ const Target::Target_info Target_aarch64<64, true>::aarch64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -3649,6 +3652,7 @@ const Target::Target_info Target_aarch64<32, true>::aarch64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// Get the GOT section, creating it if necessary.
|
||||
|
@ -3062,6 +3062,7 @@ const Target::Target_info Target_arm<big_endian>::arm_info =
|
||||
"aeabi", // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// Arm relocate functions class
|
||||
@ -13056,6 +13057,7 @@ const Target::Target_info Target_arm_nacl<big_endian>::arm_nacl_info =
|
||||
"aeabi", // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<bool big_endian>
|
||||
|
@ -925,6 +925,7 @@ const Target::Target_info Target_i386::i386_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// Get the GOT section, creating it if necessary.
|
||||
@ -4203,6 +4204,7 @@ const Target::Target_info Target_i386_nacl::i386_nacl_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
#define NACLMASK 0xe0 // 32-byte alignment mask
|
||||
@ -4440,6 +4442,7 @@ const Target::Target_info Target_iamcu::iamcu_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
class Target_selector_iamcu : public Target_selector
|
||||
|
@ -173,8 +173,8 @@ Incremental_binary::error(const char* format, ...) const
|
||||
|
||||
// Return TRUE if a section of type SH_TYPE can be updated in place
|
||||
// during an incremental update. We can update sections of type PROGBITS,
|
||||
// NOBITS, INIT_ARRAY, FINI_ARRAY, PREINIT_ARRAY, and NOTE. All others
|
||||
// will be regenerated.
|
||||
// NOBITS, INIT_ARRAY, FINI_ARRAY, PREINIT_ARRAY, NOTE, and
|
||||
// (processor-specific) unwind sections. All others will be regenerated.
|
||||
|
||||
bool
|
||||
can_incremental_update(unsigned int sh_type)
|
||||
@ -184,7 +184,8 @@ can_incremental_update(unsigned int sh_type)
|
||||
|| sh_type == elfcpp::SHT_INIT_ARRAY
|
||||
|| sh_type == elfcpp::SHT_FINI_ARRAY
|
||||
|| sh_type == elfcpp::SHT_PREINIT_ARRAY
|
||||
|| sh_type == elfcpp::SHT_NOTE);
|
||||
|| sh_type == elfcpp::SHT_NOTE
|
||||
|| sh_type == parameters->target().unwind_section_type());
|
||||
}
|
||||
|
||||
// Find the .gnu_incremental_inputs section and related sections.
|
||||
|
@ -1153,15 +1153,14 @@ template<int size, bool big_endian>
|
||||
Output_section*
|
||||
Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
|
||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||
unsigned int reloc_shndx, unsigned int, off_t* off)
|
||||
unsigned int sh_type, unsigned int reloc_shndx,
|
||||
unsigned int, off_t* off)
|
||||
{
|
||||
*off = 0;
|
||||
|
||||
if (!this->include_section(object, name, shdr))
|
||||
return NULL;
|
||||
|
||||
elfcpp::Elf_Word sh_type = shdr.get_sh_type();
|
||||
|
||||
// In a relocatable link a grouped section must not be combined with
|
||||
// any other sections.
|
||||
Output_section* os;
|
||||
@ -1315,7 +1314,7 @@ Layout::insert_section_segment_map(Const_section_id secn,
|
||||
|
||||
template<int size, bool big_endian>
|
||||
Output_section*
|
||||
Layout::layout_reloc(Sized_relobj_file<size, big_endian>* object,
|
||||
Layout::layout_reloc(Sized_relobj_file<size, big_endian>*,
|
||||
unsigned int,
|
||||
const elfcpp::Shdr<size, big_endian>& shdr,
|
||||
Output_section* data_section,
|
||||
@ -1335,24 +1334,19 @@ Layout::layout_reloc(Sized_relobj_file<size, big_endian>* object,
|
||||
gold_unreachable();
|
||||
name += data_section->name();
|
||||
|
||||
// In a relocatable link relocs for a grouped section must not be
|
||||
// combined with other reloc sections.
|
||||
Output_section* os;
|
||||
if (!parameters->options().relocatable()
|
||||
|| (data_section->flags() & elfcpp::SHF_GROUP) == 0)
|
||||
os = this->choose_output_section(object, name.c_str(), sh_type,
|
||||
shdr.get_sh_flags(), false,
|
||||
ORDER_INVALID, false, true, false);
|
||||
else
|
||||
// If the output data section already has a reloc section, use that;
|
||||
// otherwise, make a new one.
|
||||
Output_section* os = data_section->reloc_section();
|
||||
if (os == NULL)
|
||||
{
|
||||
const char* n = this->namepool_.add(name.c_str(), true, NULL);
|
||||
os = this->make_output_section(n, sh_type, shdr.get_sh_flags(),
|
||||
ORDER_INVALID, false);
|
||||
os->set_should_link_to_symtab();
|
||||
os->set_info_section(data_section);
|
||||
data_section->set_reloc_section(os);
|
||||
}
|
||||
|
||||
os->set_should_link_to_symtab();
|
||||
os->set_info_section(data_section);
|
||||
|
||||
Output_section_data* posd;
|
||||
if (sh_type == elfcpp::SHT_REL)
|
||||
{
|
||||
@ -1442,8 +1436,11 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int reloc_shndx, unsigned int reloc_type,
|
||||
off_t* off)
|
||||
{
|
||||
const unsigned int unwind_section_type =
|
||||
parameters->target().unwind_section_type();
|
||||
|
||||
gold_assert(shdr.get_sh_type() == elfcpp::SHT_PROGBITS
|
||||
|| shdr.get_sh_type() == elfcpp::SHT_X86_64_UNWIND);
|
||||
|| shdr.get_sh_type() == unwind_section_type);
|
||||
gold_assert((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
|
||||
|
||||
Output_section* os = this->make_eh_frame_section(object);
|
||||
@ -1530,10 +1527,11 @@ Layout::finalize_eh_frame_section()
|
||||
Output_section*
|
||||
Layout::make_eh_frame_section(const Relobj* object)
|
||||
{
|
||||
// FIXME: On x86_64, this could use SHT_X86_64_UNWIND rather than
|
||||
// SHT_PROGBITS.
|
||||
const unsigned int unwind_section_type =
|
||||
parameters->target().unwind_section_type();
|
||||
|
||||
Output_section* os = this->choose_output_section(object, ".eh_frame",
|
||||
elfcpp::SHT_PROGBITS,
|
||||
unwind_section_type,
|
||||
elfcpp::SHF_ALLOC, false,
|
||||
ORDER_EHFRAME, false, false,
|
||||
false);
|
||||
@ -1551,7 +1549,7 @@ Layout::make_eh_frame_section(const Relobj* object)
|
||||
{
|
||||
Output_section* hdr_os =
|
||||
this->choose_output_section(NULL, ".eh_frame_hdr",
|
||||
elfcpp::SHT_PROGBITS,
|
||||
unwind_section_type,
|
||||
elfcpp::SHF_ALLOC, false,
|
||||
ORDER_EHFRAME, false, false,
|
||||
false);
|
||||
@ -5915,7 +5913,7 @@ Layout::layout<32, false>(Sized_relobj_file<32, false>* object,
|
||||
unsigned int shndx,
|
||||
const char* name,
|
||||
const elfcpp::Shdr<32, false>& shdr,
|
||||
unsigned int, unsigned int, off_t*);
|
||||
unsigned int, unsigned int, unsigned int, off_t*);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
@ -5925,7 +5923,7 @@ Layout::layout<32, true>(Sized_relobj_file<32, true>* object,
|
||||
unsigned int shndx,
|
||||
const char* name,
|
||||
const elfcpp::Shdr<32, true>& shdr,
|
||||
unsigned int, unsigned int, off_t*);
|
||||
unsigned int, unsigned int, unsigned int, off_t*);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
@ -5935,7 +5933,7 @@ Layout::layout<64, false>(Sized_relobj_file<64, false>* object,
|
||||
unsigned int shndx,
|
||||
const char* name,
|
||||
const elfcpp::Shdr<64, false>& shdr,
|
||||
unsigned int, unsigned int, off_t*);
|
||||
unsigned int, unsigned int, unsigned int, off_t*);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
@ -5945,7 +5943,7 @@ Layout::layout<64, true>(Sized_relobj_file<64, true>* object,
|
||||
unsigned int shndx,
|
||||
const char* name,
|
||||
const elfcpp::Shdr<64, true>& shdr,
|
||||
unsigned int, unsigned int, off_t*);
|
||||
unsigned int, unsigned int, unsigned int, off_t*);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
|
@ -537,7 +537,8 @@ class Layout
|
||||
Output_section*
|
||||
layout(Sized_relobj_file<size, big_endian> *object, unsigned int shndx,
|
||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
||||
unsigned int sh_type, unsigned int reloc_shndx,
|
||||
unsigned int reloc_type, off_t* offset);
|
||||
|
||||
std::map<Section_id, unsigned int>*
|
||||
get_section_order_map()
|
||||
|
@ -12633,6 +12633,7 @@ const Target::Target_info Target_mips<size, big_endian>::mips_info =
|
||||
NULL, // attributes_vendor
|
||||
"__start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<int size, bool big_endian>
|
||||
@ -12673,6 +12674,7 @@ const Target::Target_info Target_mips_nacl<size, big_endian>::mips_nacl_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// Target selector for Mips. Note this is never instantiated directly.
|
||||
|
@ -574,7 +574,7 @@ Sized_relobj_file<size, big_endian>::check_eh_frame_flags(
|
||||
{
|
||||
elfcpp::Elf_Word sh_type = shdr->get_sh_type();
|
||||
return ((sh_type == elfcpp::SHT_PROGBITS
|
||||
|| sh_type == elfcpp::SHT_X86_64_UNWIND)
|
||||
|| sh_type == parameters->target().unwind_section_type())
|
||||
&& (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
|
||||
}
|
||||
|
||||
@ -1252,12 +1252,13 @@ Sized_relobj_file<size, big_endian>::layout_section(
|
||||
unsigned int shndx,
|
||||
const char* name,
|
||||
const typename This::Shdr& shdr,
|
||||
unsigned int sh_type,
|
||||
unsigned int reloc_shndx,
|
||||
unsigned int reloc_type)
|
||||
{
|
||||
off_t offset;
|
||||
Output_section* os = layout->layout(this, shndx, name, shdr,
|
||||
reloc_shndx, reloc_type, &offset);
|
||||
Output_section* os = layout->layout(this, shndx, name, shdr, sh_type,
|
||||
reloc_shndx, reloc_type, &offset);
|
||||
|
||||
this->output_sections()[shndx] = os;
|
||||
if (offset == -1)
|
||||
@ -1337,6 +1338,8 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
Layout* layout,
|
||||
Read_symbols_data* sd)
|
||||
{
|
||||
const unsigned int unwind_section_type =
|
||||
parameters->target().unwind_section_type();
|
||||
const unsigned int shnum = this->shnum();
|
||||
|
||||
/* Should this function be called twice? */
|
||||
@ -1522,15 +1525,17 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
for (unsigned int i = 1; i < shnum; ++i, pshdrs += This::shdr_size)
|
||||
{
|
||||
typename This::Shdr shdr(pshdrs);
|
||||
const unsigned int sh_name = shdr.get_sh_name();
|
||||
unsigned int sh_type = shdr.get_sh_type();
|
||||
|
||||
if (shdr.get_sh_name() >= section_names_size)
|
||||
if (sh_name >= section_names_size)
|
||||
{
|
||||
this->error(_("bad section name offset for section %u: %lu"),
|
||||
i, static_cast<unsigned long>(shdr.get_sh_name()));
|
||||
i, static_cast<unsigned long>(sh_name));
|
||||
return;
|
||||
}
|
||||
|
||||
const char* name = pnames + shdr.get_sh_name();
|
||||
const char* name = pnames + sh_name;
|
||||
|
||||
if (!is_pass_two)
|
||||
{
|
||||
@ -1568,7 +1573,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
bool discard = omit[i];
|
||||
if (!discard)
|
||||
{
|
||||
if (shdr.get_sh_type() == elfcpp::SHT_GROUP)
|
||||
if (sh_type == elfcpp::SHT_GROUP)
|
||||
{
|
||||
if (!this->include_section_group(symtab, layout, i, name,
|
||||
shdrs, pnames,
|
||||
@ -1588,7 +1593,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
Incremental_inputs* incremental_inputs = layout->incremental_inputs();
|
||||
if (incremental_inputs != NULL
|
||||
&& !discard
|
||||
&& can_incremental_update(shdr.get_sh_type()))
|
||||
&& can_incremental_update(sh_type))
|
||||
{
|
||||
off_t sh_size = shdr.get_sh_size();
|
||||
section_size_type uncompressed_size;
|
||||
@ -1610,8 +1615,8 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
{
|
||||
if (this->is_section_name_included(name)
|
||||
|| layout->keep_input_section (this, name)
|
||||
|| shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY
|
||||
|| shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY)
|
||||
|| sh_type == elfcpp::SHT_INIT_ARRAY
|
||||
|| sh_type == elfcpp::SHT_FINI_ARRAY)
|
||||
{
|
||||
symtab->gc()->worklist().push_back(Section_id(this, i));
|
||||
}
|
||||
@ -1632,14 +1637,14 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
// reloc sections and process them later. Garbage collection is
|
||||
// not triggered when relocatable code is desired.
|
||||
if (emit_relocs
|
||||
&& (shdr.get_sh_type() == elfcpp::SHT_REL
|
||||
|| shdr.get_sh_type() == elfcpp::SHT_RELA))
|
||||
&& (sh_type == elfcpp::SHT_REL
|
||||
|| sh_type == elfcpp::SHT_RELA))
|
||||
{
|
||||
reloc_sections.push_back(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (relocatable && shdr.get_sh_type() == elfcpp::SHT_GROUP)
|
||||
if (relocatable && sh_type == elfcpp::SHT_GROUP)
|
||||
continue;
|
||||
|
||||
// The .eh_frame section is special. It holds exception frame
|
||||
@ -1648,26 +1653,30 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
// sections so that the exception frame reader can reliably
|
||||
// determine which sections are being discarded, and discard the
|
||||
// corresponding information.
|
||||
if (!relocatable
|
||||
&& strcmp(name, ".eh_frame") == 0
|
||||
&& this->check_eh_frame_flags(&shdr))
|
||||
if (this->check_eh_frame_flags(&shdr)
|
||||
&& strcmp(name, ".eh_frame") == 0)
|
||||
{
|
||||
if (is_pass_one)
|
||||
// If the target has a special unwind section type, let's
|
||||
// canonicalize it here.
|
||||
sh_type = unwind_section_type;
|
||||
if (!relocatable)
|
||||
{
|
||||
if (this->is_deferred_layout())
|
||||
out_sections[i] = reinterpret_cast<Output_section*>(2);
|
||||
if (is_pass_one)
|
||||
{
|
||||
if (this->is_deferred_layout())
|
||||
out_sections[i] = reinterpret_cast<Output_section*>(2);
|
||||
else
|
||||
out_sections[i] = reinterpret_cast<Output_section*>(1);
|
||||
out_section_offsets[i] = invalid_address;
|
||||
}
|
||||
else if (this->is_deferred_layout())
|
||||
this->deferred_layout_.push_back(
|
||||
Deferred_layout(i, name, sh_type, pshdrs,
|
||||
reloc_shndx[i], reloc_type[i]));
|
||||
else
|
||||
out_sections[i] = reinterpret_cast<Output_section*>(1);
|
||||
out_section_offsets[i] = invalid_address;
|
||||
eh_frame_sections.push_back(i);
|
||||
continue;
|
||||
}
|
||||
else if (this->is_deferred_layout())
|
||||
this->deferred_layout_.push_back(Deferred_layout(i, name,
|
||||
pshdrs,
|
||||
reloc_shndx[i],
|
||||
reloc_type[i]));
|
||||
else
|
||||
eh_frame_sections.push_back(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_pass_two && parameters->options().gc_sections())
|
||||
@ -1731,7 +1740,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
&& this->is_deferred_layout()
|
||||
&& (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
|
||||
{
|
||||
this->deferred_layout_.push_back(Deferred_layout(i, name,
|
||||
this->deferred_layout_.push_back(Deferred_layout(i, name, sh_type,
|
||||
pshdrs,
|
||||
reloc_shndx[i],
|
||||
reloc_type[i]));
|
||||
@ -1760,7 +1769,7 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
{
|
||||
// When garbage collection is switched on the actual layout
|
||||
// only happens in the second call.
|
||||
this->layout_section(layout, i, name, shdr, reloc_shndx[i],
|
||||
this->layout_section(layout, i, name, shdr, sh_type, reloc_shndx[i],
|
||||
reloc_type[i]);
|
||||
|
||||
// When generating a .gdb_index section, we do additional
|
||||
@ -1838,7 +1847,8 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
|
||||
// to defer the relocation section, too.
|
||||
const char* name = pnames + shdr.get_sh_name();
|
||||
this->deferred_layout_relocs_.push_back(
|
||||
Deferred_layout(i, name, pshdr, 0, elfcpp::SHT_NULL));
|
||||
Deferred_layout(i, name, shdr.get_sh_type(), pshdr, 0,
|
||||
elfcpp::SHT_NULL));
|
||||
out_sections[i] = reinterpret_cast<Output_section*>(2);
|
||||
out_section_offsets[i] = invalid_address;
|
||||
continue;
|
||||
@ -1949,7 +1959,7 @@ Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
|
||||
continue;
|
||||
|
||||
this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
|
||||
shdr, deferred->reloc_shndx_,
|
||||
shdr, shdr.get_sh_type(), deferred->reloc_shndx_,
|
||||
deferred->reloc_type_);
|
||||
}
|
||||
|
||||
|
@ -2591,6 +2591,7 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||
static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||
static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||
typedef elfcpp::Shdr<size, big_endian> Shdr;
|
||||
typedef elfcpp::Shdr_write<size, big_endian> Shdr_write;
|
||||
|
||||
// To keep track of discarded comdat sections, we need to map a member
|
||||
// section index to the object and section index of the corresponding
|
||||
@ -2635,8 +2636,8 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||
// Layout an input section.
|
||||
void
|
||||
layout_section(Layout* layout, unsigned int shndx, const char* name,
|
||||
const typename This::Shdr& shdr, unsigned int reloc_shndx,
|
||||
unsigned int reloc_type);
|
||||
const typename This::Shdr& shdr, unsigned int sh_type,
|
||||
unsigned int reloc_shndx, unsigned int reloc_type);
|
||||
|
||||
// Layout an input .eh_frame section.
|
||||
void
|
||||
@ -2798,15 +2799,18 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||
{
|
||||
static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||
Deferred_layout(unsigned int shndx, const char* name,
|
||||
unsigned int sh_type,
|
||||
const unsigned char* pshdr,
|
||||
unsigned int reloc_shndx, unsigned int reloc_type)
|
||||
: shndx_(shndx), name_(name), reloc_shndx_(reloc_shndx),
|
||||
: name_(name), shndx_(shndx), reloc_shndx_(reloc_shndx),
|
||||
reloc_type_(reloc_type)
|
||||
{
|
||||
typename This::Shdr_write shdr(this->shdr_data_);
|
||||
memcpy(this->shdr_data_, pshdr, shdr_size);
|
||||
shdr.put_sh_type(sh_type);
|
||||
}
|
||||
unsigned int shndx_;
|
||||
std::string name_;
|
||||
unsigned int shndx_;
|
||||
unsigned int reloc_shndx_;
|
||||
unsigned int reloc_type_;
|
||||
unsigned char shdr_data_[shdr_size];
|
||||
|
@ -2395,7 +2395,8 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
|
||||
lookup_maps_(new Output_section_lookup_maps),
|
||||
free_list_(),
|
||||
free_space_fill_(NULL),
|
||||
patch_space_(0)
|
||||
patch_space_(0),
|
||||
reloc_section_(NULL)
|
||||
{
|
||||
// An unallocated section has no address. Forcing this means that
|
||||
// we don't need special treatment for symbols defined in debug
|
||||
|
@ -4136,6 +4136,16 @@ class Output_section : public Output_data
|
||||
input_sections()
|
||||
{ return this->input_sections_; }
|
||||
|
||||
// For -r and --emit-relocs, we need to keep track of the associated
|
||||
// relocation section.
|
||||
Output_section*
|
||||
reloc_section() const
|
||||
{ return this->reloc_section_; }
|
||||
|
||||
void
|
||||
set_reloc_section(Output_section* os)
|
||||
{ this->reloc_section_ = os; }
|
||||
|
||||
protected:
|
||||
// Return the output section--i.e., the object itself.
|
||||
Output_section*
|
||||
@ -4623,6 +4633,8 @@ class Output_section : public Output_data
|
||||
Output_fill* free_space_fill_;
|
||||
// Amount added as patch space for incremental linking.
|
||||
off_t patch_space_;
|
||||
// Associated relocation section, when emitting relocations.
|
||||
Output_section* reloc_section_;
|
||||
};
|
||||
|
||||
// An output segment. PT_LOAD segments are built from collections of
|
||||
|
@ -1625,6 +1625,7 @@ Target::Target_info Target_powerpc<32, true>::powerpc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -1653,6 +1654,7 @@ Target::Target_info Target_powerpc<32, false>::powerpc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -1681,6 +1683,7 @@ Target::Target_info Target_powerpc<64, true>::powerpc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -1709,6 +1712,7 @@ Target::Target_info Target_powerpc<64, false>::powerpc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
@ -827,6 +827,7 @@ Target::Target_info Target_s390<32>::s390_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -855,6 +856,7 @@ Target::Target_info Target_s390<64>::s390_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
64, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<int size>
|
||||
|
@ -499,6 +499,7 @@ Target::Target_info Target_sparc<32, true>::sparc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -527,6 +528,7 @@ Target::Target_info Target_sparc<64, true>::sparc_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// We have to take care here, even when operating in little-endian
|
||||
|
@ -474,6 +474,11 @@ class Target
|
||||
hash_entry_size() const
|
||||
{ return this->pti_->hash_entry_size; }
|
||||
|
||||
// Return the section type to use for unwind sections.
|
||||
unsigned int
|
||||
unwind_section_type() const
|
||||
{ return this->pti_->unwind_section_type; }
|
||||
|
||||
// Whether the target has a custom set_dynsym_indexes method.
|
||||
bool
|
||||
has_custom_set_dynsym_indexes() const
|
||||
@ -562,6 +567,9 @@ class Target
|
||||
// Size (in bits) of SHT_HASH entry. Always equal to 32, except for
|
||||
// 64-bit S/390.
|
||||
const int hash_entry_size;
|
||||
// Processor-specific section type for ".eh_frame" (unwind) sections.
|
||||
// SHT_PROGBITS if there is no special section type.
|
||||
const unsigned int unwind_section_type;
|
||||
};
|
||||
|
||||
Target(const Target_info* pti)
|
||||
|
@ -1211,6 +1211,32 @@ x32_overflow_pc32.err: x32_overflow_pc32.o gcctestdir/ld
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
check_SCRIPTS += pr23016_1.sh
|
||||
check_DATA += pr23016_1.stdout pr23016_1r.stdout
|
||||
pr23016_1.stdout: pr23016_1.o
|
||||
$(TEST_READELF) -rSW $< >$@ 2>/dev/null
|
||||
pr23016_1.o: pr23016_1a.o pr23016_1b.o gcctestdir/ld
|
||||
gcctestdir/ld -r -o $@ pr23016_1a.o pr23016_1b.o
|
||||
pr23016_1r.stdout: pr23016_1r.o
|
||||
$(TEST_READELF) -rSW $< >$@ 2>/dev/null
|
||||
pr23016_1r.o: pr23016_1a.o pr23016_1b.o gcctestdir/ld
|
||||
gcctestdir/ld -r -o $@ pr23016_1b.o pr23016_1a.o
|
||||
pr23016_1a.o: pr23016_1a.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
pr23016_1b.o: pr23016_1b.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
|
||||
check_SCRIPTS += pr23016_2.sh
|
||||
check_DATA += pr23016_2.stdout
|
||||
pr23016_2.stdout: pr23016_2.o
|
||||
$(TEST_READELF) -rW $< >$@ 2>/dev/null
|
||||
pr23016_2.o: pr23016_2a.o pr23016_2b.o gcctestdir/ld
|
||||
gcctestdir/ld -r -o $@ pr23016_2a.o pr23016_2b.o
|
||||
pr23016_2a.o: pr23016_2a.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
pr23016_2b.o: pr23016_2b.s
|
||||
$(TEST_AS) -o $@ $<
|
||||
|
||||
endif DEFAULT_TARGET_X86_64
|
||||
|
||||
if DEFAULT_TARGET_X86_64_OR_X32
|
||||
|
@ -252,7 +252,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_29 = x86_64_mov_to_lea.sh \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_call_to_direct.sh \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_overflow_pc32.sh \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x32_overflow_pc32.sh
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x32_overflow_pc32.sh \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr23016_1.sh \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr23016_2.sh
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_30 = x86_64_mov_to_lea1.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea2.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea3.stdout \
|
||||
@ -270,7 +272,10 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_call_to_direct1.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_indirect_jump_to_direct1.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_overflow_pc32.err \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x32_overflow_pc32.err
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x32_overflow_pc32.err \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr23016_1.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr23016_1r.stdout \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ pr23016_2.stdout
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_31 = x86_64_mov_to_lea1 \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea2 \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ x86_64_mov_to_lea3 \
|
||||
@ -5269,6 +5274,10 @@ x86_64_overflow_pc32.sh.log: x86_64_overflow_pc32.sh
|
||||
@p='x86_64_overflow_pc32.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
x32_overflow_pc32.sh.log: x32_overflow_pc32.sh
|
||||
@p='x32_overflow_pc32.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
pr23016_1.sh.log: pr23016_1.sh
|
||||
@p='pr23016_1.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
pr23016_2.sh.log: pr23016_2.sh
|
||||
@p='pr23016_2.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
i386_mov_to_lea.sh.log: i386_mov_to_lea.sh
|
||||
@p='i386_mov_to_lea.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
file_in_many_sections_test.sh.log: file_in_many_sections_test.sh
|
||||
@ -6489,6 +6498,26 @@ uninstall-am:
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@; \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ exit 1; \
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ fi
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1.stdout: pr23016_1.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -rSW $< >$@ 2>/dev/null
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1.o: pr23016_1a.o pr23016_1b.o gcctestdir/ld
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -r -o $@ pr23016_1a.o pr23016_1b.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1r.stdout: pr23016_1r.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -rSW $< >$@ 2>/dev/null
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1r.o: pr23016_1a.o pr23016_1b.o gcctestdir/ld
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -r -o $@ pr23016_1b.o pr23016_1a.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1a.o: pr23016_1a.s
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_1b.o: pr23016_1b.s
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_2.stdout: pr23016_2.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -rW $< >$@ 2>/dev/null
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_2.o: pr23016_2a.o pr23016_2b.o gcctestdir/ld
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -r -o $@ pr23016_2a.o pr23016_2b.o
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_2a.o: pr23016_2a.s
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr23016_2b.o: pr23016_2b.s
|
||||
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_X86_64_OR_X32_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@pr20216a.so: pr20216_gd.o pr20216_ld.o gcctestdir/ld
|
||||
@DEFAULT_TARGET_X86_64_OR_X32_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -shared pr20216_gd.o pr20216_ld.o
|
||||
|
87
gold/testsuite/pr23016_1.sh
Executable file
87
gold/testsuite/pr23016_1.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
|
||||
# pr23016_1.sh -- check that .eh_frame sections and their relocations
|
||||
# are merged together even when mixing SHT_PROGBITS and SHT_X86_64_UNWIND.
|
||||
|
||||
# Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
# Written by Cary Coutant <ccoutant@gmail.com>.
|
||||
|
||||
# This file is part of gold.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
|
||||
set -e
|
||||
|
||||
check() {
|
||||
awk -v "FILE=$1" '
|
||||
BEGIN {
|
||||
progbits = 0;
|
||||
unwind = 0;
|
||||
ehframe_rel = 0;
|
||||
relocx = 0;
|
||||
relocy = 0;
|
||||
}
|
||||
/\.eh_frame *PROGBITS/ {
|
||||
progbits++;
|
||||
}
|
||||
/\.eh_frame *X86_64_UNWIND/ {
|
||||
unwind++;
|
||||
}
|
||||
/^Relocation section .\.rela\.eh_frame/ {
|
||||
ehframe_rel++;
|
||||
}
|
||||
/R_X86_64_64.*x \+ 0/ {
|
||||
relocx++;
|
||||
}
|
||||
/R_X86_64_64.*y \+ 0/ {
|
||||
relocy++;
|
||||
}
|
||||
END {
|
||||
errs = 0;
|
||||
if (progbits != 0)
|
||||
{
|
||||
printf "%s: There should be no .eh_frame sections of type PROGBITS.\n", FILE;
|
||||
errs++;
|
||||
}
|
||||
if (unwind != 1)
|
||||
{
|
||||
printf "%s: There should be exactly one .eh_frame section of type X86_64_UNWIND.\n", FILE;
|
||||
errs++;
|
||||
}
|
||||
if (ehframe_rel != 1)
|
||||
{
|
||||
printf "%s: There should be exactly one .rela.eh_frame relocation section.\n", FILE;
|
||||
errs++;
|
||||
}
|
||||
if (relocx != 1)
|
||||
{
|
||||
printf "%s: There should be exactly one relocation for x.\n", FILE;
|
||||
errs++;
|
||||
}
|
||||
if (relocy != 1)
|
||||
{
|
||||
printf "%s: There should be exactly one relocation for y.\n", FILE;
|
||||
errs++;
|
||||
}
|
||||
exit errs;
|
||||
}
|
||||
' $1
|
||||
}
|
||||
|
||||
check pr23016_1.stdout
|
||||
check pr23016_1r.stdout
|
||||
|
||||
exit 0
|
3
gold/testsuite/pr23016_1a.s
Normal file
3
gold/testsuite/pr23016_1a.s
Normal file
@ -0,0 +1,3 @@
|
||||
.section .eh_frame,"aw",@progbits
|
||||
.globl x
|
||||
.quad x
|
3
gold/testsuite/pr23016_1b.s
Normal file
3
gold/testsuite/pr23016_1b.s
Normal file
@ -0,0 +1,3 @@
|
||||
.section .eh_frame,"aw",@unwind
|
||||
.globl y
|
||||
.quad y
|
57
gold/testsuite/pr23016_2.sh
Executable file
57
gold/testsuite/pr23016_2.sh
Executable file
@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
|
||||
# pr23016_2.sh -- check that relocations get written to separate sections
|
||||
# when data sections of the same name are not merged.
|
||||
|
||||
# Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
# Written by Cary Coutant <ccoutant@gmail.com>.
|
||||
|
||||
# This file is part of gold.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
# MA 02110-1301, USA.
|
||||
|
||||
set -e
|
||||
|
||||
awk '
|
||||
BEGIN {
|
||||
sect = 0;
|
||||
relocx = 0;
|
||||
relocy = 0;
|
||||
}
|
||||
/^Relocation section .\.relaone/ {
|
||||
sect += 1;
|
||||
}
|
||||
/R_X86_64_64.*x \+ 0/ {
|
||||
relocx += sect;
|
||||
}
|
||||
/R_X86_64_64.*y \+ 0/ {
|
||||
relocy = sect;
|
||||
}
|
||||
END {
|
||||
if (relocx != 1)
|
||||
{
|
||||
printf "Relocation for x should be in first relocation section.\n";
|
||||
exit 1;
|
||||
}
|
||||
if (relocy != 2)
|
||||
{
|
||||
printf "Relocation for y should be in second relocation section.\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
' pr23016_2.stdout
|
||||
|
||||
exit 0
|
3
gold/testsuite/pr23016_2a.s
Normal file
3
gold/testsuite/pr23016_2a.s
Normal file
@ -0,0 +1,3 @@
|
||||
.section one,"aw",@progbits
|
||||
.globl x
|
||||
.quad x
|
3
gold/testsuite/pr23016_2b.s
Normal file
3
gold/testsuite/pr23016_2b.s
Normal file
@ -0,0 +1,3 @@
|
||||
.section one,"aw",@note
|
||||
.globl y
|
||||
.quad y
|
@ -118,6 +118,7 @@ const Target::Target_info Target_test<size, big_endian>::test_target_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// The test targets.
|
||||
|
@ -688,6 +688,7 @@ const Target::Target_info Target_tilegx<64, false>::tilegx_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -716,6 +717,7 @@ const Target::Target_info Target_tilegx<32, false>::tilegx_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -744,6 +746,7 @@ const Target::Target_info Target_tilegx<64, true>::tilegx_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -772,6 +775,7 @@ const Target::Target_info Target_tilegx<32, true>::tilegx_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_PROGBITS, // unwind_section_type
|
||||
};
|
||||
|
||||
// tilegx relocation handlers
|
||||
|
@ -1273,6 +1273,7 @@ const Target::Target_info Target_x86_64<64>::x86_64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_X86_64_UNWIND, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -1301,6 +1302,7 @@ const Target::Target_info Target_x86_64<32>::x86_64_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_X86_64_UNWIND, // unwind_section_type
|
||||
};
|
||||
|
||||
// This is called when a new output section is created. This is where
|
||||
@ -5578,6 +5580,7 @@ const Target::Target_info Target_x86_64_nacl<64>::x86_64_nacl_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_X86_64_UNWIND, // unwind_section_type
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -5606,6 +5609,7 @@ const Target::Target_info Target_x86_64_nacl<32>::x86_64_nacl_info =
|
||||
NULL, // attributes_vendor
|
||||
"_start", // entry_symbol_name
|
||||
32, // hash_entry_size
|
||||
elfcpp::SHT_X86_64_UNWIND, // unwind_section_type
|
||||
};
|
||||
|
||||
#define NACLMASK 0xe0 // 32-byte alignment mask.
|
||||
|
Loading…
Reference in New Issue
Block a user