2009-10-30 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. * output.cc (Output_file_header::do_sized_write): Set ELF file header's processor-specific flags. * 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.
This commit is contained in:
parent
ebabffbd89
commit
d5b40221bc
@ -1,3 +1,12 @@
|
||||
2009-10-30 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2009-10-16 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* elfcpp/elfcpp.h (DT_PREINIT_ARRAY): Correct enum value.
|
||||
|
23
elfcpp/arm.h
23
elfcpp/arm.h
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -1,3 +1,48 @@
|
||||
2009-10-30 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* 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.
|
||||
* output.cc (Output_file_header::do_sized_write): Set ELF file
|
||||
header's processor-specific flags.
|
||||
* 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-30 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc: Use Arm_address instead of elfcpp::Elf_types<32>::Elf_Addr.
|
||||
|
270
gold/arm.cc
270
gold/arm.cc
@ -947,6 +947,12 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
|
||||
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<32, big_endian>
|
||||
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<32, big_endian>
|
||||
// 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<32, big_endian>
|
||||
|
||||
// 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<32, big_endian>
|
||||
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<32, big_endian>
|
||||
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_sections(
|
||||
}
|
||||
}
|
||||
|
||||
// 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, false);
|
||||
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, false);
|
||||
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(Symbol_table* symtab,
|
||||
|
||||
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,130 @@ Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
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.c_str(),
|
||||
(flags & elfcpp::EF_ARM_EABIMASK) >> 24,
|
||||
(out_flags & elfcpp::EF_ARM_EABIMASK) >> 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the input is the default architecture and had the default
|
||||
// flags then do not bother setting the flags for the output
|
||||
// architecture, instead allow future merges to do this. If no
|
||||
// future merges ever set these flags then they will retain their
|
||||
// uninitialised values, which surprise surprise, correspond
|
||||
// to the default values.
|
||||
if (flags == 0)
|
||||
return;
|
||||
|
||||
// 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>
|
||||
|
@ -95,7 +95,7 @@ class Target_i386 : public Target_freebsd<32, false>
|
||||
|
||||
// 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* symtab,
|
||||
// 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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -459,10 +459,7 @@ Output_file_header::do_sized_write(Output_file* of)
|
||||
oehdr.put_e_phoff(this->segment_header_->offset());
|
||||
|
||||
oehdr.put_e_shoff(this->section_header_->offset());
|
||||
|
||||
// FIXME: The target needs to set the flags.
|
||||
oehdr.put_e_flags(0);
|
||||
|
||||
oehdr.put_e_flags(this->target_->processor_specific_flags());
|
||||
oehdr.put_e_ehsize(elfcpp::Elf_sizes<size>::ehdr_size);
|
||||
|
||||
if (this->segment_header_ == NULL)
|
||||
|
@ -92,7 +92,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
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_relocs(
|
||||
|
||||
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();
|
||||
|
@ -94,7 +94,7 @@ class Target_sparc : public Sized_target<size, big_endian>
|
||||
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_relocs(
|
||||
|
||||
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();
|
||||
|
@ -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.
|
||||
|
@ -102,7 +102,7 @@ class Target_x86_64 : public Target_freebsd<64, false>
|
||||
|
||||
// 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* symtab,
|
||||
// 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();
|
||||
|
Loading…
Reference in New Issue
Block a user