Index: gold/object.cc =================================================================== RCS file: /cvs/src/src/gold/object.cc,v retrieving revision 1.97 diff -u -p -r1.97 object.cc --- gold/object.cc 5 Aug 2009 20:51:56 -0000 1.97 +++ gold/object.cc 17 Aug 2009 22:32:59 -0000 @@ -2237,27 +2237,18 @@ Object* make_elf_sized_object(const std::string& name, Input_file* input_file, off_t offset, const elfcpp::Ehdr& ehdr) { - int et = ehdr.get_e_type(); - if (et == elfcpp::ET_REL) + 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) { - Sized_relobj* obj = - new Sized_relobj(name, input_file, offset, ehdr); - obj->setup(ehdr); - return obj; - } - else if (et == elfcpp::ET_DYN) - { - Sized_dynobj* obj = - new Sized_dynobj(name, input_file, offset, ehdr); - obj->setup(ehdr); - return obj; - } - else - { - gold_error(_("%s: unsupported ELF file type %d"), - name.c_str(), et); + gold_fatal(_("%s: unsupported ELF machine number %d"), + name.c_str(), ehdr.get_e_machine()); return NULL; } + + return target->make_elf_object(name, input_file, offset, + ehdr); } } // End anonymous namespace. Index: gold/target.cc =================================================================== RCS file: /cvs/src/src/gold/target.cc,v retrieving revision 1.1 diff -u -p -r1.1 target.cc --- gold/target.cc 5 Jun 2009 21:32:56 -0000 1.1 +++ gold/target.cc 17 Aug 2009 22:32:59 -0000 @@ -22,6 +22,7 @@ #include "gold.h" #include "target.h" +#include "dynobj.h" namespace gold { @@ -56,3 +57,94 @@ Target::do_is_local_label_name (const ch } } // End namespace gold. + +namespace +{ + +using namespace gold; + +// 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 +inline Object* +make_elf_object_implementation( + const std::string& name, + Input_file* input_file, + off_t offset, + const elfcpp::Ehdr& ehdr) +{ + int et = ehdr.get_e_type(); + if (et == elfcpp::ET_REL) + { + Sized_relobj* obj = + new Sized_relobj(name, input_file, offset, ehdr); + obj->setup(ehdr); + return obj; + } + else if (et == elfcpp::ET_DYN) + { + Sized_dynobj* obj = + new Sized_dynobj(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; + } +} + +} // End anonymous namespace. + +namespace gold +{ + +// 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 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 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 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 make_elf_object_implementation<64, true>(name, input_file, offset, + ehdr); +} +#endif + +} // End namespace gold. Index: gold/target.h =================================================================== RCS file: /cvs/src/src/gold/target.h,v retrieving revision 1.34 diff -u -p -r1.34 target.h --- gold/target.h 22 Jun 2009 06:51:53 -0000 1.34 +++ gold/target.h 17 Aug 2009 22:33:00 -0000 @@ -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 + Object* + make_elf_object(const std::string& name, Input_file* input_file, + off_t offset, const elfcpp::Ehdr& 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,6 +308,37 @@ 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& name, Input_file* input_file, + off_t offset, const elfcpp::Ehdr<32, false>& ehdr); +#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& name, Input_file* input_file, + off_t offset, const elfcpp::Ehdr<32, true>& ehdr); +#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& name, Input_file* input_file, + off_t offset, 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: Target(const Target&); Target& operator=(const Target&);