diff options
author | Cary Coutant <ccoutant@gmail.com> | 2018-04-02 16:12:10 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2018-04-02 19:07:04 -0700 |
commit | bce5a025d2ed7eda2c5bbb85bd9b33333ca5d556 (patch) | |
tree | 92912c522de8e45805825292a4a94e50f753584c /gold/object.h | |
parent | 8849a5e9edda5f00d727490c7bb8be3c616742ae (diff) | |
download | gdb-bce5a025d2ed7eda2c5bbb85bd9b33333ca5d556.zip gdb-bce5a025d2ed7eda2c5bbb85bd9b33333ca5d556.tar.gz gdb-bce5a025d2ed7eda2c5bbb85bd9b33333ca5d556.tar.bz2 |
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.
Diffstat (limited to 'gold/object.h')
-rw-r--r-- | gold/object.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/gold/object.h b/gold/object.h index c92e030..9fb9b30 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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]; |