public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH][GOLD] Add make_elf_object target hooks.
@ 2009-08-18  3:12 Doug Kwan (關振德)
  2009-08-18 14:41 ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Doug Kwan (關振德) @ 2009-08-18  3:12 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]

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.

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 6467 bytes --]

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][GOLD] Add make_elf_object target hooks.
  2009-08-18  3:12 [PATCH][GOLD] Add make_elf_object target hooks Doug Kwan (關振德)
@ 2009-08-18 14:41 ` Ian Lance Taylor
  2009-08-18 16:29   ` Doug Kwan (關振德)
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2009-08-18 14:41 UTC (permalink / raw)
  To: Doug Kwan (關振德); +Cc: binutils

"Doug Kwan (關振德)" <dougkwan@google.com> writes:

> +      gold_fatal(_("%s: unsupported ELF machine number %d"),
> +		 name.c_str(), ehdr.get_e_machine());
>        return NULL;

No need to call return after calling gold_fatal.


> +      obj->setup(ehdr);

It no longer makes sense for Object::setup to take an ehdr parameter.
It should take a target parameter, and avoid looking up the target
again.


> +  // 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

Interesting problem.  I wonder if there is anything we can do to make
that easier to write.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][GOLD] Add make_elf_object target hooks.
  2009-08-18 14:41 ` Ian Lance Taylor
@ 2009-08-18 16:29   ` Doug Kwan (關振德)
  2009-08-18 18:35     ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Doug Kwan (關振德) @ 2009-08-18 16:29 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: binutils

2009/8/18 Ian Lance Taylor <iant@google.com>:

>> +      obj->setup(ehdr);
>
> It no longer makes sense for Object::setup to take an ehdr parameter.
> It should take a target parameter, and avoid looking up the target
> again.

Agree. I suppose all objects have targets and their targets do not
change.   Should setup() be simply part of the constructor?

>
>> +  // 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
>
> Interesting problem.  I wonder if there is anything we can do to make
> that easier to write.

Unfortunately, virtual functions cannot be templated.  That's why I
mentioned changing the paratmeter ehdr back to a raw unsigned char
pointer.  If we do so,  we only have one virtual function instead of
four.  The downside of doing that is that callers must ensure that the
pointer points to something valid.   Passing an
Elfcpp::Ehdr<size,big_endian> object enforces that automatically.

-Doug

> Ian
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][GOLD] Add make_elf_object target hooks.
  2009-08-18 16:29   ` Doug Kwan (關振德)
@ 2009-08-18 18:35     ` Ian Lance Taylor
  2009-08-18 19:08       ` Doug Kwan (關振德)
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2009-08-18 18:35 UTC (permalink / raw)
  To: Doug Kwan (關振德); +Cc: binutils

"Doug Kwan (關振德)" <dougkwan@google.com> writes:

> 2009/8/18 Ian Lance Taylor <iant@google.com>:
>
>>> +      obj->setup(ehdr);
>>
>> It no longer makes sense for Object::setup to take an ehdr parameter.
>> It should take a target parameter, and avoid looking up the target
>> again.
>
> Agree. I suppose all objects have targets and their targets do not
> change.   Should setup() be simply part of the constructor?

I originally left it out because it can fail, and it's weird to have a
constructor fail.  I guess I'd prefer to keep it separate for now.


>> Interesting problem.  I wonder if there is anything we can do to make
>> that easier to write.
>
> Unfortunately, virtual functions cannot be templated.  That's why I
> mentioned changing the paratmeter ehdr back to a raw unsigned char
> pointer.  If we do so,  we only have one virtual function instead of
> four.  The downside of doing that is that callers must ensure that the
> pointer points to something valid.   Passing an
> Elfcpp::Ehdr<size,big_endian> object enforces that automatically.

Yeah, I guess the way you did it is fine.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][GOLD] Add make_elf_object target hooks.
  2009-08-18 18:35     ` Ian Lance Taylor
