This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] gold: Maintain sparc ELF header bits properly


[cc'ing iant explicitly, in case this thread didn't make it through
his filters.]

-cary


On Mon, Apr 23, 2012 at 2:21 PM, David Miller <davem@davemloft.net> wrote:
> From: David Miller <davem@davemloft.net>
> Date: Fri, 20 Apr 2012 18:44:48 -0400 (EDT)
>
>> From: Cary Coutant <ccoutant@google.com>
>> Date: Fri, 20 Apr 2012 15:32:48 -0700
>>
>>>> It really would have been nice if I could just call down into the
>>>> default implementations after I did the sparc specific bits, but
>>>> it's not possible to just simply say:
>>>>
>>>> ?this->do_make_elf_object_implementation(...)
>>>
>>> Sure it is:
>>>
>>> ? ? Target::do_make_elf_object(name, input_file, offset, ehdr);
>>
>> Indeed, that does the trick, thanks!
>
> Ping?
>
>> gold/
>>
>> ? ? ? * sparc.cc (class Target_sparc): Add elf_machine_, elf_flags_,
>> ? ? ? and elf_flags_set_.
>> ? ? ? (Target_sparc::Target_sparc): Initialize new fields.
>> ? ? ? (Target_sparc::do_make_elf_object): New function.
>> ? ? ? (Target_sparc::do_adjust_elf_header): New function.
>> ---
>> ?gold/sparc.cc | ?112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> ?1 file changed, 111 insertions(+), 1 deletion(-)
>>
>> diff --git a/gold/sparc.cc b/gold/sparc.cc
>> index 762da42..004a265 100644
>> --- a/gold/sparc.cc
>> +++ b/gold/sparc.cc
>> @@ -60,7 +60,9 @@ class Target_sparc : public Sized_target<size, big_endian>
>> ? ? ?: Sized_target<size, big_endian>(&sparc_info),
>> ? ? ? ?got_(NULL), plt_(NULL), rela_dyn_(NULL), rela_ifunc_(NULL),
>> ? ? ? ?copy_relocs_(elfcpp::R_SPARC_COPY), dynbss_(NULL),
>> - ? ? ?got_mod_index_offset_(-1U), tls_get_addr_sym_(NULL)
>> + ? ? ?got_mod_index_offset_(-1U), tls_get_addr_sym_(NULL),
>> + ? ? ?elf_machine_(sparc_info.machine_code), elf_flags_(0),
>> + ? ? ?elf_flags_set_(false)
>> ? ?{
>> ? ?}
>>
>> @@ -206,6 +208,15 @@ class Target_sparc : public Sized_target<size, big_endian>
>> ? ?unsigned int
>> ? ?plt_entry_size() const;
>>
>> + protected:
>> + ?// Make an ELF object.
>> + ?Object*
>> + ?do_make_elf_object(const std::string&, Input_file*, off_t,
>> + ? ? ? ? ? ? ? ? ?const elfcpp::Ehdr<size, big_endian>& ehdr);
>> +
>> + ?void
>> + ?do_adjust_elf_header(unsigned char* view, int len) const;
>> +
>> ? private:
>>
>> ? ?// The class which scans relocations.
>> @@ -432,6 +443,12 @@ class Target_sparc : public Sized_target<size, big_endian>
>> ? ?unsigned int got_mod_index_offset_;
>> ? ?// Cached pointer to __tls_get_addr symbol
>> ? ?Symbol* tls_get_addr_sym_;
>> + ?// Accumulated elf machine type
>> + ?elfcpp::Elf_Half elf_machine_;
>> + ?// Accumulated elf header flags
>> + ?elfcpp::Elf_Word elf_flags_;
>> + ?// Whether elf_flags_ has been set for the first time yet
>> + ?bool elf_flags_set_;
>> ?};
>>
>> ?template<>
>> @@ -4071,6 +4088,99 @@ Target_sparc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
>> ? ?return this->plt_section()->address() + gsym->plt_offset();
>> ?}
>>
>> +// do_make_elf_object to override the same function in the base class.
>> +// We need to use a target-specific sub-class of
>> +// Sized_relobj_file<size, big_endian> to process SPARC specific bits
>> +// of the ELF headers. ?Hence we need to have our own ELF object creation.
>> +
>> +template<int size, bool big_endian>
>> +Object*
>> +Target_sparc<size, big_endian>::do_make_elf_object(
>> + ? ?const std::string& name,
>> + ? ?Input_file* input_file,
>> + ? ?off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
>> +{
>> + ?elfcpp::Elf_Word omm, mm, flags = ehdr.get_e_flags();
>> + ?elfcpp::Elf_Half machine = ehdr.get_e_machine();
>> +
>> + ?switch (machine)
>> + ? ?{
>> + ? ?case elfcpp::EM_SPARC32PLUS:
>> + ? ? ?this->elf_machine_ = elfcpp::EM_SPARC32PLUS;
>> + ? ? ?break;
>> +
>> + ? ?case elfcpp::EM_SPARC:
>> + ? ?case elfcpp::EM_SPARCV9:
>> + ? ? ?break;
>> +
>> + ? ?default:
>> + ? ? ?break;
>> + ? ?}
>> +
>> + ?if (!this->elf_flags_set_)
>> + ? ?{
>> + ? ? ?this->elf_flags_ = flags;
>> + ? ? ?this->elf_flags_set_ = true;
>> + ? ?}
>> + ?else
>> + ? ?{
>> + ? ? ?// Accumulate cpu feature bits.
>> + ? ? ?this->elf_flags_ |= (flags & (elfcpp::EF_SPARC_32PLUS
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | elfcpp::EF_SPARC_SUN_US1
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | elfcpp::EF_SPARC_HAL_R1
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | elfcpp::EF_SPARC_SUN_US3));
>> +
>> + ? ? ?// Bump the memory model setting to the most restrictive
>> + ? ? ?// one we encounter.
>> + ? ? ?omm = (this->elf_flags_ & elfcpp::EF_SPARCV9_MM);
>> + ? ? ?mm = (flags & elfcpp::EF_SPARCV9_MM);
>> + ? ? ?if (omm != mm)
>> + ? ? {
>> + ? ? ? if (mm == elfcpp::EF_SPARCV9_TSO)
>> + ? ? ? ? {
>> + ? ? ? ? ? this->elf_flags_ &= ~elfcpp::EF_SPARCV9_MM;
>> + ? ? ? ? ? this->elf_flags_ |= elfcpp::EF_SPARCV9_TSO;
>> + ? ? ? ? }
>> + ? ? ? else if (mm == elfcpp::EF_SPARCV9_PSO
>> + ? ? ? ? ? ? ? ?&& omm == elfcpp::EF_SPARCV9_RMO)
>> + ? ? ? ? {
>> + ? ? ? ? ? this->elf_flags_ &= ~elfcpp::EF_SPARCV9_MM;
>> + ? ? ? ? ? this->elf_flags_ |= elfcpp::EF_SPARCV9_PSO;
>> + ? ? ? ? }
>> + ? ? }
>> + ? ?}
>> +
>> + ?// Validate that the little-endian flag matches how we've
>> + ?// been instantiated.
>> + ?if (!(flags & elfcpp::EF_SPARC_LEDATA) != big_endian)
>> + ? ?{
>> + ? ? ?if (big_endian)
>> + ? ? gold_error(_("%s: Little endian elf flag set on BE object"),
>> + ? ? ? ? ? ? ? ? ?name.c_str());
>> + ? ? ?else
>> + ? ? gold_error(_("%s: Little endian elf flag clear on LE object"),
>> + ? ? ? ? ? ? ? ? ?name.c_str());
>> + ? ?}
>> +
>> + ?return Target::do_make_elf_object(name, input_file, offset, ehdr);
>> +}
>> +
>> +// Adjust ELF file header.
>> +
>> +template<int size, bool big_endian>
>> +void
>> +Target_sparc<size, big_endian>::do_adjust_elf_header(
>> + ? ?unsigned char* view,
>> + ? ?int len) const
>> +{
>> + ?elfcpp::Ehdr_write<size, big_endian> oehdr(view);
>> +
>> + ?oehdr.put_e_machine(this->elf_machine_);
>> + ?oehdr.put_e_flags(this->elf_flags_);
>> +
>> + ?Sized_target<size, big_endian>::do_adjust_elf_header(view, len);
>> +}
>> +
>> ?// The selector for sparc object files.
>>
>> ?template<int size, bool big_endian>
>> --
>> 1.7.9.5
>>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]