[PATCH] gold: remove unused methods in Output_data_got_powerpc

Alan Modra amodra@gmail.com
Sat Oct 12 00:43:00 GMT 2013


On Fri, Oct 11, 2013 at 04:48:27PM -0700, Cary Coutant wrote:
> >> No, wait a minute.  I do want those functions, but probably
> >> misunderstood C++ rules so they aren't effective.  I need to somehow
> >> arrange that Output_data_got_powerpc::reserve_ent() is called before
> >> Output_data_got adds anything to its entries_ vector, because the
> >> powerpc got header can sit somewhere in the middle of the GOT.  What's
> >> the best way to accomplish that?
> >
> > You need to change those in Output_data_got (the base class) to be virtual.
> > Then you can override them in Output_data_got_powerpc and use
> > Output_data_got<size, big_endian>::add_got_entry to call the superclass
> > method after doing what you need to do first.  Also note that you need to
> > name the argument type as Output_data_got<size, big_endian>::Got_entry.
> > You'll probably want to do typedef Output_data_got<size, big_endian> Base;
> > or suchlike in Output_data_got_powerpc so you can reduce the amount of
> > typing on the lhs of each :: there.
> >
> > And, of course, add a test case that notices the failure mode of missing
> > the reserve_ent call so you can tell whether you got it right.
> 
> When adding virtual functions, please observe the "no public virtuals"
> guideline. Rather than make add_got_entry and add_got_entry_pair
> virtual, though, I'd be OK with adding an inline reserve_entry()
> method in the Output_data_got class, having it call a protected
> virtual do_reserve_entry() method, and add a default empty
> implementation of that method in Output_data_got. Then you can simply
> override that method in Output_data_got_powerpc. That would eliminate
> the need for the messy declaration of Base::Got_entry, and the messy
> invocation of the superclass method.

Thanks for the guidance.  I obviously need some, to have written the
code that Roland removed..  Ick, how could I have thought that could
possibly work?

Another option, avoiding the need for a virtual function and the
overhead this adds for all targets, is to override add_global(),
add_global_plt() etc. in Output_data_got_powerpc.  This keeps the
overhead to powerpc.cc.  Is this preferable?

I also moved add_constant_pair into output.h for symmetry (and just in
case someone decided to optimise addition of constants).

Index: gold/output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.149
diff -u -p -r1.149 output.h
--- gold/output.h	11 Oct 2013 22:02:21 -0000	1.149
+++ gold/output.h	12 Oct 2013 00:26:10 -0000
@@ -2380,10 +2380,13 @@ class Output_data_got : public Output_da
   // entry from the start of the GOT.
   unsigned int
   add_constant(Valtype constant)
-  {
-    unsigned int got_offset = this->add_got_entry(Got_entry(constant));
-    return got_offset;
-  }
+  { return this->add_got_entry(Got_entry(constant)); }
+
+  // Add a pair of constants to the GOT.  This returns the offset of
+  // the new entry from the start of the GOT.
+  unsigned int
+  add_constant_pair(Valtype c1, Valtype c2)
+  { return this->add_got_entry_pair(Got_entry(c1), Got_entry(c2)); }
 
   // Replace GOT entry I with a new constant.
   void
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.99
diff -u -p -r1.99 powerpc.cc
--- gold/powerpc.cc	11 Oct 2013 23:06:08 -0000	1.99
+++ gold/powerpc.cc	12 Oct 2013 00:26:10 -0000
@@ -1987,13 +2094,88 @@ public:
       header_index_(size == 32 ? 0x2000 : 0)
   { }
 
+  // Override all the Output_data_got methods we use so as to first call
+  // reserve_ent().
+  bool
+  add_global(Symbol* gsym, unsigned int got_type)
+  {
+    this->reserve_ent();
+    return Output_data_got<size, big_endian>::add_global(gsym, got_type);
+  }
+
+  bool
+  add_global_plt(Symbol* gsym, unsigned int got_type)
+  {
+    this->reserve_ent();
+    return Output_data_got<size, big_endian>::add_global_plt(gsym, got_type);
+  }
+
+  bool
+  add_global_tls(Symbol* gsym, unsigned int got_type)
+  { return this->add_global_plt(gsym, got_type); }
+
+  void
+  add_global_with_rel(Symbol* gsym, unsigned int got_type,
+		      Output_data_reloc_generic* rel_dyn, unsigned int r_type)
+  {
+    this->reserve_ent();
+    Output_data_got<size, big_endian>::
+      add_global_with_rel(gsym, got_type, rel_dyn, r_type);
+  }
+
+  void
+  add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
+			   Output_data_reloc_generic* rel_dyn,
+			   unsigned int r_type_1, unsigned int r_type_2)
+  {
+    this->reserve_ent(2);
+    Output_data_got<size, big_endian>::
+      add_global_pair_with_rel(gsym, got_type, rel_dyn, r_type_1, r_type_2);
+  }
+
+  bool
+  add_local(Relobj* object, unsigned int sym_index, unsigned int got_type)
+  {
+    this->reserve_ent();
+    return Output_data_got<size, big_endian>::add_local(object, sym_index,
+							got_type);
+  }
+
+  bool
+  add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type)
+  {
+    this->reserve_ent();
+    return Output_data_got<size, big_endian>::add_local_plt(object, sym_index,
+							    got_type);
+  }
+
+  bool
+  add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type)
+  { return this->add_local_plt(object, sym_index, got_type); }
+
+  void
+  add_local_tls_pair(Relobj* object, unsigned int sym_index,
+		     unsigned int got_type,
+		     Output_data_reloc_generic* rel_dyn,
+		     unsigned int r_type)
+  {
+    this->reserve_ent(2);
+    Output_data_got<size, big_endian>::
+      add_local_tls_pair(object, sym_index, got_type, rel_dyn, r_type);
+  }
+
+  unsigned int
+  add_constant(Valtype constant)
+  {
+    this->reserve_ent();
+    return Output_data_got<size, big_endian>::add_constant(constant);
+  }
+
   unsigned int
   add_constant_pair(Valtype c1, Valtype c2)
   {
     this->reserve_ent(2);
-    unsigned int got_offset = this->add_constant(c1);
-    this->add_constant(c2);
-    return got_offset;
+    return Output_data_got<size, big_endian>::add_constant_pair(c1, c2);
   }
 
   // Offset of _GLOBAL_OFFSET_TABLE_.


-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list