[GOLD][PATCH] Set ARM ABI information in ELF file header.
Doug Kwan (關振德)
dougkwan@google.com
Fri Oct 30 05:19:00 GMT 2009
Hi,
This is the third version. I believe it is MT-safe. The
processor-specific flags are not read during do_read_symbols and are
merged in Target_arm::do_finalize_sections.
-Doug
2009-10-29 Doug Kwan <dougkwan@google.com>
elfcpp/ChangeLog:
* arm.h (EF_ARM_BE8, EF_ARM_EABIMASK, EF_ARM_EABI_UNKNOWN,
EF_ARM_EABI_VER1, EF_ARM_EABI_VER2, EF_ARM_EABI_VER3,
EF_ARM_EABI_VER4, EF_ARM_EABI_VER5): New enums for processor-specific
flags.
(arm_eabi_version): New inline function.
* elfcpp.h: Add a comment about DT_ENCODING.
gold/ChangeLog:
* arm.cc (Arm_relobj::processor_specific_flags): New method
definition.
(Arm_relobj::do_read_symbols): New method declaration.
(Arm_relobj::processor_specific_flags_): New data member declaration.
(Arm_dynobj): New class definition.
(Target_arm::do_finalize_sections): Add input_objects parameter.
(Target_arm::do_adjust_elf_header): New method declaration.
(Target_arm::are_eabi_versions_compatible,
(Target_arm::merge_processor_specific_flags): New method declaration.
(Target_arm::do_make_elf_object): New overloaded method definitions
and declaration.
(Arm_relobj::do_read_symbols): New method definition.
(Arm_dynobj::do_read_symbols): Ditto.
(Target_arm::do_finalize_sections): Add input_objects parameters.
Merge processor-specific flags from all input objects.
(Target_arm::are_eabi_versions_compatible,
Target_arm::merge_processor_specific_flags,
Target_arm::do_adjust_elf_header, Target_arm::do_make_elf_object):
New method definitions.
* i386.cc (Target_i386::do_finalize_sections): Add unnamed
Input_objects pointer type parameter.
* layout.cc (Layout::finalize): Pass input objects to target's.
finalize_sections function.
* powerpc.cc (Target_powerpc::do_finalize_sections): Add unnamed
Input_objects pointer type parameter.
* sparc.cc (Target_sparc::do_finalize_sections): Same.
* target.h (Input_objects): New forward class declaration.
(Target::processor_specific_flags,
Target::are_processor_specific_flags_sect): New method definitions.
(Target::finalize_sections): Add input_objects parameter.
(Target::Target): Initialize processor_specific_flags_ and
are_processor_specific_flags_set_.
(Target::do_finalize_sections): Add unnamed Input_objects pointer type
parameter.
(Target::set_processor_specific_flags): New method definition.
(Target::processor_specific_flags_,
Target::are_processor_specific_flags_set_): New data member
declarations.
* x86_64.cc (Target_x86_64::do_finalize_sections): Add unnamed
Input_objects pointer type parameter.
2009/10/28 Doug Kwan (關振德) <dougkwan@google.com>:
> This is not MT-safe. Afrer a discussion with Ian, I know how to fix
> this. Will submit a new patch.
>
> -Doug
>
> 2009/10/27 Doug Kwan (關振德) <dougkwan@google.com>:
>> Hi Ian,
>>
>> This is and updated patch. I removed all code related to obsolete
>> processor-specific flags. I checked the ARM ELF specs and it said
>> only EF_ARM_BE8 and the EABI version flag are supported. Bit used by
>> previously defined flags are now reserved.
>>
>> -Doug
>>
>> elfcpp/ChangeLog:
>>
>> * arm.h (EF_ARM_BE8, EF_ARM_EABI_UNKNOWN, EF_ARM_EABI_VER1,
>> EF_ARM_EABI_VER2, EF_ARM_EABI_VER3, EF_ARM_EABI_VER4,
>> EF_ARM_EABI_VER5): New enums for processor-specific flags in ELF
>> file header.
>> (arm_eabi_version): New inline function.
>>
>> gold/ChangeLog:
>> * arm.cc (Target_arm::do_adjust_elf_header): New method declaration.
>> (Target_arm::are_eabi_versions_compatible): Same.
>> (Target_arm::do_make_elf_object): New overloaded method declaration
>> and definitions.
>> (Target_arm::are_eabi_versions_compatible,
>> Target_arm::merge_processor_specific_flags,
>> Target_arm::do_adjust_elf_header, Target_arm::do_make_elf_object):
>> New method definitions.
>> * output.cc (Output_file_header::do_sized_write): Set e_flags using
>> values from target.
>> * target.h (Target::processor_specific_flags,
>> Target::are_processor_specific_flags_set): New method definitions.
>> (Target::Target): Initialize processor_specific_flags_ and
>> are_processor_specific_flags_set_.
>> (set_processor_specific_flags): New method definition.
>> (processor_specific_flags_, are_processor_specific_flags_set_):
>> New data member declarations.
>>
>>
>> 2009/10/27 Doug Kwan (關振德) <dougkwan@google.com>:
>>> Yes, that's what I told you about having partially working code in the
>>> another thread.
>>>
>>> -Doug
>>>
>>> 2009/10/27 Viktor Kutuzov <vkutuzov@accesssoftek.com>:
>>>> Good work, Doug!
>>>> Are you going to parse input objects ".ARM.attributes" section as well?
>>>>
>>>> -Viktor
>>>>
>>>> ----- Original Message ----- From: "Doug Kwan (關振德)" <dougkwan@google.com>
>>>> To: "Joseph S. Myers" <joseph@codesourcery.com>
>>>> Cc: "Ian Lance Taylor" <iant@google.com>; "binutils"
>>>> <binutils@sourceware.org>; "Viktor Kutuzov" <vkutuzov@accesssoftek.com>
>>>> Sent: Tuesday, October 27, 2009 9:12 AM
>>>> Subject: Re: [GOLD][PATCH] Set ARM ABI information in ELF file header.
>>>>
>>>>
>>>>> Wow. This makes gold bug-compatible with ld :). I can remove that.
>>>>> Thanks for catching it.
>>>>>
>>>>> -Doug
>>>>>
>>>>> 2009/10/27 Joseph S. Myers <joseph@codesourcery.com>:
>>>>>>
>>>>>> On Mon, 26 Oct 2009, Doug Kwan (關振德) wrote:
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> This patch adds code to set proper flags in the processor-specific
>>>>>>> flags in the ELF file header. Previously we always set e_flags to 0
>>>>>>> on all target. This patch add methods processor_specific_flags and
>>>>>>> set_processor_specific_flags in Target so that Output_file_header can
>>>>>>> get the flags. For targets that merge processor-specific flags from
>>>>>>> input objects, we also track whether the flags have been set at least
>>>>>>> once. Currently only the ARM target sets the flags correctly.
>>>>>>
>>>>>> It looks like this patch is replicating the GNU ld bug whereby
>>>>>> EF_ARM_HASENTRY is set on EABI objects. There is no such flag in AAELF
>>>>>> and so it is a bug to set it on such objects.
>>>>>>
>>>>>> --
>>>>>> Joseph S. Myers
>>>>>> joseph@codesourcery.com
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
Index: elfcpp/arm.h
===================================================================
RCS file: /cvs/src/src/elfcpp/arm.h,v
retrieving revision 1.1
diff -u -p -r1.1 arm.h
--- elfcpp/arm.h 27 May 2009 18:27:42 -0000 1.1
+++ elfcpp/arm.h 29 Oct 2009 22:48:28 -0000
@@ -199,6 +199,29 @@ enum
// 160 - 255 Unallocated
};
+// e_flags values used for ARM. We only support flags defined in AAELF.
+
+enum
+{
+ EF_ARM_BE8 = 0x00800000,
+
+ // Mask to extract EABI version, not really a flag value.
+ EF_ARM_EABIMASK = 0xFF000000,
+
+ EF_ARM_EABI_UNKNOWN = 0x00000000,
+ EF_ARM_EABI_VER1 = 0x01000000,
+ EF_ARM_EABI_VER2 = 0x02000000,
+ EF_ARM_EABI_VER3 = 0x03000000,
+ EF_ARM_EABI_VER4 = 0x04000000,
+ EF_ARM_EABI_VER5 = 0x05000000,
+};
+
+// Extract EABI version from flags.
+
+inline Elf_Word
+arm_eabi_version(Elf_Word flags)
+{ return flags & EF_ARM_EABIMASK; }
+
} // End namespace elfcpp.
#endif // !defined(ELFCPP_ARM_H)
Index: elfcpp/elfcpp.h
===================================================================
RCS file: /cvs/src/src/elfcpp/elfcpp.h,v
retrieving revision 1.26
diff -u -p -r1.26 elfcpp.h
--- elfcpp/elfcpp.h 16 Oct 2009 23:07:23 -0000 1.26
+++ elfcpp/elfcpp.h 29 Oct 2009 22:48:28 -0000
@@ -656,7 +656,11 @@ enum DT
DT_FINI_ARRAYSZ = 28,
DT_RUNPATH = 29,
DT_FLAGS = 30,
+
+ // This is used to mark a range of dynamic tags. It is not really
+ // a tag value.
DT_ENCODING = 32,
+
DT_PREINIT_ARRAY = 32,
DT_PREINIT_ARRAYSZ = 33,
DT_LOOS = 0x6000000d,
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.22
diff -u -p -r1.22 arm.cc
--- gold/arm.cc 29 Oct 2009 05:16:22 -0000 1.22
+++ gold/arm.cc 29 Oct 2009 22:48:31 -0000
@@ -947,6 +947,12 @@ class Arm_relobj : public Sized_relobj<3
as_arm_relobj(Relobj* relobj)
{ return static_cast<Arm_relobj<big_endian>*>(relobj); }
+ // Processor-specific flags in ELF file header. This is valid only after
+ // reading symbols.
+ elfcpp::Elf_Word
+ processor_specific_flags() const
+ { return this->processor_specific_flags_; }
+
protected:
// Post constructor setup.
void
@@ -971,6 +977,10 @@ class Arm_relobj : public Sized_relobj<3
const unsigned char* pshdrs,
typename Sized_relobj<32, big_endian>::Views* pivews);
+ // Read the symbol information.
+ void
+ do_read_symbols(Read_symbols_data* sd);
+
private:
// List of stub tables.
typedef std::vector<Stub_table<big_endian>*> Stub_table_list;
@@ -978,6 +988,45 @@ class Arm_relobj : public Sized_relobj<3
// Bit vector to tell if a local symbol is a thumb function or not.
// This is only valid after do_count_local_symbol is called.
std::vector<bool> local_symbol_is_thumb_function_;
+ // processor-specific flags in ELF file header.
+ elfcpp::Elf_Word processor_specific_flags_;
+};
+
+// Arm_dynobj class.
+
+template<bool big_endian>
+class Arm_dynobj : public Sized_dynobj<32, big_endian>
+{
+ public:
+ Arm_dynobj(const std::string& name, Input_file* input_file, off_t offset,
+ const elfcpp::Ehdr<32, big_endian>& ehdr)
+ : Sized_dynobj<32, big_endian>(name, input_file, offset, ehdr),
+ processor_specific_flags_(0)
+ { }
+
+ ~Arm_dynobj()
+ { }
+
+ // Downcast a base pointer to an Arm_relobj pointer. This is
+ // not type-safe but we only use Arm_relobj not the base class.
+ static Arm_dynobj<big_endian>*
+ as_arm_dynobj(Dynobj* dynobj)
+ { return static_cast<Arm_dynobj<big_endian>*>(dynobj); }
+
+ // Processor-specific flags in ELF file header. This is valid only after
+ // reading symbols.
+ elfcpp::Elf_Word
+ processor_specific_flags() const
+ { return this->processor_specific_flags_; }
+
+ protected:
+ // Read the symbol information.
+ void
+ do_read_symbols(Read_symbols_data* sd);
+
+ private:
+ // processor-specific flags in ELF file header.
+ elfcpp::Elf_Word processor_specific_flags_;
};
// Utilities for manipulating integers of up to 32-bits
@@ -1120,7 +1169,7 @@ class Target_arm : public Sized_target<3
// Finalize the sections.
void
- do_finalize_sections(Layout*);
+ do_finalize_sections(Layout*, const Input_objects*);
// Return the value to use for a dynamic symbol which requires special
// treatment.
@@ -1196,6 +1245,10 @@ class Target_arm : public Sized_target<3
return static_cast<const Target_arm<big_endian>&>(parameters->target());
}
+ protected:
+ void
+ do_adjust_elf_header(unsigned char* view, int len) const;
+
private:
// The class which scans relocations.
class Scan
@@ -1366,6 +1419,34 @@ class Target_arm : public Sized_target<3
this->rel_dyn_section(layout));
}
+ // Whether two EABI versions are compatible.
+ static bool
+ are_eabi_versions_compatible(elfcpp::Elf_Word v1, elfcpp::Elf_Word v2);
+
+ // Merge processor-specific flags from input object and those in the ELF
+ // header of the output.
+ void
+ merge_processor_specific_flags(const std::string&, elfcpp::Elf_Word);
+
+ Object*
+ do_make_elf_object(const std::string&, Input_file*, off_t,
+ const elfcpp::Ehdr<32, big_endian>& ehdr);
+
+ Object*
+ do_make_elf_object(const std::string&, Input_file*, off_t,
+ const elfcpp::Ehdr<32, !big_endian>&)
+ { gold_unreachable(); }
+
+ Object*
+ do_make_elf_object(const std::string&, Input_file*, off_t,
+ const elfcpp::Ehdr<64, false>&)
+ { gold_unreachable(); }
+
+ Object*
+ do_make_elf_object(const std::string&, Input_file*, off_t,
+ const elfcpp::Ehdr<64, true>&)
+ { gold_unreachable(); }
+
// Information about this specific target which we pass to the
// general Target structure.
static const Target::Target_info arm_info;
@@ -3250,6 +3331,42 @@ Arm_relobj<big_endian>::do_relocate_sect
}
}
+// Read the symbol information.
+
+template<bool big_endian>
+void
+Arm_relobj<big_endian>::do_read_symbols(Read_symbols_data* sd)
+{
+ // Call parent class to read symbol information.
+ Sized_relobj<32, big_endian>::do_read_symbols(sd);
+
+ // Read processor-specific flags in ELF file header.
+ const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
+ elfcpp::Elf_sizes<32>::ehdr_size,
+ true, true);
+ elfcpp::Ehdr<32, big_endian> ehdr(pehdr);
+ this->processor_specific_flags_ = ehdr.get_e_flags();
+}
+
+// Arm_dynobj methods.
+
+// Read the symbol information.
+
+template<bool big_endian>
+void
+Arm_dynobj<big_endian>::do_read_symbols(Read_symbols_data* sd)
+{
+ // Call parent class to read symbol information.
+ Sized_dynobj<32, big_endian>::do_read_symbols(sd);
+
+ // Read processor-specific flags in ELF file header.
+ const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
+ elfcpp::Elf_sizes<32>::ehdr_size,
+ true, true);
+ elfcpp::Ehdr<32, big_endian> ehdr(pehdr);
+ this->processor_specific_flags_ = ehdr.get_e_flags();
+}
+
// A class to handle the PLT data.
template<bool big_endian>
@@ -3950,8 +4067,33 @@ Target_arm<big_endian>::scan_relocs(Symb
template<bool big_endian>
void
-Target_arm<big_endian>::do_finalize_sections(Layout* layout)
+Target_arm<big_endian>::do_finalize_sections(
+ Layout* layout,
+ const Input_objects* input_objects)
{
+ // Merge processor-specific flags.
+ for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
+ p != input_objects->relobj_end();
+ ++p)
+ {
+ Arm_relobj<big_endian>* arm_relobj =
+ Arm_relobj<big_endian>::as_arm_relobj(*p);
+ this->merge_processor_specific_flags(
+ arm_relobj->name(),
+ arm_relobj->processor_specific_flags());
+ }
+
+ for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
+ p != input_objects->dynobj_end();
+ ++p)
+ {
+ Arm_dynobj<big_endian>* arm_dynobj =
+ Arm_dynobj<big_endian>::as_arm_dynobj(*p);
+ this->merge_processor_specific_flags(
+ arm_dynobj->name(),
+ arm_dynobj->processor_specific_flags());
+ }
+
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
if (odyn != NULL)
@@ -4588,6 +4730,122 @@ Target_arm<big_endian>::get_real_reloc_t
}
}
+// Whether if two EABI versions V1 and V2 are compatible.
+
+template<bool big_endian>
+bool
+Target_arm<big_endian>::are_eabi_versions_compatible(
+ elfcpp::Elf_Word v1,
+ elfcpp::Elf_Word v2)
+{
+ // v4 and v5 are the same spec before and after it was released,
+ // so allow mixing them.
+ if ((v1 == elfcpp::EF_ARM_EABI_VER4 && v2 == elfcpp::EF_ARM_EABI_VER5)
+ || (v1 == elfcpp::EF_ARM_EABI_VER5 && v2 == elfcpp::EF_ARM_EABI_VER4))
+ return true;
+
+ return v1 == v2;
+}
+
+// Combine FLAGS from an input object called NAME and the processor-specific
+// flags in the ELF header of the output. Much of this is adapted from the
+// processor-specific flags merging code in elf32_arm_merge_private_bfd_data
+// in bfd/elf32-arm.c.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::merge_processor_specific_flags(
+ const std::string& name,
+ elfcpp::Elf_Word flags)
+{
+ if (this->are_processor_specific_flags_set())
+ {
+ elfcpp::Elf_Word out_flags = this->processor_specific_flags();
+
+ // Nothing to merge if flags equal to those in output.
+ if (flags == out_flags)
+ return;
+
+ // Complain about various flag mismatches.
+ const char* name_as_c_string = name.c_str();
+ elfcpp::Elf_Word version1 = elfcpp::arm_eabi_version(flags);
+ elfcpp::Elf_Word version2 = elfcpp::arm_eabi_version(out_flags);
+ if (!this->are_eabi_versions_compatible(version1, version2))
+ gold_error(_("Source object %s has EABI version %d but output has "
+ "EABI version %d."),
+ name_as_c_string,
+ (flags & elfcpp::EF_ARM_EABIMASK) >> 24,
+ (out_flags & elfcpp::EF_ARM_EABIMASK) >> 24);
+ }
+ else
+ {
+ // This is the first time, just copy the flags.
+ // We only copy the EABI version for now.
+ this->set_processor_specific_flags(flags & elfcpp::EF_ARM_EABIMASK);
+ }
+}
+
+// Adjust ELF file header.
+template<bool big_endian>
+void
+Target_arm<big_endian>::do_adjust_elf_header(
+ unsigned char* view,
+ int len) const
+{
+ gold_assert(len == elfcpp::Elf_sizes<32>::ehdr_size);
+
+ elfcpp::Ehdr<32, big_endian> ehdr(view);
+ unsigned char e_ident[elfcpp::EI_NIDENT];
+ memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT);
+
+ if (elfcpp::arm_eabi_version(this->processor_specific_flags())
+ == elfcpp::EF_ARM_EABI_UNKNOWN)
+ e_ident[elfcpp::EI_OSABI] = elfcpp::ELFOSABI_ARM;
+ else
+ e_ident[elfcpp::EI_OSABI] = 0;
+ e_ident[elfcpp::EI_ABIVERSION] = 0;
+
+ // FIXME: Do EF_ARM_BE8 adjustment.
+
+ elfcpp::Ehdr_write<32, big_endian> oehdr(view);
+ oehdr.put_e_ident(e_ident);
+}
+
+// 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<32, big_endian>
+// to store ARM specific information. Hence we need to have our own
+// ELF object creation.
+
+template<bool big_endian>
+Object*
+Target_arm<big_endian>::do_make_elf_object(
+ const std::string& name,
+ Input_file* input_file,
+ off_t offset, const elfcpp::Ehdr<32, big_endian>& ehdr)
+{
+ int et = ehdr.get_e_type();
+ if (et == elfcpp::ET_REL)
+ {
+ Arm_relobj<big_endian>* obj =
+ new Arm_relobj<big_endian>(name, input_file, offset, ehdr);
+ obj->setup();
+ return obj;
+ }
+ else if (et == elfcpp::ET_DYN)
+ {
+ Sized_dynobj<32, big_endian>* obj =
+ new Arm_dynobj<big_endian>(name, input_file, offset, ehdr);
+ obj->setup();
+ return obj;
+ }
+ else
+ {
+ gold_error(_("%s: unsupported ELF file type %d"),
+ name.c_str(), et);
+ return NULL;
+ }
+}
+
// The selector for arm object files.
template<bool big_endian>
Index: gold/i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.96
diff -u -p -r1.96 i386.cc
--- gold/i386.cc 29 Oct 2009 05:16:23 -0000 1.96
+++ gold/i386.cc 29 Oct 2009 22:48:32 -0000
@@ -95,7 +95,7 @@ class Target_i386 : public Target_freebs
// Finalize the sections.
void
- do_finalize_sections(Layout*);
+ do_finalize_sections(Layout*, const Input_objects*);
// Return the value to use for a dynamic which requires special
// treatment.
@@ -1552,7 +1552,7 @@ Target_i386::scan_relocs(Symbol_table* s
// Finalize the sections.
void
-Target_i386::do_finalize_sections(Layout* layout)
+Target_i386::do_finalize_sections(Layout* layout, const Input_objects*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
Index: gold/layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.142
diff -u -p -r1.142 layout.cc
--- gold/layout.cc 16 Oct 2009 05:16:09 -0000 1.142
+++ gold/layout.cc 29 Oct 2009 22:48:32 -0000
@@ -1509,7 +1509,7 @@ off_t
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
Target* target, const Task* task)
{
- target->finalize_sections(this);
+ target->finalize_sections(this, input_objects);
this->count_local_symbols(task, input_objects);
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.17
diff -u -p -r1.17 powerpc.cc
--- gold/powerpc.cc 29 Oct 2009 05:16:23 -0000 1.17
+++ gold/powerpc.cc 29 Oct 2009 22:48:32 -0000
@@ -92,7 +92,7 @@ class Target_powerpc : public Sized_targ
const unsigned char* plocal_symbols);
// Finalize the sections.
void
- do_finalize_sections(Layout*);
+ do_finalize_sections(Layout*, const Input_objects*);
// Return the value to use for a dynamic which requires special
// treatment.
@@ -1530,7 +1530,9 @@ Target_powerpc<size, big_endian>::scan_r
template<int size, bool big_endian>
void
-Target_powerpc<size, big_endian>::do_finalize_sections(Layout* layout)
+Target_powerpc<size, big_endian>::do_finalize_sections(
+ Layout* layout,
+ const Input_objects*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
Index: gold/sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.21
diff -u -p -r1.21 sparc.cc
--- gold/sparc.cc 29 Oct 2009 05:16:23 -0000 1.21
+++ gold/sparc.cc 29 Oct 2009 22:48:32 -0000
@@ -94,7 +94,7 @@ class Target_sparc : public Sized_target
const unsigned char* plocal_symbols);
// Finalize the sections.
void
- do_finalize_sections(Layout*);
+ do_finalize_sections(Layout*, const Input_objects*);
// Return the value to use for a dynamic which requires special
// treatment.
@@ -2317,7 +2317,9 @@ Target_sparc<size, big_endian>::scan_rel
template<int size, bool big_endian>
void
-Target_sparc<size, big_endian>::do_finalize_sections(Layout* layout)
+Target_sparc<size, big_endian>::do_finalize_sections(
+ Layout* layout,
+ const Input_objects*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
Index: gold/target.h
===================================================================
RCS file: /cvs/src/src/gold/target.h,v
retrieving revision 1.39
diff -u -p -r1.39 target.h
--- gold/target.h 29 Oct 2009 05:16:23 -0000 1.39
+++ gold/target.h 29 Oct 2009 22:48:32 -0000
@@ -54,6 +54,7 @@ template<int size>
class Sized_symbol;
class Symbol_table;
class Output_section;
+class Input_objects;
// The abstract class for target specific handling.
@@ -79,6 +80,16 @@ class Target
machine_code() const
{ return this->pti_->machine_code; }
+ // Processor specific flags to store in e_flags field of ELF header.
+ elfcpp::Elf_Word
+ processor_specific_flags() const
+ { return this->processor_specific_flags_; }
+
+ // Whether processor specific flags are set at least once.
+ bool
+ are_processor_specific_flags_set() const
+ { return this->are_processor_specific_flags_set_; }
+
// Whether this target has a specific make_symbol function.
bool
has_make_symbol() const
@@ -183,8 +194,8 @@ class Target
// This is called to tell the target to complete any sections it is
// handling. After this all sections must have their final size.
void
- finalize_sections(Layout* layout)
- { return this->do_finalize_sections(layout); }
+ finalize_sections(Layout* layout, const Input_objects* input_objects)
+ { return this->do_finalize_sections(layout, input_objects); }
// Return the value to use for a global symbol which needs a special
// value in the dynamic symbol table. This will only be called if
@@ -314,7 +325,8 @@ class Target
};
Target(const Target_info* pti)
- : pti_(pti)
+ : pti_(pti), processor_specific_flags_(0),
+ are_processor_specific_flags_set_(false)
{ }
// Virtual function which may be implemented by the child class.
@@ -324,7 +336,7 @@ class Target
// Virtual function which may be implemented by the child class.
virtual void
- do_finalize_sections(Layout*)
+ do_finalize_sections(Layout*, const Input_objects*)
{ }
// Virtual function which may be implemented by the child class.
@@ -364,6 +376,14 @@ class Target
// make_elf_object hooks. There are four versions of these for
// different address sizes and endianities.
+ // Set processor specific flags.
+ void
+ set_processor_specific_flags(elfcpp::Elf_Word flags)
+ {
+ this->processor_specific_flags_ = flags;
+ this->are_processor_specific_flags_set_ = true;
+ }
+
#ifdef HAVE_TARGET_32_LITTLE
// Virtual functions which may be overriden by the child class.
virtual Object*
@@ -433,6 +453,10 @@ class Target
// The target information.
const Target_info* pti_;
+ // Processor-specific flags.
+ elfcpp::Elf_Word processor_specific_flags_;
+ // Whether the processor-specific flags are set at least once.
+ bool are_processor_specific_flags_set_;
};
// The abstract class for a specific size and endianness of target.
Index: gold/x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.89
diff -u -p -r1.89 x86_64.cc
--- gold/x86_64.cc 29 Oct 2009 05:16:23 -0000 1.89
+++ gold/x86_64.cc 29 Oct 2009 22:48:32 -0000
@@ -102,7 +102,7 @@ class Target_x86_64 : public Target_free
// Finalize the sections.
void
- do_finalize_sections(Layout*);
+ do_finalize_sections(Layout*, const Input_objects*);
// Return the value to use for a dynamic which requires special
// treatment.
@@ -1642,7 +1642,7 @@ Target_x86_64::scan_relocs(Symbol_table*
// Finalize the sections.
void
-Target_x86_64::do_finalize_sections(Layout* layout)
+Target_x86_64::do_finalize_sections(Layout* layout, const Input_objects*)
{
// Fill in some more dynamic tags.
Output_data_dynamic* const odyn = layout->dynamic_data();
More information about the Binutils
mailing list