mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-19 15:34:18 +00:00
* layout.cc (Layout::Layout): Initialize increase_relro_.
(Layout::get_output_section): Add is_relro, is_last_relro, and is_first_non_relro parameters. Change all callers. (Layout::choose_output_section): Likewise. (Layout::add_output_section_data): Likewise. (Layout::make_output_section): Likewise. (Layout::set_segment_offsets): Clear increase_relro when using a linker script. * layout.h (class Layout): Add increase_relro method. Add increase_relro_ field. Update declarations. * output.cc (Output_section::Output_section): Initialize is_last_relro_ and is_first_non_relro_. (Output_segment::add_output_section): Group relro sections is do_sort is true. Handle is_last_relro and is_first_non_relro. (Output_segment::maximum_alignment): Remove relro handling. (Output_segment::set_section_addresses): Add increase_relro parameter. Change all callers. Add initial alignment to align relro sections on separate page. Remove old relro handling. (Output_segment::set_section_list_addresses): Remove in_relro parameter. Change all callers. (Output_segment::set_offset): Add increase parameter. Change all callers. Remove old relro handling. * output.h (class Output_section): Add new methods: is_last_relro, set_is_last_relro, is_first_non_relro, set_is_first_non_relro. Add is_last_relro_ and is_first_non_relro_ fields. * i386.cc (Target_i386::got_section): Don't call set_is_relro. Create separate .got.plt section. Call increase_relro. * x86_64.cc (Target_x86_64::got_section): Likewise. * testsuite/relro_script_test.t: Add .got.plt.
This commit is contained in:
parent
f0ba79e29c
commit
1a2dff539b
@ -1,5 +1,35 @@
|
||||
2009-12-29 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* layout.cc (Layout::Layout): Initialize increase_relro_.
|
||||
(Layout::get_output_section): Add is_relro, is_last_relro, and
|
||||
is_first_non_relro parameters. Change all callers.
|
||||
(Layout::choose_output_section): Likewise.
|
||||
(Layout::add_output_section_data): Likewise.
|
||||
(Layout::make_output_section): Likewise.
|
||||
(Layout::set_segment_offsets): Clear increase_relro when using a
|
||||
linker script.
|
||||
* layout.h (class Layout): Add increase_relro method. Add
|
||||
increase_relro_ field. Update declarations.
|
||||
* output.cc (Output_section::Output_section): Initialize
|
||||
is_last_relro_ and is_first_non_relro_.
|
||||
(Output_segment::add_output_section): Group relro sections is
|
||||
do_sort is true. Handle is_last_relro and is_first_non_relro.
|
||||
(Output_segment::maximum_alignment): Remove relro handling.
|
||||
(Output_segment::set_section_addresses): Add increase_relro
|
||||
parameter. Change all callers. Add initial alignment to align
|
||||
relro sections on separate page. Remove old relro handling.
|
||||
(Output_segment::set_section_list_addresses): Remove in_relro
|
||||
parameter. Change all callers.
|
||||
(Output_segment::set_offset): Add increase parameter. Change all
|
||||
callers. Remove old relro handling.
|
||||
* output.h (class Output_section): Add new methods: is_last_relro,
|
||||
set_is_last_relro, is_first_non_relro, set_is_first_non_relro.
|
||||
Add is_last_relro_ and is_first_non_relro_ fields.
|
||||
* i386.cc (Target_i386::got_section): Don't call set_is_relro.
|
||||
Create separate .got.plt section. Call increase_relro.
|
||||
* x86_64.cc (Target_x86_64::got_section): Likewise.
|
||||
* testsuite/relro_script_test.t: Add .got.plt.
|
||||
|
||||
PR 10450
|
||||
* layout.cc (Layout::Layout): Initialize dynamic_symbol_ field.
|
||||
(Layout::create_initial_dynamic_sections): Set dynamic_symbol_.
|
||||
|
19
gold/arm.cc
19
gold/arm.cc
@ -2592,8 +2592,8 @@ Target_arm<big_endian>::got_section(Symbol_table* symtab, Layout* layout)
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_, false);
|
||||
os->set_is_relro();
|
||||
this->got_, false, true, true,
|
||||
false);
|
||||
|
||||
// The old GNU linker creates a .got.plt section. We just
|
||||
// create another set of data in the .got section. Note that we
|
||||
@ -2603,8 +2603,8 @@ Target_arm<big_endian>::got_section(Symbol_table* symtab, Layout* layout)
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_plt_, false);
|
||||
os->set_is_relro();
|
||||
this->got_plt_, false, false,
|
||||
false, true);
|
||||
|
||||
// The first three entries are reserved.
|
||||
this->got_plt_->set_current_data_size(3 * 4);
|
||||
@ -2632,7 +2632,8 @@ Target_arm<big_endian>::rel_dyn_section(Layout* layout)
|
||||
gold_assert(layout != NULL);
|
||||
this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
|
||||
layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
|
||||
elfcpp::SHF_ALLOC, this->rel_dyn_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_dyn_, true,
|
||||
false, false, false);
|
||||
}
|
||||
return this->rel_dyn_;
|
||||
}
|
||||
@ -4052,7 +4053,8 @@ Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout,
|
||||
{
|
||||
this->rel_ = new Reloc_section(false);
|
||||
layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
|
||||
elfcpp::SHF_ALLOC, this->rel_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_, true, false,
|
||||
false, false);
|
||||
}
|
||||
|
||||
template<bool big_endian>
|
||||
@ -4214,7 +4216,7 @@ Target_arm<big_endian>::make_plt_entry(Symbol_table* symtab, Layout* layout,
|
||||
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR),
|
||||
this->plt_, false);
|
||||
this->plt_, false, false, false, false);
|
||||
}
|
||||
this->plt_->add_entry(gsym);
|
||||
}
|
||||
@ -4793,7 +4795,8 @@ Target_arm<big_endian>::do_finalize_sections(
|
||||
new Output_attributes_section_data(*this->attributes_section_data_);
|
||||
layout->add_output_section_data(".ARM.attributes",
|
||||
elfcpp::SHT_ARM_ATTRIBUTES, 0,
|
||||
attributes_section, false);
|
||||
attributes_section, false, false, false,
|
||||
false);
|
||||
}
|
||||
|
||||
// Return whether a direct absolute static relocation needs to be applied.
|
||||
|
@ -239,7 +239,8 @@ Symbol_table::do_allocate_commons_list(
|
||||
Output_data_space *poc = new Output_data_space(addralign, ds_name);
|
||||
Output_section *os = layout->add_output_section_data(name,
|
||||
elfcpp::SHT_NOBITS,
|
||||
flags, poc, false);
|
||||
flags, poc, false,
|
||||
false, false, false);
|
||||
if (os != NULL)
|
||||
{
|
||||
if (commons_section_type == COMMONS_SMALL)
|
||||
|
@ -138,7 +138,8 @@ Copy_relocs<sh_type, size, big_endian>::emit_copy_reloc(
|
||||
layout->add_output_section_data(".bss",
|
||||
elfcpp::SHT_NOBITS,
|
||||
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
|
||||
this->dynbss_, false);
|
||||
this->dynbss_, false, false, false,
|
||||
false);
|
||||
}
|
||||
|
||||
Output_data_space* dynbss = this->dynbss_;
|
||||
|
25
gold/i386.cc
25
gold/i386.cc
@ -461,23 +461,22 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout)
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_, false);
|
||||
os->set_is_relro();
|
||||
this->got_, false, true, true,
|
||||
false);
|
||||
|
||||
// The old GNU linker creates a .got.plt section. We just
|
||||
// create another set of data in the .got section. Note that we
|
||||
// always create a PLT if we create a GOT, although the PLT
|
||||
// might be empty.
|
||||
this->got_plt_ = new Output_data_space(4, "** GOT PLT");
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
os = layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_plt_, false);
|
||||
os->set_is_relro();
|
||||
this->got_plt_, false, false, false,
|
||||
true);
|
||||
|
||||
// The first three entries are reserved.
|
||||
this->got_plt_->set_current_data_size(3 * 4);
|
||||
|
||||
// Those bytes can go into the relro segment.
|
||||
layout->increase_relro(3 * 4);
|
||||
|
||||
// Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
|
||||
symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
|
||||
Symbol_table::PREDEFINED,
|
||||
@ -501,7 +500,8 @@ Target_i386::rel_dyn_section(Layout* layout)
|
||||
gold_assert(layout != NULL);
|
||||
this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
|
||||
layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
|
||||
elfcpp::SHF_ALLOC, this->rel_dyn_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_dyn_, true,
|
||||
false, false, false);
|
||||
}
|
||||
return this->rel_dyn_;
|
||||
}
|
||||
@ -576,7 +576,8 @@ Output_data_plt_i386::Output_data_plt_i386(Layout* layout,
|
||||
{
|
||||
this->rel_ = new Reloc_section(false);
|
||||
layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
|
||||
elfcpp::SHF_ALLOC, this->rel_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_, true,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -761,7 +762,7 @@ Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
|
||||
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR),
|
||||
this->plt_, false);
|
||||
this->plt_, false, false, false, false);
|
||||
}
|
||||
|
||||
this->plt_->add_entry(gsym);
|
||||
|
121
gold/layout.cc
121
gold/layout.cc
@ -175,6 +175,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
|
||||
section_headers_(NULL),
|
||||
tls_segment_(NULL),
|
||||
relro_segment_(NULL),
|
||||
increase_relro_(0),
|
||||
symtab_section_(NULL),
|
||||
symtab_xindex_(NULL),
|
||||
dynsym_section_(NULL),
|
||||
@ -391,12 +392,16 @@ Layout::find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
|
||||
// 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 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.
|
||||
|
||||
Output_section*
|
||||
Layout::get_output_section(const char* name, Stringpool::Key name_key,
|
||||
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
|
||||
bool is_interp, bool is_dynamic_linker_section)
|
||||
bool is_interp, bool is_dynamic_linker_section,
|
||||
bool is_relro, bool is_last_relro,
|
||||
bool is_first_non_relro)
|
||||
{
|
||||
elfcpp::Elf_Xword lookup_flags = flags;
|
||||
|
||||
@ -446,7 +451,8 @@ Layout::get_output_section(const char* name, Stringpool::Key name_key,
|
||||
|
||||
if (os == NULL)
|
||||
os = this->make_output_section(name, type, flags, is_interp,
|
||||
is_dynamic_linker_section);
|
||||
is_dynamic_linker_section, is_relro,
|
||||
is_last_relro, is_first_non_relro);
|
||||
ins.first->second = os;
|
||||
return os;
|
||||
}
|
||||
@ -458,14 +464,17 @@ Layout::get_output_section(const char* name, Stringpool::Key name_key,
|
||||
// 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. This will return NULL if the input section should
|
||||
// be discarded.
|
||||
// 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.
|
||||
|
||||
Output_section*
|
||||
Layout::choose_output_section(const Relobj* relobj, const char* name,
|
||||
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
|
||||
bool is_input_section, bool is_interp,
|
||||
bool is_dynamic_linker_section)
|
||||
bool is_dynamic_linker_section, bool is_relro,
|
||||
bool is_last_relro, bool is_first_non_relro)
|
||||
{
|
||||
// We should not see any input sections after we have attached
|
||||
// sections to segments.
|
||||
@ -515,7 +524,8 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
|
||||
|
||||
Output_section* os =
|
||||
this->make_output_section(name, type, flags, is_interp,
|
||||
is_dynamic_linker_section);
|
||||
is_dynamic_linker_section, is_relro,
|
||||
is_last_relro, is_first_non_relro);
|
||||
os->set_found_in_sections_clause();
|
||||
*output_section_slot = os;
|
||||
return os;
|
||||
@ -539,7 +549,8 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
|
||||
// Find or make the output section. The output section is selected
|
||||
// based on the section name, type, and flags.
|
||||
return this->get_output_section(name, name_key, type, flags, is_interp,
|
||||
is_dynamic_linker_section);
|
||||
is_dynamic_linker_section, is_relro,
|
||||
is_last_relro, is_first_non_relro);
|
||||
}
|
||||
|
||||
// Return the output section to use for input section SHNDX, with name
|
||||
@ -572,13 +583,14 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
|
||||
{
|
||||
name = this->namepool_.add(name, true, NULL);
|
||||
os = this->make_output_section(name, shdr.get_sh_type(),
|
||||
shdr.get_sh_flags(), false, false);
|
||||
shdr.get_sh_flags(), false, false,
|
||||
false, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
os = this->choose_output_section(object, name, shdr.get_sh_type(),
|
||||
shdr.get_sh_flags(), true, false,
|
||||
false);
|
||||
false, false, false, false);
|
||||
if (os == NULL)
|
||||
return NULL;
|
||||
}
|
||||
@ -629,6 +641,7 @@ Layout::layout_reloc(Sized_relobj<size, big_endian>* object,
|
||||
Output_section* os = this->choose_output_section(object, name.c_str(),
|
||||
sh_type,
|
||||
shdr.get_sh_flags(),
|
||||
false, false, false,
|
||||
false, false, false);
|
||||
|
||||
os->set_should_link_to_symtab();
|
||||
@ -677,6 +690,7 @@ Layout::layout_group(Symbol_table* symtab,
|
||||
Output_section* os = this->make_output_section(group_section_name,
|
||||
elfcpp::SHT_GROUP,
|
||||
shdr.get_sh_flags(),
|
||||
false, false, false,
|
||||
false, false);
|
||||
|
||||
// We need to find a symbol with the signature in the symbol table.
|
||||
@ -731,6 +745,7 @@ Layout::layout_eh_frame(Sized_relobj<size, big_endian>* object,
|
||||
name,
|
||||
elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, false,
|
||||
false, false, false);
|
||||
if (os == NULL)
|
||||
return NULL;
|
||||
@ -747,6 +762,7 @@ Layout::layout_eh_frame(Sized_relobj<size, big_endian>* object,
|
||||
".eh_frame_hdr",
|
||||
elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, false,
|
||||
false, false, false);
|
||||
|
||||
if (hdr_os != NULL)
|
||||
@ -814,11 +830,15 @@ Output_section*
|
||||
Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type,
|
||||
elfcpp::Elf_Xword flags,
|
||||
Output_section_data* posd,
|
||||
bool is_dynamic_linker_section)
|
||||
bool is_dynamic_linker_section,
|
||||
bool is_relro, bool is_last_relro,
|
||||
bool is_first_non_relro)
|
||||
{
|
||||
Output_section* os = this->choose_output_section(NULL, name, type, flags,
|
||||
false, false,
|
||||
is_dynamic_linker_section);
|
||||
is_dynamic_linker_section,
|
||||
is_relro, is_last_relro,
|
||||
is_first_non_relro);
|
||||
if (os != NULL)
|
||||
os->add_output_section_data(posd);
|
||||
return os;
|
||||
@ -855,12 +875,15 @@ is_compressible_debug_section(const char* secname)
|
||||
// Make a new Output_section, and attach it to segments as
|
||||
// appropriate. 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.
|
||||
// dynamic linker. IS_RELRO is true if this is a relro section.
|
||||
// IS_LAST_RELRO is true if this is the last relro section.
|
||||
// IS_FIRST_NON_RELRO is true if this is the first non relro section.
|
||||
|
||||
Output_section*
|
||||
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
||||
elfcpp::Elf_Xword flags, bool is_interp,
|
||||
bool is_dynamic_linker_section)
|
||||
bool is_dynamic_linker_section, bool is_relro,
|
||||
bool is_last_relro, bool is_first_non_relro)
|
||||
{
|
||||
Output_section* os;
|
||||
if ((flags & elfcpp::SHF_ALLOC) == 0
|
||||
@ -897,6 +920,12 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
||||
os->set_is_interp();
|
||||
if (is_dynamic_linker_section)
|
||||
os->set_is_dynamic_linker_section();
|
||||
if (is_relro)
|
||||
os->set_is_relro();
|
||||
if (is_last_relro)
|
||||
os->set_is_last_relro();
|
||||
if (is_first_non_relro)
|
||||
os->set_is_first_non_relro();
|
||||
|
||||
parameters->target().new_output_section(os);
|
||||
|
||||
@ -1089,7 +1118,7 @@ Layout::make_output_section_for_script(const char* name)
|
||||
name = this->namepool_.add(name, false, NULL);
|
||||
Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC, false,
|
||||
false);
|
||||
false, false, false, false);
|
||||
os->set_found_in_sections_clause();
|
||||
return os;
|
||||
}
|
||||
@ -1159,8 +1188,8 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab)
|
||||
elfcpp::SHT_DYNAMIC,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
false, false, true);
|
||||
this->dynamic_section_->set_is_relro();
|
||||
false, false, true,
|
||||
true, false, false);
|
||||
|
||||
this->dynamic_symbol_ =
|
||||
symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED,
|
||||
@ -1766,7 +1795,7 @@ Layout::create_note(const char* name, int note_type,
|
||||
Output_section* os = this->choose_output_section(NULL, section_name,
|
||||
elfcpp::SHT_NOTE,
|
||||
flags, false, false,
|
||||
false);
|
||||
false, false, false, false);
|
||||
if (os == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -1846,7 +1875,7 @@ Layout::create_executable_stack_info()
|
||||
if (is_stack_executable)
|
||||
flags |= elfcpp::SHF_EXECINSTR;
|
||||
this->make_output_section(name, elfcpp::SHT_PROGBITS, flags, false,
|
||||
false);
|
||||
false, false, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2007,7 +2036,7 @@ Layout::create_incremental_info_sections()
|
||||
Output_section* inputs_os =
|
||||
this->make_output_section(incremental_inputs_name,
|
||||
elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0,
|
||||
false, false);
|
||||
false, false, false, false, false);
|
||||
Output_section_data* posd =
|
||||
this->incremental_inputs_->create_incremental_inputs_section_data();
|
||||
inputs_os->add_output_section_data(posd);
|
||||
@ -2017,7 +2046,8 @@ Layout::create_incremental_info_sections()
|
||||
this->namepool_.add(".gnu_incremental_strtab", false, NULL);
|
||||
Output_section* strtab_os = this->make_output_section(incremental_strtab_name,
|
||||
elfcpp::SHT_STRTAB,
|
||||
0, false, false);
|
||||
0, false, false,
|
||||
false, false, false);
|
||||
Output_data_strtab* strtab_data =
|
||||
new Output_data_strtab(this->incremental_inputs_->get_stringpool());
|
||||
strtab_os->add_output_section_data(strtab_data);
|
||||
@ -2203,6 +2233,10 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int increase_relro = this->increase_relro_;
|
||||
if (this->script_options_->saw_sections_clause())
|
||||
increase_relro = 0;
|
||||
|
||||
const bool check_sections = parameters->options().check_sections();
|
||||
Output_segment* last_load_segment = NULL;
|
||||
|
||||
@ -2291,6 +2325,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
|
||||
|
||||
unsigned int shndx_hold = *pshndx;
|
||||
uint64_t new_addr = (*p)->set_section_addresses(this, false, addr,
|
||||
increase_relro,
|
||||
&off, pshndx);
|
||||
|
||||
// Now that we know the size of this segment, we may be able
|
||||
@ -2317,6 +2352,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
|
||||
off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
|
||||
off = align_file_offset(off, addr, abi_pagesize);
|
||||
new_addr = (*p)->set_section_addresses(this, true, addr,
|
||||
increase_relro,
|
||||
&off, pshndx);
|
||||
}
|
||||
}
|
||||
@ -2354,7 +2390,9 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
|
||||
++p)
|
||||
{
|
||||
if ((*p)->type() != elfcpp::PT_LOAD)
|
||||
(*p)->set_offset();
|
||||
(*p)->set_offset((*p)->type() == elfcpp::PT_GNU_RELRO
|
||||
? increase_relro
|
||||
: 0);
|
||||
}
|
||||
|
||||
// Set the TLS offsets for each section in the PT_TLS segment.
|
||||
@ -2629,7 +2667,8 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
|
||||
const char* symtab_name = this->namepool_.add(".symtab", false, NULL);
|
||||
Output_section* osymtab = this->make_output_section(symtab_name,
|
||||
elfcpp::SHT_SYMTAB,
|
||||
0, false, false);
|
||||
0, false, false,
|
||||
false, false, false);
|
||||
this->symtab_section_ = osymtab;
|
||||
|
||||
Output_section_data* pos = new Output_data_fixed_space(off - startoff,
|
||||
@ -2651,7 +2690,7 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
|
||||
Output_section* osymtab_xindex =
|
||||
this->make_output_section(symtab_xindex_name,
|
||||
elfcpp::SHT_SYMTAB_SHNDX, 0, false,
|
||||
false);
|
||||
false, false, false, false);
|
||||
|
||||
size_t symcount = (off - startoff) / symsize;
|
||||
this->symtab_xindex_ = new Output_symtab_xindex(symcount);
|
||||
@ -2673,7 +2712,8 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
|
||||
const char* strtab_name = this->namepool_.add(".strtab", false, NULL);
|
||||
Output_section* ostrtab = this->make_output_section(strtab_name,
|
||||
elfcpp::SHT_STRTAB,
|
||||
0, false, false);
|
||||
0, false, false,
|
||||
false, false, false);
|
||||
|
||||
Output_section_data* pstr = new Output_data_strtab(&this->sympool_);
|
||||
ostrtab->add_output_section_data(pstr);
|
||||
@ -2701,7 +2741,8 @@ Layout::create_shstrtab()
|
||||
const char* name = this->namepool_.add(".shstrtab", false, NULL);
|
||||
|
||||
Output_section* os = this->make_output_section(name, elfcpp::SHT_STRTAB, 0,
|
||||
false, false);
|
||||
false, false, false, false,
|
||||
false);
|
||||
|
||||
if (strcmp(parameters->options().compress_debug_sections(), "none") != 0)
|
||||
{
|
||||
@ -2818,7 +2859,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
||||
Output_section* dynsym = this->choose_output_section(NULL, ".dynsym",
|
||||
elfcpp::SHT_DYNSYM,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true,
|
||||
false, false, false);
|
||||
|
||||
Output_section_data* odata = new Output_data_fixed_space(index * symsize,
|
||||
align,
|
||||
@ -2848,7 +2890,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
||||
this->choose_output_section(NULL, ".dynsym_shndx",
|
||||
elfcpp::SHT_SYMTAB_SHNDX,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true, false, false, false);
|
||||
|
||||
this->dynsym_xindex_ = new Output_symtab_xindex(index);
|
||||
|
||||
@ -2871,7 +2913,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
||||
Output_section* dynstr = this->choose_output_section(NULL, ".dynstr",
|
||||
elfcpp::SHT_STRTAB,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true,
|
||||
false, false, false);
|
||||
|
||||
Output_section_data* strdata = new Output_data_strtab(&this->dynpool_);
|
||||
dynstr->add_output_section_data(strdata);
|
||||
@ -2897,7 +2940,9 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
||||
Output_section* hashsec = this->choose_output_section(NULL, ".hash",
|
||||
elfcpp::SHT_HASH,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true,
|
||||
false, false,
|
||||
false);
|
||||
|
||||
Output_section_data* hashdata = new Output_data_const_buffer(phash,
|
||||
hashlen,
|
||||
@ -2922,7 +2967,9 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
|
||||
Output_section* hashsec = this->choose_output_section(NULL, ".gnu.hash",
|
||||
elfcpp::SHT_GNU_HASH,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true,
|
||||
false, false,
|
||||
false);
|
||||
|
||||
Output_section_data* hashdata = new Output_data_const_buffer(phash,
|
||||
hashlen,
|
||||
@ -3020,7 +3067,8 @@ Layout::sized_create_version_sections(
|
||||
Output_section* vsec = this->choose_output_section(NULL, ".gnu.version",
|
||||
elfcpp::SHT_GNU_versym,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true,
|
||||
false, false, false);
|
||||
|
||||
unsigned char* vbuf;
|
||||
unsigned int vsize;
|
||||
@ -3045,7 +3093,8 @@ Layout::sized_create_version_sections(
|
||||
vdsec= this->choose_output_section(NULL, ".gnu.version_d",
|
||||
elfcpp::SHT_GNU_verdef,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true, false, false,
|
||||
false);
|
||||
|
||||
unsigned char* vdbuf;
|
||||
unsigned int vdsize;
|
||||
@ -3070,7 +3119,8 @@ Layout::sized_create_version_sections(
|
||||
vnsec = this->choose_output_section(NULL, ".gnu.version_r",
|
||||
elfcpp::SHT_GNU_verneed,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, false, true);
|
||||
false, false, true, false, false,
|
||||
false);
|
||||
|
||||
unsigned char* vnbuf;
|
||||
unsigned int vnsize;
|
||||
@ -3110,7 +3160,8 @@ Layout::create_interp(const Target* target)
|
||||
Output_section* osec = this->choose_output_section(NULL, ".interp",
|
||||
elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC,
|
||||
false, true, true);
|
||||
false, true, true,
|
||||
false, false, false);
|
||||
osec->add_output_section_data(odata);
|
||||
|
||||
if (!this->script_options_->saw_phdrs_clause())
|
||||
|
@ -362,11 +362,21 @@ class Layout
|
||||
// Add an Output_section_data to the layout. This is used for
|
||||
// special sections like the GOT section. IS_DYNAMIC_LINKER_SECTION
|
||||
// is true for sections which are used by the dynamic linker, such
|
||||
// as dynamic reloc sections.
|
||||
// as dynamic reloc sections. IS_RELRO is true for relro sections.
|
||||
// IS_LAST_RELRO is true for the last relro section.
|
||||
// IS_FIRST_NON_RELRO is true for the first section after the relro
|
||||
// sections.
|
||||
Output_section*
|
||||
add_output_section_data(const char* name, elfcpp::Elf_Word type,
|
||||
elfcpp::Elf_Xword flags,
|
||||
Output_section_data*, bool is_dynamic_linker_section);
|
||||
Output_section_data*, bool is_dynamic_linker_section,
|
||||
bool is_relro, bool is_last_relro,
|
||||
bool is_first_non_relro);
|
||||
|
||||
// Increase the size of the relro segment by this much.
|
||||
void
|
||||
increase_relro(unsigned int s)
|
||||
{ this->increase_relro_ += s; }
|
||||
|
||||
// Create dynamic sections if necessary.
|
||||
void
|
||||
@ -752,20 +762,24 @@ class Layout
|
||||
Output_section*
|
||||
get_output_section(const char* name, Stringpool::Key name_key,
|
||||
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
|
||||
bool is_interp, bool is_dynamic_linker_section);
|
||||
bool is_interp, bool is_dynamic_linker_section,
|
||||
bool is_relro, bool is_last_relro,
|
||||
bool is_first_non_relro);
|
||||
|
||||
// Choose the output section for NAME in RELOBJ.
|
||||
Output_section*
|
||||
choose_output_section(const Relobj* relobj, const char* name,
|
||||
elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
|
||||
bool is_input_section, bool is_interp,
|
||||
bool is_dynamic_linker_section);
|
||||
bool is_dynamic_linker_section, bool is_relro,
|
||||
bool is_last_relro, bool is_first_non_relro);
|
||||
|
||||
// Create a new Output_section.
|
||||
Output_section*
|
||||
make_output_section(const char* name, elfcpp::Elf_Word type,
|
||||
elfcpp::Elf_Xword flags, bool is_interp,
|
||||
bool is_dynamic_linker_section);
|
||||
bool is_dynamic_linker_section, bool is_relro,
|
||||
bool is_last_relro, bool is_first_non_relro);
|
||||
|
||||
// Attach a section to a segment.
|
||||
void
|
||||
@ -941,6 +955,9 @@ class Layout
|
||||
Output_segment* tls_segment_;
|
||||
// A pointer to the PT_GNU_RELRO segment if there is one.
|
||||
Output_segment* relro_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_;
|
||||
// The SHT_SYMTAB output section.
|
||||
Output_section* symtab_section_;
|
||||
// The SHT_SYMTAB_SHNDX for the regular symbol table if there is one.
|
||||
|
169
gold/output.cc
169
gold/output.cc
@ -1795,6 +1795,8 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
|
||||
attached_input_sections_are_sorted_(false),
|
||||
is_relro_(false),
|
||||
is_relro_local_(false),
|
||||
is_last_relro_(false),
|
||||
is_first_non_relro_(false),
|
||||
is_small_section_(false),
|
||||
is_large_section_(false),
|
||||
is_interp_(false),
|
||||
@ -3157,26 +3159,52 @@ Output_segment::add_output_section(Output_section* os,
|
||||
// location in the section list.
|
||||
}
|
||||
|
||||
// For the PT_GNU_RELRO segment, we need to group relro sections,
|
||||
// and we need to put them before any non-relro sections. Also,
|
||||
// relro local sections go before relro non-local sections.
|
||||
if (parameters->options().relro() && os->is_relro())
|
||||
if (do_sort)
|
||||
{
|
||||
gold_assert(pdl == &this->output_data_);
|
||||
Output_segment::Output_data_list::iterator p;
|
||||
for (p = pdl->begin(); p != pdl->end(); ++p)
|
||||
// For the PT_GNU_RELRO segment, we need to group relro
|
||||
// sections, and we need to put them before any non-relro
|
||||
// sections. Any relro local sections go before relro non-local
|
||||
// sections. One section may be marked as the last relro
|
||||
// section.
|
||||
if (os->is_relro())
|
||||
{
|
||||
if (!(*p)->is_section())
|
||||
break;
|
||||
gold_assert(pdl == &this->output_data_);
|
||||
Output_segment::Output_data_list::iterator p;
|
||||
for (p = pdl->begin(); p != pdl->end(); ++p)
|
||||
{
|
||||
if (!(*p)->is_section())
|
||||
break;
|
||||
|
||||
Output_section* pos = (*p)->output_section();
|
||||
if (!pos->is_relro()
|
||||
|| (os->is_relro_local() && !pos->is_relro_local()))
|
||||
break;
|
||||
Output_section* pos = (*p)->output_section();
|
||||
if (!pos->is_relro()
|
||||
|| (os->is_relro_local() && !pos->is_relro_local())
|
||||
|| (!os->is_last_relro() && pos->is_last_relro()))
|
||||
break;
|
||||
}
|
||||
|
||||
pdl->insert(p, os);
|
||||
return;
|
||||
}
|
||||
|
||||
pdl->insert(p, os);
|
||||
return;
|
||||
// One section may be marked as the first section which follows
|
||||
// the relro sections.
|
||||
if (os->is_first_non_relro())
|
||||
{
|
||||
gold_assert(pdl == &this->output_data_);
|
||||
Output_segment::Output_data_list::iterator p;
|
||||
for (p = pdl->begin(); p != pdl->end(); ++p)
|
||||
{
|
||||
if (!(*p)->is_section())
|
||||
break;
|
||||
|
||||
Output_section* pos = (*p)->output_section();
|
||||
if (!pos->is_relro())
|
||||
break;
|
||||
}
|
||||
|
||||
pdl->insert(p, os);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Small data sections go at the end of the list of data sections.
|
||||
@ -3365,19 +3393,6 @@ Output_segment::maximum_alignment()
|
||||
if (addralign > this->max_align_)
|
||||
this->max_align_ = addralign;
|
||||
|
||||
// If -z relro is in effect, and the first section in this
|
||||
// segment is a relro section, then the segment must be aligned
|
||||
// to at least the common page size. This ensures that the
|
||||
// PT_GNU_RELRO segment will start at a page boundary.
|
||||
if (this->type_ == elfcpp::PT_LOAD
|
||||
&& parameters->options().relro()
|
||||
&& this->is_first_section_relro())
|
||||
{
|
||||
addralign = parameters->target().common_pagesize();
|
||||
if (addralign > this->max_align_)
|
||||
this->max_align_ = addralign;
|
||||
}
|
||||
|
||||
this->is_max_align_known_ = true;
|
||||
}
|
||||
|
||||
@ -3431,11 +3446,57 @@ Output_segment::dynamic_reloc_count_list(const Output_data_list* pdl) const
|
||||
|
||||
uint64_t
|
||||
Output_segment::set_section_addresses(const Layout* layout, bool reset,
|
||||
uint64_t addr, off_t* poff,
|
||||
uint64_t addr,
|
||||
unsigned int increase_relro,
|
||||
off_t* poff,
|
||||
unsigned int* pshndx)
|
||||
{
|
||||
gold_assert(this->type_ == elfcpp::PT_LOAD);
|
||||
|
||||
off_t orig_off = *poff;
|
||||
|
||||
// If we have relro sections, we need to pad forward now so that the
|
||||
// relro sections plus INCREASE_RELRO end on a common page boundary.
|
||||
if (parameters->options().relro()
|
||||
&& this->is_first_section_relro()
|
||||
&& (!this->are_addresses_set_ || reset))
|
||||
{
|
||||
uint64_t relro_size = 0;
|
||||
off_t off = *poff;
|
||||
for (Output_data_list::iterator p = this->output_data_.begin();
|
||||
p != this->output_data_.end();
|
||||
++p)
|
||||
{
|
||||
if (!(*p)->is_section())
|
||||
break;
|
||||
Output_section* pos = (*p)->output_section();
|
||||
if (!pos->is_relro())
|
||||
break;
|
||||
gold_assert(!(*p)->is_section_flag_set(elfcpp::SHF_TLS));
|
||||
if ((*p)->is_address_valid())
|
||||
relro_size += (*p)->data_size();
|
||||
else
|
||||
{
|
||||
// FIXME: This could be faster.
|
||||
(*p)->set_address_and_file_offset(addr + relro_size,
|
||||
off + relro_size);
|
||||
relro_size += (*p)->data_size();
|
||||
(*p)->reset_address_and_file_offset();
|
||||
}
|
||||
}
|
||||
relro_size += increase_relro;
|
||||
|
||||
uint64_t page_align = parameters->target().common_pagesize();
|
||||
|
||||
// Align to offset N such that (N + RELRO_SIZE) % PAGE_ALIGN == 0.
|
||||
uint64_t desired_align = page_align - (relro_size % page_align);
|
||||
if (desired_align < *poff % page_align)
|
||||
*poff += page_align - *poff % page_align;
|
||||
*poff += desired_align - *poff % page_align;
|
||||
addr += *poff - orig_off;
|
||||
orig_off = *poff;
|
||||
}
|
||||
|
||||
if (!reset && this->are_addresses_set_)
|
||||
{
|
||||
gold_assert(this->paddr_ == addr);
|
||||
@ -3450,15 +3511,10 @@ Output_segment::set_section_addresses(const Layout* layout, bool reset,
|
||||
|
||||
bool in_tls = false;
|
||||
|
||||
bool in_relro = (parameters->options().relro()
|
||||
&& this->is_first_section_relro());
|
||||
|
||||
off_t orig_off = *poff;
|
||||
this->offset_ = orig_off;
|
||||
|
||||
addr = this->set_section_list_addresses(layout, reset, &this->output_data_,
|
||||
addr, poff, pshndx, &in_tls,
|
||||
&in_relro);
|
||||
addr, poff, pshndx, &in_tls);
|
||||
this->filesz_ = *poff - orig_off;
|
||||
|
||||
off_t off = *poff;
|
||||
@ -3466,7 +3522,7 @@ Output_segment::set_section_addresses(const Layout* layout, bool reset,
|
||||
uint64_t ret = this->set_section_list_addresses(layout, reset,
|
||||
&this->output_bss_,
|
||||
addr, poff, pshndx,
|
||||
&in_tls, &in_relro);
|
||||
&in_tls);
|
||||
|
||||
// If the last section was a TLS section, align upward to the
|
||||
// alignment of the TLS segment, so that the overall size of the TLS
|
||||
@ -3477,14 +3533,6 @@ Output_segment::set_section_addresses(const Layout* layout, bool reset,
|
||||
*poff = align_address(*poff, segment_align);
|
||||
}
|
||||
|
||||
// If all the sections were relro sections, align upward to the
|
||||
// common page size.
|
||||
if (in_relro)
|
||||
{
|
||||
uint64_t page_align = parameters->target().common_pagesize();
|
||||
*poff = align_address(*poff, page_align);
|
||||
}
|
||||
|
||||
this->memsz_ = *poff - orig_off;
|
||||
|
||||
// Ignore the file offset adjustments made by the BSS Output_data
|
||||
@ -3502,7 +3550,7 @@ Output_segment::set_section_list_addresses(const Layout* layout, bool reset,
|
||||
Output_data_list* pdl,
|
||||
uint64_t addr, off_t* poff,
|
||||
unsigned int* pshndx,
|
||||
bool* in_tls, bool* in_relro)
|
||||
bool* in_tls)
|
||||
{
|
||||
off_t startoff = *poff;
|
||||
|
||||
@ -3553,19 +3601,6 @@ Output_segment::set_section_list_addresses(const Layout* layout, bool reset,
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a non-relro section after a relro section,
|
||||
// align it to a common page boundary so that the dynamic
|
||||
// linker has a page to mark as read-only.
|
||||
if (*in_relro
|
||||
&& (!(*p)->is_section()
|
||||
|| !(*p)->output_section()->is_relro()))
|
||||
{
|
||||
uint64_t page_align = parameters->target().common_pagesize();
|
||||
if (page_align > align)
|
||||
align = page_align;
|
||||
*in_relro = false;
|
||||
}
|
||||
|
||||
off = align_address(off, align);
|
||||
(*p)->set_address_and_file_offset(addr + (off - startoff), off);
|
||||
}
|
||||
@ -3621,10 +3656,10 @@ Output_segment::set_section_list_addresses(const Layout* layout, bool reset,
|
||||
}
|
||||
|
||||
// For a non-PT_LOAD segment, set the offset from the sections, if
|
||||
// any.
|
||||
// any. Add INCREASE to the file size and the memory size.
|
||||
|
||||
void
|
||||
Output_segment::set_offset()
|
||||
Output_segment::set_offset(unsigned int increase)
|
||||
{
|
||||
gold_assert(this->type_ != elfcpp::PT_LOAD);
|
||||
|
||||
@ -3632,6 +3667,7 @@ Output_segment::set_offset()
|
||||
|
||||
if (this->output_data_.empty() && this->output_bss_.empty())
|
||||
{
|
||||
gold_assert(increase == 0);
|
||||
this->vaddr_ = 0;
|
||||
this->paddr_ = 0;
|
||||
this->are_addresses_set_ = true;
|
||||
@ -3673,6 +3709,9 @@ Output_segment::set_offset()
|
||||
+ last->data_size()
|
||||
- this->vaddr_);
|
||||
|
||||
this->filesz_ += increase;
|
||||
this->memsz_ += increase;
|
||||
|
||||
// If this is a TLS segment, align the memory size. The code in
|
||||
// set_section_list ensures that the section after the TLS segment
|
||||
// is aligned to give us room.
|
||||
@ -3682,16 +3721,6 @@ Output_segment::set_offset()
|
||||
gold_assert(this->vaddr_ == align_address(this->vaddr_, segment_align));
|
||||
this->memsz_ = align_address(this->memsz_, segment_align);
|
||||
}
|
||||
|
||||
// If this is a RELRO segment, align the memory size. The code in
|
||||
// set_section_list ensures that the section after the RELRO segment
|
||||
// is aligned to give us room.
|
||||
if (this->type_ == elfcpp::PT_GNU_RELRO)
|
||||
{
|
||||
uint64_t page_align = parameters->target().common_pagesize();
|
||||
gold_assert(this->vaddr_ == align_address(this->vaddr_, page_align));
|
||||
this->memsz_ = align_address(this->memsz_, page_align);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the TLS offsets of the sections in the PT_TLS segment.
|
||||
|
@ -2351,6 +2351,35 @@ class Output_section : public Output_data
|
||||
set_is_relro_local()
|
||||
{ this->is_relro_local_ = true; }
|
||||
|
||||
// True if this must be the last relro section.
|
||||
bool
|
||||
is_last_relro() const
|
||||
{ return this->is_last_relro_; }
|
||||
|
||||
// Record that this must be the last relro section.
|
||||
void
|
||||
set_is_last_relro()
|
||||
{
|
||||
gold_assert(this->is_relro_);
|
||||
this->is_last_relro_ = true;
|
||||
}
|
||||
|
||||
// True if this must be the first section following the relro sections.
|
||||
bool
|
||||
is_first_non_relro() const
|
||||
{
|
||||
gold_assert(!this->is_relro_);
|
||||
return this->is_first_non_relro_;
|
||||
}
|
||||
|
||||
// Record that this must be the first non-relro section.
|
||||
void
|
||||
set_is_first_non_relro()
|
||||
{
|
||||
gold_assert(!this->is_relro_);
|
||||
this->is_first_non_relro_ = true;
|
||||
}
|
||||
|
||||
// True if this is a small section: a section which holds small
|
||||
// variables.
|
||||
bool
|
||||
@ -3341,6 +3370,10 @@ class Output_section : public Output_data
|
||||
bool is_relro_ : 1;
|
||||
// True if this section holds relro local data.
|
||||
bool is_relro_local_ : 1;
|
||||
// True if this must be the last relro section.
|
||||
bool is_last_relro_ : 1;
|
||||
// True if this must be the first section after the relro sections.
|
||||
bool is_first_non_relro_ : 1;
|
||||
// True if this is a small section.
|
||||
bool is_small_section_ : 1;
|
||||
// True if this is a large section.
|
||||
@ -3497,7 +3530,8 @@ class Output_segment
|
||||
// address of the immediately following segment. Update *POFF and
|
||||
// *PSHNDX. This should only be called for a PT_LOAD segment.
|
||||
uint64_t
|
||||
set_section_addresses(const Layout*, bool reset, uint64_t addr, off_t* poff,
|
||||
set_section_addresses(const Layout*, bool reset, uint64_t addr,
|
||||
unsigned int increase_relro, off_t* poff,
|
||||
unsigned int* pshndx);
|
||||
|
||||
// Set the minimum alignment of this segment. This may be adjusted
|
||||
@ -3509,7 +3543,7 @@ class Output_segment
|
||||
// Set the offset of this segment based on the section. This should
|
||||
// only be called for a non-PT_LOAD segment.
|
||||
void
|
||||
set_offset();
|
||||
set_offset(unsigned int increase);
|
||||
|
||||
// Set the TLS offsets of the sections contained in the PT_TLS segment.
|
||||
void
|
||||
@ -3555,7 +3589,7 @@ class Output_segment
|
||||
uint64_t
|
||||
set_section_list_addresses(const Layout*, bool reset, Output_data_list*,
|
||||
uint64_t addr, off_t* poff, unsigned int* pshndx,
|
||||
bool* in_tls, bool* in_relro);
|
||||
bool* in_tls);
|
||||
|
||||
// Return the number of Output_sections in an Output_data_list.
|
||||
unsigned int
|
||||
|
@ -716,7 +716,7 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
|
||||
|
||||
layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
|
||||
this->got_, false);
|
||||
this->got_, false, false, false, false);
|
||||
|
||||
// Create the GOT2 or TOC in the .got section.
|
||||
if (size == 32)
|
||||
@ -725,7 +725,8 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
|
||||
layout->add_output_section_data(".got2", elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE,
|
||||
this->got2_, false);
|
||||
this->got2_, false, false, false,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -733,7 +734,8 @@ Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
|
||||
layout->add_output_section_data(".toc", elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE,
|
||||
this->toc_, false);
|
||||
this->toc_, false, false, false,
|
||||
false);
|
||||
}
|
||||
|
||||
// Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
|
||||
@ -760,7 +762,8 @@ Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
|
||||
gold_assert(layout != NULL);
|
||||
this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
|
||||
layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true);
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true,
|
||||
false, false, false);
|
||||
}
|
||||
return this->rela_dyn_;
|
||||
}
|
||||
@ -820,7 +823,8 @@ Output_data_plt_powerpc<size, big_endian>::Output_data_plt_powerpc(Layout* layou
|
||||
{
|
||||
this->rel_ = new Reloc_section(false);
|
||||
layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rel_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_, true, false,
|
||||
false, false);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
@ -949,7 +953,7 @@ Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->plt_, false);
|
||||
this->plt_, false, false, false, false);
|
||||
|
||||
// Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
|
||||
symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
|
||||
@ -1512,7 +1516,8 @@ Target_powerpc<size, big_endian>::scan_relocs(
|
||||
Output_section* os = layout->add_output_section_data(".sdata", 0,
|
||||
elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE,
|
||||
sdata, false);
|
||||
sdata, false,
|
||||
false, false, false);
|
||||
symtab->define_in_output_data("_SDA_BASE_", NULL,
|
||||
Symbol_table::PREDEFINED,
|
||||
os,
|
||||
|
@ -1026,8 +1026,8 @@ Target_sparc<size, big_endian>::got_section(Symbol_table* symtab,
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_, false);
|
||||
os->set_is_relro();
|
||||
this->got_, false, true, false,
|
||||
false);
|
||||
|
||||
// Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section.
|
||||
symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
|
||||
@ -1053,7 +1053,8 @@ Target_sparc<size, big_endian>::rela_dyn_section(Layout* layout)
|
||||
gold_assert(layout != NULL);
|
||||
this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
|
||||
layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true);
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true,
|
||||
false, false, false);
|
||||
}
|
||||
return this->rela_dyn_;
|
||||
}
|
||||
@ -1155,7 +1156,8 @@ Output_data_plt_sparc<size, big_endian>::Output_data_plt_sparc(Layout* layout)
|
||||
{
|
||||
this->rel_ = new Reloc_section(false);
|
||||
layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rel_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_, true,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
@ -1372,7 +1374,7 @@ Target_sparc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->plt_, false);
|
||||
this->plt_, false, false, false, false);
|
||||
|
||||
// Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
|
||||
symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
|
||||
|
@ -46,6 +46,8 @@ SECTIONS
|
||||
|
||||
. = DATA_SEGMENT_RELRO_END(0, .);
|
||||
|
||||
.got.plt : { *(.got.plt) }
|
||||
|
||||
.data : { *(.data .data.* .gnu.linkonce.d.*) }
|
||||
|
||||
. = DATA_SEGMENT_END (.);
|
||||
|
@ -469,23 +469,22 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout)
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_, false);
|
||||
os->set_is_relro();
|
||||
this->got_, false, true, true,
|
||||
false);
|
||||
|
||||
// The old GNU linker creates a .got.plt section. We just
|
||||
// create another set of data in the .got section. Note that we
|
||||
// always create a PLT if we create a GOT, although the PLT
|
||||
// might be empty.
|
||||
this->got_plt_ = new Output_data_space(8, "** GOT PLT");
|
||||
os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
|
||||
os = layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_WRITE),
|
||||
this->got_plt_, false);
|
||||
os->set_is_relro();
|
||||
this->got_plt_, false, false,
|
||||
false, true);
|
||||
|
||||
// The first three entries are reserved.
|
||||
this->got_plt_->set_current_data_size(3 * 8);
|
||||
|
||||
// Those bytes can go into the relro segment.
|
||||
layout->increase_relro(3 * 8);
|
||||
|
||||
// Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
|
||||
symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
|
||||
Symbol_table::PREDEFINED,
|
||||
@ -509,7 +508,8 @@ Target_x86_64::rela_dyn_section(Layout* layout)
|
||||
gold_assert(layout != NULL);
|
||||
this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
|
||||
layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true);
|
||||
elfcpp::SHF_ALLOC, this->rela_dyn_, true,
|
||||
false, false, false);
|
||||
}
|
||||
return this->rela_dyn_;
|
||||
}
|
||||
@ -609,7 +609,8 @@ Output_data_plt_x86_64::Output_data_plt_x86_64(Layout* layout,
|
||||
{
|
||||
this->rel_ = new Reloc_section(false);
|
||||
layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
|
||||
elfcpp::SHF_ALLOC, this->rel_, true);
|
||||
elfcpp::SHF_ALLOC, this->rel_, true,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -805,7 +806,7 @@ Target_x86_64::make_plt_section(Symbol_table* symtab, Layout* layout)
|
||||
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR),
|
||||
this->plt_, false);
|
||||
this->plt_, false, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user