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:
Doug Kwan 2009-08-18 23:49:29 +00:00
parent 688805f3b8
commit f733487b04
7 changed files with 165 additions and 54 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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&);