@ 2009-08-18 19:08       ` Doug Kwan (關振德)
  2009-08-19  0:02         ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Doug Kwan (關振德) @ 2009-08-18 19:08 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 2343 bytes --]

Hi,

    I have updated the patch.

-Doug

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/8/18 Ian Lance Taylor <iant@google.com>:
> "Doug Kwan (關振德)" <dougkwan@google.com> writes:
>
>> 2009/8/18 Ian Lance Taylor <iant@google.com>:
>>
>>>> +      obj->setup(ehdr);
>>>
>>> It no longer makes sense for Object::setup to take an ehdr parameter.
>>> It should take a target parameter, and avoid looking up the target
>>> again.
>>
>> Agree. I suppose all objects have targets and their targets do not
>> change.   Should setup() be simply part of the constructor?
>
> I originally left it out because it can fail, and it's weird to have a
> constructor fail.  I guess I'd prefer to keep it separate for now.
>
>
>>> Interesting problem.  I wonder if there is anything we can do to make
>>> that easier to write.
>>
>> Unfortunately, virtual functions cannot be templated.  That's why I
>> mentioned changing the paratmeter ehdr back to a raw unsigned char
>> pointer.  If we do so,  we only have one virtual function instead of
>> four.  The downside of doing that is that callers must ensure that the
>> pointer points to something valid.   Passing an
>> Elfcpp::Ehdr<size,big_endian> object enforces that automatically.
>
> Yeah, I guess the way you did it is fine.
>
> Ian
>

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 10449 bytes --]

Index: gold/dynobj.cc
===================================================================
RCS file: /cvs/src/src/gold/dynobj.cc,v
retrieving revision 1.43
diff -u -p -r1.43 dynobj.cc
--- gold/dynobj.cc	13 Feb 2009 19:04:44 -0000	1.43
+++ gold/dynobj.cc	18 Aug 2009 18:50:10 -0000
@@ -83,13 +83,9 @@ Sized_dynobj<size, big_endian>::Sized_dy
 
 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);
 }
Index: gold/dynobj.h
===================================================================
RCS file: /cvs/src/src/gold/dynobj.h,v
retrieving revision 1.31
diff -u -p -r1.31 dynobj.h
--- gold/dynobj.h	10 Aug 2009 02:29:30 -0000	1.31
+++ gold/dynobj.h	18 Aug 2009 18:50:10 -0000
@@ -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
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	18 Aug 2009 18:50:11 -0000
@@ -132,19 +132,6 @@ Xindex::sym_xindex_to_shndx(Object* obje
 
 // 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_r
 
 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.
Index: gold/object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.77
diff -u -p -r1.77 object.h
--- gold/object.h	5 Aug 2009 20:51:56 -0000	1.77
+++ gold/object.h	18 Aug 2009 18:50:11 -0000
@@ -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.
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	18 Aug 2009 18:50:11 -0000
@@ -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 ch
   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.
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	18 Aug 2009 18:50:11 -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,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&);
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][GOLD] Add make_elf_object target hooks.
  2009-08-18 19:08       ` Doug Kwan (關振德)
@ 2009-08-19  0:02         ` Ian Lance Taylor
  0 siblings, 0 replies; 6+ messages in thread
From: Ian Lance Taylor @ 2009-08-19  0:02 UTC (permalink / raw)
  To: Doug Kwan (關振德); +Cc: binutils

"Doug Kwan (關振德)" <dougkwan@google.com> writes:

> 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 is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-08-18 23:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-18  3:12 [PATCH][GOLD] Add make_elf_object target hooks Doug Kwan (關振德)
2009-08-18 14:41 ` Ian Lance Taylor
2009-08-18 16:29   ` Doug Kwan (關振德)
2009-08-18 18:35     ` Ian Lance Taylor
2009-08-18 19:08       ` Doug Kwan (關振德)
2009-08-19  0:02         ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).