mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 19:50:13 +08:00
Mips: Omit empty objects for merging processor-specific data.
gold/ * mips.cc (Mips_relobj::merge_processor_specific_data_): New data member. (Mips_relobj::merge_processor_specific_data): New method. (Mips_relobj::do_read_symbols): Set merge_processor_specific_data_ to false, only if the input file is a binary or if object has no contents except the section name string table and an empty symbol table with the undefined symbol. (Target_mips::do_finalize_sections): Refactor. Skip empty object files for merging processor-specific data.
This commit is contained in:

committed by
Cary Coutant

parent
152c92b261
commit
4d78db49e6
@ -1,3 +1,15 @@
|
|||||||
|
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
|
* mips.cc (Mips_relobj::merge_processor_specific_data_): New data
|
||||||
|
member.
|
||||||
|
(Mips_relobj::merge_processor_specific_data): New method.
|
||||||
|
(Mips_relobj::do_read_symbols): Set merge_processor_specific_data_
|
||||||
|
to false, only if the input file is a binary or if object has no
|
||||||
|
contents except the section name string table and an empty symbol
|
||||||
|
table with the undefined symbol.
|
||||||
|
(Target_mips::do_finalize_sections): Refactor. Skip empty object files
|
||||||
|
for merging processor-specific data.
|
||||||
|
|
||||||
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
* mips.cc (Target_mips::Relocate::calculated_value_): New data
|
* mips.cc (Target_mips::Relocate::calculated_value_): New data
|
||||||
|
97
gold/mips.cc
97
gold/mips.cc
@ -1592,10 +1592,11 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
|
|||||||
local_symbol_is_micromips_(), mips16_stub_sections_(),
|
local_symbol_is_micromips_(), mips16_stub_sections_(),
|
||||||
local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(),
|
local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(),
|
||||||
local_mips16_call_stubs_(), gp_(0), has_reginfo_section_(false),
|
local_mips16_call_stubs_(), gp_(0), has_reginfo_section_(false),
|
||||||
got_info_(NULL), section_is_mips16_fn_stub_(),
|
merge_processor_specific_data_(true), got_info_(NULL),
|
||||||
section_is_mips16_call_stub_(), section_is_mips16_call_fp_stub_(),
|
section_is_mips16_fn_stub_(), section_is_mips16_call_stub_(),
|
||||||
pdr_shndx_(-1U), attributes_section_data_(NULL), abiflags_(NULL),
|
section_is_mips16_call_fp_stub_(), pdr_shndx_(-1U),
|
||||||
gprmask_(0), cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0)
|
attributes_section_data_(NULL), abiflags_(NULL), gprmask_(0),
|
||||||
|
cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0)
|
||||||
{
|
{
|
||||||
this->is_pic_ = (ehdr.get_e_flags() & elfcpp::EF_MIPS_PIC) != 0;
|
this->is_pic_ = (ehdr.get_e_flags() & elfcpp::EF_MIPS_PIC) != 0;
|
||||||
this->is_n32_ = elfcpp::abi_n32(ehdr.get_e_flags());
|
this->is_n32_ = elfcpp::abi_n32(ehdr.get_e_flags());
|
||||||
@ -1836,6 +1837,11 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
|
|||||||
has_reginfo_section() const
|
has_reginfo_section() const
|
||||||
{ return this->has_reginfo_section_; }
|
{ return this->has_reginfo_section_; }
|
||||||
|
|
||||||
|
// Return whether we want to merge processor-specific data.
|
||||||
|
bool
|
||||||
|
merge_processor_specific_data() const
|
||||||
|
{ return this->merge_processor_specific_data_; }
|
||||||
|
|
||||||
// Return gprmask from the .reginfo section of this object.
|
// Return gprmask from the .reginfo section of this object.
|
||||||
Valtype
|
Valtype
|
||||||
gprmask() const
|
gprmask() const
|
||||||
@ -1926,6 +1932,8 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian>
|
|||||||
bool is_n32_ : 1;
|
bool is_n32_ : 1;
|
||||||
// Whether the object contains a .reginfo section.
|
// Whether the object contains a .reginfo section.
|
||||||
bool has_reginfo_section_ : 1;
|
bool has_reginfo_section_ : 1;
|
||||||
|
// Whether we merge processor-specific data of this object to output.
|
||||||
|
bool merge_processor_specific_data_ : 1;
|
||||||
// The Mips_got_info for this object.
|
// The Mips_got_info for this object.
|
||||||
Mips_got_info<size, big_endian>* got_info_;
|
Mips_got_info<size, big_endian>* got_info_;
|
||||||
|
|
||||||
@ -6818,6 +6826,16 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
|||||||
// Call parent class to read symbol information.
|
// Call parent class to read symbol information.
|
||||||
this->base_read_symbols(sd);
|
this->base_read_symbols(sd);
|
||||||
|
|
||||||
|
// If this input file is a binary file, it has no processor
|
||||||
|
// specific data.
|
||||||
|
Input_file::Format format = this->input_file()->format();
|
||||||
|
if (format != Input_file::FORMAT_ELF)
|
||||||
|
{
|
||||||
|
gold_assert(format == Input_file::FORMAT_BINARY);
|
||||||
|
this->merge_processor_specific_data_ = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Read processor-specific flags in ELF file header.
|
// Read processor-specific flags in ELF file header.
|
||||||
const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
|
const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
|
||||||
elfcpp::Elf_sizes<size>::ehdr_size,
|
elfcpp::Elf_sizes<size>::ehdr_size,
|
||||||
@ -6837,10 +6855,27 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
|||||||
const size_t shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
const size_t shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
|
||||||
const unsigned char* pshdrs = sd->section_headers->data();
|
const unsigned char* pshdrs = sd->section_headers->data();
|
||||||
const unsigned char* ps = pshdrs + shdr_size;
|
const unsigned char* ps = pshdrs + shdr_size;
|
||||||
|
bool must_merge_processor_specific_data = false;
|
||||||
for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
|
for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
|
||||||
{
|
{
|
||||||
elfcpp::Shdr<size, big_endian> shdr(ps);
|
elfcpp::Shdr<size, big_endian> shdr(ps);
|
||||||
|
|
||||||
|
// Sometimes an object has no contents except the section name string
|
||||||
|
// table and an empty symbol table with the undefined symbol. We
|
||||||
|
// don't want to merge processor-specific data from such an object.
|
||||||
|
if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
|
||||||
|
{
|
||||||
|
// Symbol table is not empty.
|
||||||
|
const typename elfcpp::Elf_types<size>::Elf_WXword sym_size =
|
||||||
|
elfcpp::Elf_sizes<size>::sym_size;
|
||||||
|
if (shdr.get_sh_size() > sym_size)
|
||||||
|
must_merge_processor_specific_data = true;
|
||||||
|
}
|
||||||
|
else if (shdr.get_sh_type() != elfcpp::SHT_STRTAB)
|
||||||
|
// If this is neither an empty symbol table nor a string table,
|
||||||
|
// be conservative.
|
||||||
|
must_merge_processor_specific_data = true;
|
||||||
|
|
||||||
if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO)
|
if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO)
|
||||||
{
|
{
|
||||||
this->has_reginfo_section_ = true;
|
this->has_reginfo_section_ = true;
|
||||||
@ -7013,6 +7048,10 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
|||||||
this->pdr_shndx_ = i;
|
this->pdr_shndx_ = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is rare.
|
||||||
|
if (!must_merge_processor_specific_data)
|
||||||
|
this->merge_processor_specific_data_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard MIPS16 stub secions that are not needed.
|
// Discard MIPS16 stub secions that are not needed.
|
||||||
@ -9600,6 +9639,8 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
const Input_objects* input_objects,
|
const Input_objects* input_objects,
|
||||||
Symbol_table* symtab)
|
Symbol_table* symtab)
|
||||||
{
|
{
|
||||||
|
const bool relocatable = parameters->options().relocatable();
|
||||||
|
|
||||||
// Add +1 to MIPS16 and microMIPS init_ and _fini symbols so that DT_INIT and
|
// Add +1 to MIPS16 and microMIPS init_ and _fini symbols so that DT_INIT and
|
||||||
// DT_FINI have correct values.
|
// DT_FINI have correct values.
|
||||||
Mips_symbol<size>* init = static_cast<Mips_symbol<size>*>(
|
Mips_symbol<size>* init = static_cast<Mips_symbol<size>*>(
|
||||||
@ -9633,19 +9674,6 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
if (this->got16_addends_.size() > 0)
|
if (this->got16_addends_.size() > 0)
|
||||||
gold_error("Can't find matching LO16 reloc");
|
gold_error("Can't find matching LO16 reloc");
|
||||||
|
|
||||||
// Check for any mips16 stub sections that we can discard.
|
|
||||||
if (!parameters->options().relocatable())
|
|
||||||
{
|
|
||||||
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
|
|
||||||
p != input_objects->relobj_end();
|
|
||||||
++p)
|
|
||||||
{
|
|
||||||
Mips_relobj<size, big_endian>* object =
|
|
||||||
Mips_relobj<size, big_endian>::as_mips_relobj(*p);
|
|
||||||
object->discard_mips16_stub_sections(symtab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Valtype gprmask = 0;
|
Valtype gprmask = 0;
|
||||||
Valtype cprmask1 = 0;
|
Valtype cprmask1 = 0;
|
||||||
Valtype cprmask2 = 0;
|
Valtype cprmask2 = 0;
|
||||||
@ -9660,6 +9688,13 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
Mips_relobj<size, big_endian>* relobj =
|
Mips_relobj<size, big_endian>* relobj =
|
||||||
Mips_relobj<size, big_endian>::as_mips_relobj(*p);
|
Mips_relobj<size, big_endian>::as_mips_relobj(*p);
|
||||||
|
|
||||||
|
// Check for any mips16 stub sections that we can discard.
|
||||||
|
if (!relocatable)
|
||||||
|
relobj->discard_mips16_stub_sections(symtab);
|
||||||
|
|
||||||
|
if (!relobj->merge_processor_specific_data())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Merge .reginfo contents of input objects.
|
// Merge .reginfo contents of input objects.
|
||||||
if (relobj->has_reginfo_section())
|
if (relobj->has_reginfo_section())
|
||||||
{
|
{
|
||||||
@ -9671,24 +9706,6 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
cprmask4 |= relobj->cprmask4();
|
cprmask4 |= relobj->cprmask4();
|
||||||
}
|
}
|
||||||
|
|
||||||
Input_file::Format format = relobj->input_file()->format();
|
|
||||||
if (format != Input_file::FORMAT_ELF)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// If all input sections will be discarded, don't use this object
|
|
||||||
// file for merging processor specific flags.
|
|
||||||
bool should_merge_processor_specific_flags = false;
|
|
||||||
|
|
||||||
for (unsigned int i = 1; i < relobj->shnum(); ++i)
|
|
||||||
if (relobj->output_section(i) != NULL)
|
|
||||||
{
|
|
||||||
should_merge_processor_specific_flags = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!should_merge_processor_specific_flags)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Merge processor specific flags.
|
// Merge processor specific flags.
|
||||||
Mips_abiflags<big_endian> in_abiflags;
|
Mips_abiflags<big_endian> in_abiflags;
|
||||||
|
|
||||||
@ -9723,7 +9740,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
elfcpp::SHF_ALLOC,
|
elfcpp::SHF_ALLOC,
|
||||||
abiflags_section, ORDER_INVALID, false);
|
abiflags_section, ORDER_INVALID, false);
|
||||||
|
|
||||||
if (!parameters->options().relocatable() && os != NULL)
|
if (!relocatable && os != NULL)
|
||||||
{
|
{
|
||||||
Output_segment* abiflags_segment =
|
Output_segment* abiflags_segment =
|
||||||
layout->make_output_segment(elfcpp::PT_MIPS_ABIFLAGS, elfcpp::PF_R);
|
layout->make_output_segment(elfcpp::PT_MIPS_ABIFLAGS, elfcpp::PF_R);
|
||||||
@ -9744,7 +9761,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
elfcpp::SHF_ALLOC, reginfo_section,
|
elfcpp::SHF_ALLOC, reginfo_section,
|
||||||
ORDER_INVALID, false);
|
ORDER_INVALID, false);
|
||||||
|
|
||||||
if (!parameters->options().relocatable() && os != NULL)
|
if (!relocatable && os != NULL)
|
||||||
{
|
{
|
||||||
Output_segment* reginfo_segment =
|
Output_segment* reginfo_segment =
|
||||||
layout->make_output_segment(elfcpp::PT_MIPS_REGINFO,
|
layout->make_output_segment(elfcpp::PT_MIPS_REGINFO,
|
||||||
@ -9789,7 +9806,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
false, false);
|
false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parameters->options().relocatable() && !parameters->doing_static_link())
|
if (!relocatable && !parameters->doing_static_link())
|
||||||
// In case there is no .got section, create one.
|
// In case there is no .got section, create one.
|
||||||
this->got_section(symtab, layout);
|
this->got_section(symtab, layout);
|
||||||
|
|
||||||
@ -9821,7 +9838,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
symtab));
|
symtab));
|
||||||
|
|
||||||
// Add NULL segment.
|
// Add NULL segment.
|
||||||
if (!parameters->options().relocatable())
|
if (!relocatable)
|
||||||
layout->make_output_segment(elfcpp::PT_NULL, 0);
|
layout->make_output_segment(elfcpp::PT_NULL, 0);
|
||||||
|
|
||||||
// Fill in some more dynamic tags.
|
// Fill in some more dynamic tags.
|
||||||
@ -9833,7 +9850,7 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
|
|||||||
|
|
||||||
Output_data_dynamic* const odyn = layout->dynamic_data();
|
Output_data_dynamic* const odyn = layout->dynamic_data();
|
||||||
if (odyn != NULL
|
if (odyn != NULL
|
||||||
&& !parameters->options().relocatable()
|
&& !relocatable
|
||||||
&& !parameters->doing_static_link())
|
&& !parameters->doing_static_link())
|
||||||
{
|
{
|
||||||
unsigned int d_val;
|
unsigned int d_val;
|
||||||
|
Reference in New Issue
Block a user