[PATCH][GOLD] Add make_elf_object target hooks.
Doug Kwan (關振德)
dougkwan@google.com
Tue Aug 18 03:12:00 GMT 2009
Hi,
This patch adds hooks in the Target class for creating ELF objects
via a target. The hooks are useful for targets requiring
target-specific extension to the existing ELF object classes via
sub-classing. This is tested on x86_64-unknown-linux-gnu.
-Doug
2009-08-17 Doug Kwan <dougkwan@google.com>
* object.cc(make_elf_sized_object): Find target and ask target to
make an ELF object.
* target.cc: Include dynobj.h.
(make_elf_object_implementation): New.
(Target::do_make_elf_object): New.
* target.h (Target::make_elf_object): New.
(Target::do_make_elf_object): New.
-------------- next part --------------
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<size, big_endian>& 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<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);
+ gold_fatal(_("%s: unsupported ELF machine number %d"),
+ name.c_str(), ehdr.get_e_machine());
return NULL;
}
+
+ return target->make_elf_object<size, big_endian>(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<int size, bool big_endian>
+inline Object*
+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(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;
+ }
+}
+
+} // 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<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,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&);
More information about the Binutils
mailing list