Add support for .MIPS.options section.
gold/ * mips.cc (class Mips_output_section_options): New class. (Target_mips::do_make_output_section): New method.
This commit is contained in:
parent
c3847462f8
commit
1728969e93
@ -1,3 +1,8 @@
|
|||||||
|
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
|
* mips.cc (class Mips_output_section_options): New class.
|
||||||
|
(Target_mips::do_make_output_section): New method.
|
||||||
|
|
||||||
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
2017-03-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
|
||||||
|
|
||||||
* mips.cc (Mips_relocate_functions::rel26): Don't print relocation
|
* mips.cc (Mips_relocate_functions::rel26): Don't print relocation
|
||||||
|
78
gold/mips.cc
78
gold/mips.cc
@ -63,6 +63,9 @@ class Target_mips;
|
|||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
class Mips_output_section_reginfo;
|
class Mips_output_section_reginfo;
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
class Mips_output_section_options;
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
class Mips_output_data_la25_stub;
|
class Mips_output_data_la25_stub;
|
||||||
|
|
||||||
@ -2821,6 +2824,31 @@ class Mips_output_section_reginfo : public Output_section_data
|
|||||||
Valtype cprmask4_;
|
Valtype cprmask4_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class handles .MIPS.options output section.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
class Mips_output_section_options : public Output_section
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mips_output_section_options(const char* name, elfcpp::Elf_Word type,
|
||||||
|
elfcpp::Elf_Xword flags,
|
||||||
|
Target_mips<size, big_endian>* target)
|
||||||
|
: Output_section(name, type, flags), target_(target)
|
||||||
|
{
|
||||||
|
// After the input sections are written, we only need to update
|
||||||
|
// ri_gp_value field of ODK_REGINFO entries.
|
||||||
|
this->set_after_input_sections();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Write out option section.
|
||||||
|
void
|
||||||
|
do_write(Output_file* of);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Target_mips<size, big_endian>* target_;
|
||||||
|
};
|
||||||
|
|
||||||
// This class handles .MIPS.abiflags output section.
|
// This class handles .MIPS.abiflags output section.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
@ -3635,6 +3663,18 @@ class Target_mips : public Sized_target<size, big_endian>
|
|||||||
const elfcpp::Ehdr<size, !big_endian>&)
|
const elfcpp::Ehdr<size, !big_endian>&)
|
||||||
{ gold_unreachable(); }
|
{ gold_unreachable(); }
|
||||||
|
|
||||||
|
// Make an output section.
|
||||||
|
Output_section*
|
||||||
|
do_make_output_section(const char* name, elfcpp::Elf_Word type,
|
||||||
|
elfcpp::Elf_Xword flags)
|
||||||
|
{
|
||||||
|
if (type == elfcpp::SHT_MIPS_OPTIONS)
|
||||||
|
return new Mips_output_section_options<size, big_endian>(name, type,
|
||||||
|
flags, this);
|
||||||
|
else
|
||||||
|
return new Output_section(name, type, flags);
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust ELF file header.
|
// Adjust ELF file header.
|
||||||
void
|
void
|
||||||
do_adjust_elf_header(unsigned char* view, int len);
|
do_adjust_elf_header(unsigned char* view, int len);
|
||||||
@ -8177,6 +8217,44 @@ Mips_output_section_reginfo<size, big_endian>::do_write(Output_file* of)
|
|||||||
of->write_output_view(offset, data_size, view);
|
of->write_output_view(offset, data_size, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mips_output_section_options methods.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Mips_output_section_options<size, big_endian>::do_write(Output_file* of)
|
||||||
|
{
|
||||||
|
off_t offset = this->offset();
|
||||||
|
const section_size_type oview_size =
|
||||||
|
convert_to_section_size_type(this->data_size());
|
||||||
|
unsigned char* view = of->get_output_view(offset, oview_size);
|
||||||
|
const unsigned char* end = view + oview_size;
|
||||||
|
|
||||||
|
while (view + 8 <= end)
|
||||||
|
{
|
||||||
|
unsigned char kind = elfcpp::Swap<8, big_endian>::readval(view);
|
||||||
|
unsigned char sz = elfcpp::Swap<8, big_endian>::readval(view + 1);
|
||||||
|
if (sz < 8)
|
||||||
|
{
|
||||||
|
gold_error(_("Warning: bad `%s' option size %u smaller "
|
||||||
|
"than its header in output section"),
|
||||||
|
this->name(), sz);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update ri_gp_value (GP register value) field of ODK_REGINFO entry.
|
||||||
|
if (this->target_->is_output_n64() && kind == elfcpp::ODK_REGINFO)
|
||||||
|
elfcpp::Swap<size, big_endian>::writeval(view + 32,
|
||||||
|
this->target_->gp_value());
|
||||||
|
else if (kind == elfcpp::ODK_REGINFO)
|
||||||
|
elfcpp::Swap<size, big_endian>::writeval(view + 28,
|
||||||
|
this->target_->gp_value());
|
||||||
|
|
||||||
|
view += sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
of->write_output_view(offset, oview_size, view);
|
||||||
|
}
|
||||||
|
|
||||||
// Mips_output_section_abiflags methods.
|
// Mips_output_section_abiflags methods.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
|
Loading…
Reference in New Issue
Block a user