aboutsummaryrefslogtreecommitdiff
path: root/gold/object.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@gmail.com>2017-11-28 18:09:41 -0800
committerCary Coutant <ccoutant@gmail.com>2017-11-28 18:09:41 -0800
commit8de0e07bf381f677bb93a8da72185a54e5b014bd (patch)
treed598f897f5281705c96ff2d4c42afd59d9521426 /gold/object.cc
parent144653ec15141907a3276b6181c4d1114f71be13 (diff)
downloadgdb-8de0e07bf381f677bb93a8da72185a54e5b014bd.zip
gdb-8de0e07bf381f677bb93a8da72185a54e5b014bd.tar.gz
gdb-8de0e07bf381f677bb93a8da72185a54e5b014bd.tar.bz2
Allow multiple .eh_frame sections per object file.
LLVM is experimenting with placing .eh_frame sections in the COMDAT group with the function's text. This triggers an internal error in gold because we don't expect to see but one .eh_frame section in an object, and we use a single data member in class Sized_relobj_file to keep track of that section. This patch removes that data member, and instead checks the output section and the input section offset to identify an optimized .eh_frame section. gold/ * object.h (class Sized_relobj_file): Remove discarded_eh_frame_shndx_. * object.cc (Sized_relobj_file::Sized_relobj_file): Likewise. (Sized_relobj_file::layout_eh_frame_section): Likewise. (Sized_relobj_file::do_count_local_symbols): Check for optimized .eh_frame section by other means. (Sized_relobj_file::compute_final_local_value_internal): Likewise.
Diffstat (limited to 'gold/object.cc')
-rw-r--r--gold/object.cc23
1 files changed, 10 insertions, 13 deletions
diff --git a/gold/object.cc b/gold/object.cc
index f7fe088..ee99c5f 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -476,7 +476,6 @@ Sized_relobj_file<size, big_endian>::Sized_relobj_file(
local_plt_offsets_(),
kept_comdat_sections_(),
has_eh_frame_(false),
- discarded_eh_frame_shndx_(-1U),
is_deferred_layout_(false),
deferred_layout_(),
deferred_layout_relocs_(),
@@ -1303,13 +1302,7 @@ Sized_relobj_file<size, big_endian>::layout_eh_frame_section(
&offset);
this->output_sections()[shndx] = os;
if (os == NULL || offset == -1)
- {
- // An object can contain at most one section holding exception
- // frame information.
- gold_assert(this->discarded_eh_frame_shndx_ == -1U);
- this->discarded_eh_frame_shndx_ = shndx;
- this->section_offsets()[shndx] = invalid_address;
- }
+ this->section_offsets()[shndx] = invalid_address;
else
this->section_offsets()[shndx] = convert_types<Address, off_t>(offset);
@@ -2226,9 +2219,13 @@ Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
// Decide whether this symbol should go into the output file.
if (is_ordinary
- && ((shndx < shnum && out_sections[shndx] == NULL)
- || shndx == this->discarded_eh_frame_shndx_))
+ && shndx < shnum
+ && (out_sections[shndx] == NULL
+ || (out_sections[shndx]->order() == ORDER_EHFRAME
+ && out_section_offsets[shndx] == invalid_address)))
{
+ // This is either a discarded section or an optimized .eh_frame
+ // section.
lv.set_no_output_symtab_entry();
gold_assert(!lv.needs_output_dynsym_entry());
continue;
@@ -2393,10 +2390,10 @@ Sized_relobj_file<size, big_endian>::compute_final_local_value_internal(
// This is a SHF_MERGE section or one which otherwise
// requires special handling.
- if (shndx == this->discarded_eh_frame_shndx_)
+ if (os->order() == ORDER_EHFRAME)
{
- // This local symbol belongs to a discarded .eh_frame
- // section. Just treat it like the case in which
+ // This local symbol belongs to a discarded or optimized
+ // .eh_frame section. Just treat it like the case in which
// os == NULL above.
gold_assert(this->has_eh_frame_);
return This::CFLV_DISCARDED;