mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
PR gold/12880
* layout.h (class Layout): Add interp_segment_ field. * layout.cc (Layout::Layout): Initialize interp_segment_ field. (Layout::attach_allocated_section_to_segment): If making shared library, put .interp section in PT_INTERP segment. (Layout::finalize): Also call create_interp if -dynamic-linker option was used. (Layout::create_interp): Assert that there is no PT_INTERP segment. If not using a SECTIONS clause, use make_output_section. (Layout::make_output_segment): Set interp_segment_ if PT_INTERP. * script-sections.cc (Script_sections::create_note_and_tls_segments): If making shared library, put .interp section in PT_INTERP segment.
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
2011-06-17 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR gold/12880
|
||||
* layout.h (class Layout): Add interp_segment_ field.
|
||||
* layout.cc (Layout::Layout): Initialize interp_segment_ field.
|
||||
(Layout::attach_allocated_section_to_segment): If making shared
|
||||
library, put .interp section in PT_INTERP segment.
|
||||
(Layout::finalize): Also call create_interp if -dynamic-linker
|
||||
option was used.
|
||||
(Layout::create_interp): Assert that there is no PT_INTERP
|
||||
segment. If not using a SECTIONS clause, use make_output_section.
|
||||
(Layout::make_output_segment): Set interp_segment_ if PT_INTERP.
|
||||
* script-sections.cc
|
||||
(Script_sections::create_note_and_tls_segments): If making shared
|
||||
library, put .interp section in PT_INTERP segment.
|
||||
|
||||
2011-06-17 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* object.cc (Sized_relobj_file::do_layout): Keep warning sections
|
||||
|
||||
@@ -360,6 +360,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
|
||||
section_headers_(NULL),
|
||||
tls_segment_(NULL),
|
||||
relro_segment_(NULL),
|
||||
interp_segment_(NULL),
|
||||
increase_relro_(0),
|
||||
symtab_section_(NULL),
|
||||
symtab_xindex_(NULL),
|
||||
@@ -618,11 +619,8 @@ Layout::find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
|
||||
|
||||
// Return the output section to use for section NAME with type TYPE
|
||||
// and section flags FLAGS. NAME must be canonicalized in the string
|
||||
// pool, and NAME_KEY is the key. IS_INTERP is true if this is the
|
||||
// .interp section. IS_DYNAMIC_LINKER_SECTION is true if this section
|
||||
// is used by the dynamic linker. IS_RELRO is true for a relro
|
||||
// section. IS_LAST_RELRO is true for the last relro section.
|
||||
// IS_FIRST_NON_RELRO is true for the first non-relro section.
|
||||
// pool, and NAME_KEY is the key. ORDER is where this should appear
|
||||
// in the output sections. IS_RELRO is true for a relro section.
|
||||
|
||||
Output_section*
|
||||
Layout::get_output_section(const char* name, Stringpool::Key name_key,
|
||||
@@ -687,12 +685,9 @@ Layout::get_output_section(const char* name, Stringpool::Key name_key,
|
||||
// RELOBJ, with type TYPE and flags FLAGS. RELOBJ may be NULL for a
|
||||
// linker created section. IS_INPUT_SECTION is true if we are
|
||||
// choosing an output section for an input section found in a input
|
||||
// file. IS_INTERP is true if this is the .interp section.
|
||||
// IS_DYNAMIC_LINKER_SECTION is true if this section is used by the
|
||||
// dynamic linker. IS_RELRO is true for a relro section.
|
||||
// IS_LAST_RELRO is true for the last relro section.
|
||||
// IS_FIRST_NON_RELRO is true for the first non-relro section. This
|
||||
// will return NULL if the input section should be discarded.
|
||||
// file. ORDER is where this section should appear in the output
|
||||
// sections. IS_RELRO is true for a relro section. This will return
|
||||
// NULL if the input section should be discarded.
|
||||
|
||||
Output_section*
|
||||
Layout::choose_output_section(const Relobj* relobj, const char* name,
|
||||
@@ -1541,6 +1536,21 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
|
||||
this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
|
||||
this->relro_segment_->add_output_section_to_nonload(os, seg_flags);
|
||||
}
|
||||
|
||||
// If we are making a shared library, and we see a section named
|
||||
// .interp, and the -dynamic-linker option was not used, then put
|
||||
// the .interp section into a PT_INTERP segment. This is for GNU ld
|
||||
// compatibility. If making an executable, or if the
|
||||
// -dynamic-linker option was used, we will create the section and
|
||||
// segment in Layout::create_interp.
|
||||
if (strcmp(os->name(), ".interp") == 0
|
||||
&& parameters->options().shared()
|
||||
&& parameters->options().dynamic_linker() == NULL)
|
||||
{
|
||||
if (this->interp_segment_ == NULL)
|
||||
this->make_output_segment(elfcpp::PT_INTERP, seg_flags);
|
||||
this->interp_segment_->add_output_section_to_nonload(os, seg_flags);
|
||||
}
|
||||
}
|
||||
|
||||
// Make an output section for a script.
|
||||
@@ -2164,7 +2174,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
|
||||
|
||||
// Create the .interp section to hold the name of the
|
||||
// interpreter, and put it in a PT_INTERP segment.
|
||||
if (!parameters->options().shared())
|
||||
if (!parameters->options().shared()
|
||||
|| parameters->options().dynamic_linker() != NULL)
|
||||
this->create_interp(target);
|
||||
|
||||
// Finish the .dynamic section to hold the dynamic data, and put
|
||||
@@ -3845,6 +3856,8 @@ Layout::sized_create_version_sections(
|
||||
void
|
||||
Layout::create_interp(const Target* target)
|
||||
{
|
||||
gold_assert(this->interp_segment_ == NULL);
|
||||
|
||||
const char* interp = parameters->options().dynamic_linker();
|
||||
if (interp == NULL)
|
||||
{
|
||||
@@ -3856,11 +3869,23 @@ Layout::create_interp(const Target* target)
|
||||
|
||||
Output_section_data* odata = new Output_data_const(interp, len, 1);
|
||||
|
||||
Output_section* osec = this->choose_output_section(NULL, ".interp",
|
||||
elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, ORDER_INTERP,
|
||||
false);
|
||||
Output_section* osec;
|
||||
|
||||
// If we are using a SECTIONS clause, let it decide where the
|
||||
// .interp section should go. Otherwise always create a new section
|
||||
// so that this .interp section does not get confused with any
|
||||
// section of the same name in the program.
|
||||
if (this->script_options_->saw_sections_clause())
|
||||
osec = this->choose_output_section(NULL, ".interp", elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC, false, ORDER_INTERP,
|
||||
false);
|
||||
else
|
||||
{
|
||||
const char* n = this->namepool_.add("interp", false, NULL);
|
||||
osec = this->make_output_section(n, elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC, ORDER_INTERP, false);
|
||||
}
|
||||
|
||||
osec->add_output_section_data(odata);
|
||||
|
||||
if (!this->script_options_->saw_phdrs_clause())
|
||||
@@ -4389,6 +4414,8 @@ Layout::make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
|
||||
this->tls_segment_ = oseg;
|
||||
else if (type == elfcpp::PT_GNU_RELRO)
|
||||
this->relro_segment_ = oseg;
|
||||
else if (type == elfcpp::PT_INTERP)
|
||||
this->interp_segment_ = oseg;
|
||||
|
||||
return oseg;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// layout.h -- lay out output file sections for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@@ -1168,6 +1168,8 @@ class Layout
|
||||
Output_segment* tls_segment_;
|
||||
// A pointer to the PT_GNU_RELRO segment if there is one.
|
||||
Output_segment* relro_segment_;
|
||||
// A pointer to the PT_INTERP segment if there is one.
|
||||
Output_segment* interp_segment_;
|
||||
// A backend may increase the size of the PT_GNU_RELRO segment if
|
||||
// there is one. This is the amount to increase it by.
|
||||
unsigned int increase_relro_;
|
||||
|
||||
@@ -3936,6 +3936,21 @@ Script_sections::create_note_and_tls_segments(
|
||||
|
||||
saw_tls = true;
|
||||
}
|
||||
|
||||
// If we are making a shared library, and we see a section named
|
||||
// .interp, and the -dynamic-linker option was not used, then
|
||||
// put the .interp section in a PT_INTERP segment. This is for
|
||||
// GNU ld compatibility.
|
||||
if (strcmp((*p)->name(), ".interp") == 0
|
||||
&& parameters->options().shared()
|
||||
&& parameters->options().dynamic_linker() == NULL)
|
||||
{
|
||||
elfcpp::Elf_Word seg_flags =
|
||||
Layout::section_flags_to_segment((*p)->flags());
|
||||
Output_segment* oseg = layout->make_output_segment(elfcpp::PT_INTERP,
|
||||
seg_flags);
|
||||
oseg->add_output_section_to_nonload(*p, seg_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user