This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gold] PowerPC PLT


"David Edelsohn" <dje.gcc@gmail.com> writes:

> Does Output_data_space and add_output_section_data create a new section
> or create a new view within a section?

Output_data_space is essentially equivalent to an input section,
albeit one for which the linker itself provides the contents.  Each
Output_data_space, like each input section, is attached to a
particular output section.  The layout machinery will pick a location
for the Output_data_space object within the output section.

Calling add_output_section_data is the primary way to attach an
Output_section_data object (such as an Output_data_space object) to an
output section.  In general gold treats each {name, type, flags} tuple
as a unique output section (for completeness I will note that some
flags are ignored, and that there are some exceptions for GNU ld
compatibility).  When you call add_output_section_data, if there is no
output section matching the {name, type, flags} tuple, gold will
create one.  Otherwise gold will attach the Output_section_data object
to the existing output section.


> Can Output_data_plt_powerpc::do_write()  use the different spaces to materialize
> all three pieces of the new PLT with a single iteration tlhrough the
> PLT entires or
> should the PLT be a single, undifferentiated blob that do_write()
> iterates through --
> appending the different pieces manually with three, separate loops over the PLT
> entries?

You may do it however you like.  For an Output_data_space you must
arrange to somehow write out the data.  The generic code doesn't care
how you do that.  For example, for the i386, the PLT portion of the
GOT is created as an Output_data_space object.  The actual contents
are written out in the Output_data_plt_i386::do_write function.  That
function loops over all the PLT entries once.  It writes out both the
PLT proper and the PLT portion of the GOT, using two separate output
views.

You couldn't make all of your PLT input data use Output_data_space,
because then there would be no object responsible for writing out the
data.  Typically you would have one class which gathers the PLT
entries, and the do_write function of that class would be responsible
for writing out all the data.


> +       // Define blrl instruction at _G_O_T_ - 4 for old ABI.
> +       this->got_->add_constant(blrl);
>         // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
> +       Symbol *got_anchor = 
>         symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
> ! 				    this->got_plt_,
>   				    0, 0, elfcpp::STT_OBJECT,
>   				    elfcpp::STB_LOCAL,
>   				    elfcpp::STV_HIDDEN, 0,
>   				    false, false);
> +       // ???
> +       got_anchor->set_got_offset (GOT_TYPE_STANDARD, 1);

Calling set_got_offset here may be correct but it seems odd.  Normally
the linker calls set_got_offset for a symbol which is referenced by a
relocation type which requires a GOT entry.  _GLOBAL_OFFSET_TABLE_
points to the GOT but it does not itself have a GOT entry.


>     if (size == 64)
>       {
> +       elfcpp::Swap<64, true>::writeval(pov + 0x00, b);
> +       elfcpp::Swap<64, true>::writeval(pov + 0x04, b);
> +       elfcpp::Swap<64, true>::writeval(pov + 0x08, b);

Shouldn't this code use <64, big_endian> rather than <64, true> ?


The rest of the code in
Output_data_plt_powerpc<size,big_endian>::do_write all looks
reasonable.


> +       // Create glink section within PLT.
> +       this->glink_ = new Output_data_space(8, "** GLINK");
> +       layout->add_output_section_data(".glink", elfcpp::SHT_PROGBITS,
> + 				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
> + 				      this->glink_);
> + 
> +       // Create stub section within PLT.
> +       this->stub_ = new Output_data_space(8, "** STUB");
> +       layout->add_output_section_data(".stub", elfcpp::SHT_PROGBITS,
> + 				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
> + 				      this->stub_);
> + 

Here you are effectively creating output sections named ".glink" and
".stub".  Is that where you want this data to wind up?


Thanks for working on this.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]