[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