mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
2009-08-18 Doug Kwan <dougkwan@google.com>
* dynobj.cc (Sized_dynobj::setup): Take a Target object instead of an elcpp::Ehdr as parameter. Adjust call to set_target. * dynobj.h (Sized_dynobj::setup): Take a Target object instead of an elfcpp::Ehdr as parameter. * object.cc (Object::set_target): Remove the version that looks up a target and sets it. (Sized_relobj::setup): Take a Target object instead of an elfcpp::Ehdr as parameter. Adjust call to set_target. (make_elf_sized_object): Find target and ask target to make an ELF object. * object.h: (Object::set_target): Remove the version that looks up a target and sets it. (Sized_relobj::setup): Take a Target object instead of an elfcpp:Ehdr as parameter. * target.cc: Include dynobj.h. (Target::do_make_elf_object_implementation): New. (Target::do_make_elf_object): New. * target.h (Target::make_elf_object): New template declaration. (Target::do_make_elf_object): New method declarations. (Target::do_make_elf_object_implementation): New template declaration.
This commit is contained in:
parent
688805f3b8
commit
f733487b04
@ -1,3 +1,26 @@
|
||||
2009-08-18 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* dynobj.cc (Sized_dynobj::setup): Take a Target object instead of
|
||||
an elcpp::Ehdr as parameter. Adjust call to set_target.
|
||||
* dynobj.h (Sized_dynobj::setup): Take a Target object instead of
|
||||
an elfcpp::Ehdr as parameter.
|
||||
* object.cc (Object::set_target): Remove the version that looks up
|
||||
a target and sets it.
|
||||
(Sized_relobj::setup): Take a Target object instead of
|
||||
an elfcpp::Ehdr as parameter. Adjust call to set_target.
|
||||
(make_elf_sized_object): Find target and ask target to
|
||||
make an ELF object.
|
||||
* object.h: (Object::set_target): Remove the version that looks up
|
||||
a target and sets it.
|
||||
(Sized_relobj::setup): Take a Target object instead of
|
||||
an elfcpp:Ehdr as parameter.
|
||||
* target.cc: Include dynobj.h.
|
||||
(Target::do_make_elf_object_implementation): New.
|
||||
(Target::do_make_elf_object): New.
|
||||
* target.h (Target::make_elf_object): New template declaration.
|
||||
(Target::do_make_elf_object): New method declarations.
|
||||
(Target::do_make_elf_object_implementation): New template declaration.
|
||||
|
||||
2009-08-14 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* gold.h (FUNCTION_NAME): Define.
|
||||
|
@ -83,13 +83,9 @@ Sized_dynobj<size, big_endian>::Sized_dynobj(
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_dynobj<size, big_endian>::setup(
|
||||
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
Sized_dynobj<size, big_endian>::setup(Target *target)
|
||||
{
|
||||
this->set_target(ehdr.get_e_machine(), size, big_endian,
|
||||
ehdr.get_e_ident()[elfcpp::EI_OSABI],
|
||||
ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
|
||||
|
||||
this->set_target(target);
|
||||
const unsigned int shnum = this->elf_file_.shnum();
|
||||
this->set_shnum(shnum);
|
||||
}
|
||||
|
@ -161,9 +161,9 @@ class Sized_dynobj : public Dynobj
|
||||
Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset,
|
||||
const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
|
||||
// Set up the object file based on the ELF header.
|
||||
// Set up the object file based on TARGET.
|
||||
void
|
||||
setup(const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
setup(Target *target);
|
||||
|
||||
// Read the symbols.
|
||||
void
|
||||
|
@ -132,19 +132,6 @@ Xindex::sym_xindex_to_shndx(Object* object, unsigned int symndx)
|
||||
|
||||
// Class Object.
|
||||
|
||||
// Set the target based on fields in the ELF file header.
|
||||
|
||||
void
|
||||
Object::set_target(int machine, int size, bool big_endian, int osabi,
|
||||
int abiversion)
|
||||
{
|
||||
Target* target = select_target(machine, size, big_endian, osabi, abiversion);
|
||||
if (target == NULL)
|
||||
gold_fatal(_("%s: unsupported ELF machine number %d"),
|
||||
this->name().c_str(), machine);
|
||||
this->target_ = target;
|
||||
}
|
||||
|
||||
// Report an error for this object file. This is used by the
|
||||
// elfcpp::Elf_file interface, and also called by the Object code
|
||||
// itself.
|
||||
@ -353,12 +340,9 @@ Sized_relobj<size, big_endian>::~Sized_relobj()
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Sized_relobj<size, big_endian>::setup(
|
||||
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
Sized_relobj<size, big_endian>::setup(Target *target)
|
||||
{
|
||||
this->set_target(ehdr.get_e_machine(), size, big_endian,
|
||||
ehdr.get_e_ident()[elfcpp::EI_OSABI],
|
||||
ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
|
||||
this->set_target(target);
|
||||
|
||||
const unsigned int shnum = this->elf_file_.shnum();
|
||||
this->set_shnum(shnum);
|
||||
@ -2237,27 +2221,14 @@ Object*
|
||||
make_elf_sized_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
{
|
||||
int et = ehdr.get_e_type();
|
||||
if (et == elfcpp::ET_REL)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* obj =
|
||||
new Sized_relobj<size, big_endian>(name, input_file, offset, ehdr);
|
||||
obj->setup(ehdr);
|
||||
return obj;
|
||||
}
|
||||
else if (et == elfcpp::ET_DYN)
|
||||
{
|
||||
Sized_dynobj<size, big_endian>* obj =
|
||||
new Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr);
|
||||
obj->setup(ehdr);
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold_error(_("%s: unsupported ELF file type %d"),
|
||||
name.c_str(), et);
|
||||
return NULL;
|
||||
}
|
||||
Target* target = select_target(ehdr.get_e_machine(), size, big_endian,
|
||||
ehdr.get_e_ident()[elfcpp::EI_OSABI],
|
||||
ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
|
||||
if (target == NULL)
|
||||
gold_fatal(_("%s: unsupported ELF machine number %d"),
|
||||
name.c_str(), ehdr.get_e_machine());
|
||||
return target->make_elf_object<size, big_endian>(name, input_file, offset,
|
||||
ehdr);
|
||||
}
|
||||
|
||||
} // End anonymous namespace.
|
||||
|
@ -545,11 +545,6 @@ class Object
|
||||
virtual void
|
||||
do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const = 0;
|
||||
|
||||
// Set the target.
|
||||
void
|
||||
set_target(int machine, int size, bool big_endian, int osabi,
|
||||
int abiversion);
|
||||
|
||||
// Set the number of sections.
|
||||
void
|
||||
set_shnum(int shnum)
|
||||
@ -1311,9 +1306,9 @@ class Sized_relobj : public Relobj
|
||||
is_output_section_offset_invalid(unsigned int shndx) const
|
||||
{ return this->get_output_section_offset(shndx) == invalid_address; }
|
||||
|
||||
// Set up the object file based on the ELF header.
|
||||
// Set up the object file based on TARGET.
|
||||
void
|
||||
setup(const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
setup(Target *target);
|
||||
|
||||
// Return the number of symbols. This is only valid after
|
||||
// Object::add_symbols has been called.
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "gold.h"
|
||||
#include "target.h"
|
||||
#include "dynobj.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
@ -55,4 +56,83 @@ Target::do_is_local_label_name (const char* name) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implementations of methods Target::do_make_elf_object are almost identical
|
||||
// except for the address sizes and endianities. So we extract this
|
||||
// into a template.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
inline Object*
|
||||
Target::do_make_elf_object_implementation(
|
||||
const std::string& name,
|
||||
Input_file* input_file,
|
||||
off_t offset,
|
||||
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
{
|
||||
int et = ehdr.get_e_type();
|
||||
if (et == elfcpp::ET_REL)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* obj =
|
||||
new Sized_relobj<size, big_endian>(name, input_file, offset, ehdr);
|
||||
obj->setup(this);
|
||||
return obj;
|
||||
}
|
||||
else if (et == elfcpp::ET_DYN)
|
||||
{
|
||||
Sized_dynobj<size, big_endian>* obj =
|
||||
new Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr);
|
||||
obj->setup(this);
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold_error(_("%s: unsupported ELF file type %d"),
|
||||
name.c_str(), et);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Make an ELF object called NAME by reading INPUT_FILE at OFFSET. EHDR
|
||||
// is the ELF header of the object. There are four versions of this
|
||||
// for different address sizes and endianities.
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
Object*
|
||||
Target::do_make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<32, false>& ehdr)
|
||||
{
|
||||
return this->do_make_elf_object_implementation<32, false>(name, input_file,
|
||||
offset, ehdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
Object*
|
||||
Target::do_make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<32, true>& ehdr)
|
||||
{
|
||||
return this->do_make_elf_object_implementation<32, true>(name, input_file,
|
||||
offset, ehdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
Object*
|
||||
Target::do_make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<64, false>& ehdr)
|
||||
{
|
||||
return this->do_make_elf_object_implementation<64, false>(name, input_file,
|
||||
offset, ehdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
Object*
|
||||
Target::do_make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<64, true>& ehdr)
|
||||
{
|
||||
return this->do_make_elf_object_implementation<64, true>(name, input_file,
|
||||
offset, ehdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // End namespace gold.
|
||||
|
@ -216,6 +216,13 @@ class Target
|
||||
is_local_label_name(const char* name) const
|
||||
{ return this->do_is_local_label_name(name); }
|
||||
|
||||
// Make an ELF object.
|
||||
template<int size, bool big_endian>
|
||||
Object*
|
||||
make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||
{ return this->do_make_elf_object(name, input_file, offset, ehdr); }
|
||||
|
||||
protected:
|
||||
// This struct holds the constant information for a child class. We
|
||||
// use a struct to avoid the overhead of virtual function calls for
|
||||
@ -301,7 +308,46 @@ class Target
|
||||
virtual bool
|
||||
do_is_local_label_name(const char*) const;
|
||||
|
||||
// make_elf_object hooks. There are four versions of these for
|
||||
// different address sizes and endianities.
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
// Virtual functions which may be overriden by the child class.
|
||||
virtual Object*
|
||||
do_make_elf_object(const std::string&, Input_file*, off_t,
|
||||
const elfcpp::Ehdr<32, false>&);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_32_BIG
|
||||
// Virtual functions which may be overriden by the child class.
|
||||
virtual Object*
|
||||
do_make_elf_object(const std::string&, Input_file*, off_t,
|
||||
const elfcpp::Ehdr<32, true>&);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_LITTLE
|
||||
// Virtual functions which may be overriden by the child class.
|
||||
virtual Object*
|
||||
do_make_elf_object(const std::string&, Input_file*, off_t,
|
||||
const elfcpp::Ehdr<64, false>& ehdr);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TARGET_64_BIG
|
||||
// Virtual functions which may be overriden by the child class.
|
||||
virtual Object*
|
||||
do_make_elf_object(const std::string& name, Input_file* input_file,
|
||||
off_t offset, const elfcpp::Ehdr<64, true>& ehdr);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// The implementations of the four do_make_elf_object virtual functions are
|
||||
// almost identical except for their sizes and endianity. We use a template.
|
||||
// for their implementations.
|
||||
template<int size, bool big_endian>
|
||||
inline Object*
|
||||
do_make_elf_object_implementation(const std::string&, Input_file*, off_t,
|
||||
const elfcpp::Ehdr<size, big_endian>&);
|
||||
|
||||
Target(const Target&);
|
||||
Target& operator=(const Target&);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user